Azure-Samples/hello-spring-function-azure

Issue with 2.1.1 spring-cloud-function-dependencies

kubarzeplinski opened this issue · 10 comments

Hi,
do you plan to upgrade spring-cloud-function-dependencies version in this sample project? I got Failed to locate main class exception for 2.1.1 spring-cloud-function-dependencies.

Stack: java.lang.IllegalStateException: Failed to discover main class. An attempt was made to discover main class as 'MAIN_CLASS' environment variable, system property as well as entry in META-INF/MANIFEST.MF (in that order).
[26.11.2019 15:35:50] at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.getStartClass(AbstractSpringFunctionAdapterInitializer.java:283)
[26.11.2019 15:35:50] at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.(AbstractSpringFunctionAdapterInitializer.java:99)
[26.11.2019 15:35:50] at org.springframework.cloud.function.adapter.azure.AzureSpringBootRequestHandler.(AzureSpringBootRequestHandler.java:44)

Thanks a lot @kubarzeplinski !!!
In fact I corrected it on my own project at https://github.com/jdubois/hello-spring-function-azure and didn't make the change here.

Let me correct that:

  • I'm going to copy my changes to this repo
  • I will then archive my own repo, so I don't do this again

I'll keep you updated on this ticket, but meanwhile you can use my https://github.com/jdubois/hello-spring-function-azure project, which is already good.

@kubarzeplinski everything is done, the "main class" issue should be solved with f0c9417

I notice that you are using an even newer Spring Boot version (I'm on 2.2.0, you are on 2.2.1), can you check if everything is fine on your side? Then we can close the ticket.

Hi @jdubois,
i fetched your change. I think that you should upgrade spring-cloud-function-dependencies in pom.xml also. This sample project still doesn't work for me with 2.1.1.RELEASE and the latest 3.0.0.RELEASE version. It will be good to use 3.0.0.RELEASE. It is available in Maven repository since yesterday.

My pom.xml:


4.0.0

<groupId>com.example</groupId>
<artifactId>hello</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Hello Spring Function on Azure</name>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <azure.functions.maven.plugin.version>1.3.2</azure.functions.maven.plugin.version>
    <azure.functions.java.library.version>1.3.0</azure.functions.java.library.version>
    <functionAppName>my-spring-function</functionAppName>
    <functionAppRegion>westus</functionAppRegion>
    <stagingDirectory>${project.build.directory}/azure-functions/${functionAppName}</stagingDirectory>
    <functionResourceGroup>my-resource-group</functionResourceGroup>
    <start-class>com.example.HelloFunction</start-class>
    <wrapper.version>1.0.22.RELEASE</wrapper.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-function-adapter-azure</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-function-web</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- Test -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-function-dependencies</artifactId>
            <version>2.1.1.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>com.microsoft.azure</groupId>
                <artifactId>azure-functions-maven-plugin</artifactId>
                <version>${azure.functions.maven.plugin.version}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.1.0</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.1</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</version>
            </plugin>
        </plugins>
    </pluginManagement>

    <plugins>
        <plugin>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>azure-functions-maven-plugin</artifactId>
            <configuration>
                <resourceGroup>${functionResourceGroup}</resourceGroup>
                <appName>${functionAppName}</appName>
                <region>${functionAppRegion}</region>
                <appSettings>
                    <!-- Run Azure Function from package file by default -->
                    <property>
                        <name>WEBSITE_RUN_FROM_PACKAGE</name>
                        <value>1</value>
                    </property>
                    <property>
                        <name>FUNCTIONS_EXTENSION_VERSION</name>
                        <value>~2</value>
                    </property>
                    <property>
                        <name>FUNCTIONS_WORKER_RUNTIME</name>
                        <value>java</value>
                    </property>
                    <property>
                        <name>MAIN_CLASS</name>
                        <value>com.example.HelloFunction</value>
                    </property>
                </appSettings>
            </configuration>
            <executions>
                <execution>
                    <id>package-functions</id>
                    <goals>
                        <goal>package</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-resources</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <overwrite>true</overwrite>
                        <outputDirectory>
                            ${project.build.directory}/azure-functions/${functionAppName}
                        </outputDirectory>
                        <resources>
                            <resource>
                                <directory>${project.basedir}/src/main/azure
                                </directory>
                                <includes>
                                    <include>**</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${stagingDirectory}/lib</outputDirectory>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                        <includeScope>runtime</includeScope>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!--Remove obj folder generated by .NET SDK in maven clean-->
        <plugin>
            <artifactId>maven-clean-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <filesets>
                    <fileset>
                        <directory>obj</directory>
                    </fileset>
                </filesets>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot.experimental</groupId>
                    <artifactId>spring-boot-thin-layout</artifactId>
                    <version>${wrapper.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/libs-snapshot-local</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone-local</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-releases</id>
        <name>Spring Releases</name>
        <url>https://repo.spring.io/release</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/libs-snapshot-local</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>false</enabled>
        </releases>
    </pluginRepository>
    <pluginRepository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone-local</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </pluginRepository>
    <pluginRepository>
        <id>spring-releases</id>
        <name>Spring Releases</name>
        <url>https://repo.spring.io/libs-release-local</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

Console logs:

[27.11.2019 10:02:22] Executed 'Functions.hello' (Failed, Id=09860192-70cd-4ce9-acbe-86dc17ece135)
[27.11.2019 10:02:22] System.Private.CoreLib: Exception while executing function: Functions.hello. System.Private.CoreLib: Result: Failure
Exception: IllegalArgumentException: Failed to locate main class
Stack: java.lang.IllegalStateException: Failed to discover main class. An attempt was made to discover main class as 'MAIN_CLASS' environment variable, system property as well as entry in META-INF/MANIFEST.MF (in that order).
[27.11.2019 10:02:22] at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.getStartClass(AbstractSpringFunctionAdapterInitializer.java:283)
[27.11.2019 10:02:22] at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.(AbstractSpringFunctionAdapterInitializer.java:99)
[27.11.2019 10:02:22] at org.springframework.cloud.function.adapter.azure.AzureSpringBootRequestHandler.(AzureSpringBootRequestHandler.java:44)
[27.11.2019 10:02:22] at com.example.HelloHandler.(HelloHandler.java:15)
[27.11.2019 10:02:22] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[27.11.2019 10:02:22] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
[27.11.2019 10:02:22] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[27.11.2019 10:02:22] at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
[27.11.2019 10:02:22] at java.lang.Class.newInstance(Class.java:442)
[27.11.2019 10:02:22] at com.microsoft.azure.functions.worker.broker.JavaMethodExecutor.lambda$execute$1(JavaMethodExecutor.java:54)
[27.11.2019 10:02:22] at com.microsoft.azure.functions.worker.broker.JavaMethodInvokeInfo.invoke(JavaMethodInvokeInfo.java:20)
[27.11.2019 10:02:22] at com.microsoft.azure.functions.worker.broker.JavaMethodExecutor.execute(JavaMethodExecutor.java:54)
[27.11.2019 10:02:22] at com.microsoft.azure.functions.worker.broker.JavaFunctionBroker.invokeMethod(JavaFunctionBroker.java:53)
[27.11.2019 10:02:22] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:33)
[27.11.2019 10:02:22] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:10)
[27.11.2019 10:02:22] at com.microsoft.azure.functions.worker.handler.MessageHandler.handle(MessageHandler.java:45)
[27.11.2019 10:02:22] at com.microsoft.azure.functions.worker.JavaWorkerClient$StreamingMessagePeer.lambda$onNext$0(JavaWorkerClient.java:92)
[27.11.2019 10:02:22] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[27.11.2019 10:02:22] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[27.11.2019 10:02:22] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[27.11.2019 10:02:22] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[27.11.2019 10:02:22] at java.lang.Thread.run(Thread.java:748)
[27.11.2019 10:02:22] Caused by: java.lang.IllegalArgumentException: Failed to locate main class
[27.11.2019 10:02:22] at org.springframework.util.Assert.notNull(Assert.java:198)
[27.11.2019 10:02:22] at org.springframework.cloud.function.context.AbstractSpringFunctionAdapterInitializer.getStartClass(AbstractSpringFunctionAdapterInitializer.java:279)
[27.11.2019 10:02:22] ... 21 more
[27.11.2019 10:02:22] .
[27.11.2019 10:02:22] Executed HTTP request: {
[27.11.2019 10:02:22] "requestId": "3675fdbc-b4fa-4f1d-9047-4410ee3a32b8",
[27.11.2019 10:02:22] "method": "POST",
[27.11.2019 10:02:22] "uri": "/api/hello",
[27.11.2019 10:02:22] "identities": [
[27.11.2019 10:02:22] {
[27.11.2019 10:02:22] "type": "WebJobsAuthLevel",
[27.11.2019 10:02:22] "level": "Admin"
[27.11.2019 10:02:22] }
[27.11.2019 10:02:22] ],
[27.11.2019 10:02:22] "status": 500,
[27.11.2019 10:02:22] "duration": 607
[27.11.2019 10:02:22] }

Thanks @kubarzeplinski - I tested again with Spring Boot 2.2.0 and it was working, but you are correct, so I have upgraded:

  • Upgrade to the latest Spring Boot 2.2.1 release in f06a398
  • Upgrade to the latest Spring Cloud Function 3.0.0 release in 35d01ce

I have tested again and everything works fine.

Your issue is different, this is because the main class could not be found, so I guess you didn't see the trick here:

<name>MAIN_CLASS</name>

Indeed, that trick isn't very developer-friendly, and this should be automated (I'm guessing by the Spring Cloud team).

Thank you @jdubois. I don't know why, but i still have this issue with main class. I added new system variable with key MAIN_CLASS and it works, but i think that it is not recommended. Which mvn command do you use to package and run this project? I use mvn clean package azure-functions:run.

@kubarzeplinski I'm doing mvn clean package azure-functions:deploy but I don't understand why there would be a difference, it's hard-coded in the configuration. Did you check you have the correct package+name for your class?

Hi @jdubois, i confirm that this sample project with all your changes works on Azure (i use the same command as you). I would like to test this app locally before deploying this. That is why i use azure-functions:run instead of azure-functions:deploy. This is recommended way for business applications. :)). I have this issue with main class when i run this app locally in my IDE.

Oh thanks for the explanation @kubarzeplinski ! Indeed, I didn't test locally, but I wasn't expecting there would be a difference, it's supposed to be the same environment! Maybe there's a version mismatch between your local environment and the one on Azure? This would be a case for support, as I don't think this should happen at all.

@jdubois, i see MAIN_CLASS property in application settings tab in my App Service. I think that this was added automatically during deployment of this app (azure-functions:deploy). It does't work without this setting.
image

Indeed @kubarzeplinski this setting is mandatory.

  • I would love to get rid of this configuration, and I guess there is some way to automate this inside the plugin.
  • Then I force this setting in the plugin, so it should both work for "deploy" and "run". So for me this is a bug in the plugin.

I'm going to fill a ticket for this on the plugin repository, and I will link it here for follow up.

As this issue is with a specific Maven goal, I'll then close this ticket.