我正在使用 Spring Cloud 创建一个 Azure 函数,配置如下。在本地运行时工作正常,但当我在 Azure 中部署它(使用 IntelliJ IDE 部署)时,部署成功,但在 Azure 门户中访问该函数时,它抛出错误,无法找到主类。
当我提取在本地创建的 jar 时,可以看到 MANIFEST.MF 文件,其中条目为主类:com.azlearning.functionapp.AzEmailSenderFunctionApplication。
但是 Azure 运行时期望使用 MAIN_CLASS 定义主类。当使用 spring 提供的插件时,它总是创建主类条目。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.azlearning</groupId>
<artifactId>az-email-sender-function</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>az-email-sender-function</name>
<description>Azure Email Sender function</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
<spring-boot-thin-layout.version>1.0.31.RELEASE</spring-boot-thin-layout.version>
<!-- Spring Boot start class! WARING: correct class must be set! -->
<start-class>com.azlearning.functionapp.AzEmailSenderFunctionApplication</start-class>
<!-- AZURE FUNCTION CONFIG -->
<azure.functions.maven.plugin.version>1.36.0</azure.functions.maven.plugin.version>
<functionAppName>email-sender-funapp</functionAppName>
<functionAppRegion>Region</functionAppRegion>
<functionResourceGroup>az-cert-resource-group</functionResourceGroup>
<functionAppServicePlanName>PlanName</functionAppServicePlanName>
<functionPricingTier>PriceTier</functionPricingTier>
<spring-cloud.version>2024.0.0</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-azure</artifactId>
</dependency>
<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-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<version>${azure.functions.maven.plugin.version}</version>
<configuration>
<appName>${functionAppName}</appName>
<resourceGroup>${functionResourceGroup}</resourceGroup>
<region>${functionAppRegion}</region>
<appServicePlanName>${functionAppServicePlanName}</appServicePlanName>
<pricingTier>${functionPricingTier}</pricingTier>
<hostJson>${project.basedir}/src/main/resources/host.json</hostJson>
<!-- <localSettingsJson>${project.basedir}/src/main/resources/local.settings.json</localSettingsJson> -->
<runtime>
<os>linux</os>
<javaVersion>17</javaVersion>
</runtime>
<funcPort>7072</funcPort>
<appSettings>
<property>
<name>FUNCTIONS_EXTENSION_VERSION</name>
<value>~4</value>
</property>
<!-- <property>
<name>MAIN_CLASS</name>
<value>com.azlearning.functionapp.AzEmailSenderFunctionApplication</value>
</property> -->
</appSettings>
</configuration>
<executions>
<execution>
<id>package-functions</id>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- <plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.azlearning.functionapp.AzEmailSenderFunctionApplication</mainClass>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>1.0.31.RELEASE</version>
</dependency>
</dependencies>
</plugin> -->
</plugins>
</build>
</project>
Start-Class
中的pom.xml
指向你的Spring Boot应用程序的主类。<start-class>com.example.DemoApplication</start-class>
Main_Class = com.example.DemoApplication
中添加应用程序设置 FunctionApp=>Settings=>Environment Variables=>App Settings
。我创建了一个简单的 Spring Boot Azure 函数,请参阅 GitHub 存储库 获取示例项目。
在部署到 Azure 之前在本地运行项目并检查是否能够同步函数触发器。
更新
pom.xml
如下:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<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>3.0.1</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<azure.functions.maven.plugin.version>1.22.0</azure.functions.maven.plugin.version>
<azure.functions.java.library.version>3.0.0</azure.functions.java.library.version>
<spring.cloud.function.dependencies>4.0.0</spring.cloud.function.dependencies>
<functionResourceGroup>resource_group_name</functionResourceGroup>
<functionAppServicePlanName>AppService_Plan</functionAppServicePlanName>
<functionAppName>Function_App_Name</functionAppName>
<functionAppRegion>Region</functionAppRegion>
<functionPricingTier>Pricing Tier</functionPricingTier>
<start-class>com.example.DemoApplication</start-class>
</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-webflux</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
<version>3.9.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-dependencies</artifactId>
<version>${spring.cloud.function.dependencies}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-library</artifactId>
<version>${azure.functions.java.library.version}</version>
</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.3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.4.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.gatling</groupId>
<artifactId>gatling-maven-plugin</artifactId>
<version>4.1.5</version>
<configuration>
<includes>
<include>com.example.loadtest.*</include>
</includes>
</configuration>
</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>
<appServicePlanName>${functionAppServicePlanName}</appServicePlanName>
<pricingTier>${functionPricingTier}</pricingTier>
<hostJson>${project.basedir}/src/main/azure/host.json</hostJson>
<localSettingsJson>${project.basedir}/src/main/azure/local.settings.json</localSettingsJson>
<runtime>
<os>linux</os>
<javaVersion>17</javaVersion>
</runtime>
<appSettings>
<!-- Run Azure Function from package file by default -->
<property>
<name>FUNCTIONS_EXTENSION_VERSION</name>
<value>~4</value>
</property>
</appSettings>
</configuration>
<executions>
<execution>
<id>package-functions</id>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
<!--Remove obj folder generated by .NET SDK in maven clean-->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<filesets>
<fileset>
<directory>obj</directory>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
DemoApplication.java:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(DemoApplication.class, args);
}
}
HelloHandler.java:
package com.example;
import com.example.model.Greeting;
import com.example.model.User;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import org.springframework.cloud.function.adapter.azure.FunctionInvoker;
import java.util.Optional;
public class HelloHandler extends FunctionInvoker<User, Greeting> {
@FunctionName("hello")
public HttpResponseMessage execute(
@HttpTrigger(name = "request", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<User>> request,
ExecutionContext context) {
User user = request.getBody()
.filter((u -> u.getName() != null))
.orElseGet(() -> new User(
request.getQueryParameters()
.getOrDefault("name", "world")));
context.getLogger().info("Greeting user name: " + user.getName());
return request
.createResponseBuilder(HttpStatus.OK)
.body(handleRequest(user, context))
.header("Content-Type", "application/json")
.build();
}
}
使用命令
mvn azure-functions:deploy
将Spring Boot功能部署到Azure:
C:\Users\uname\hello-spring-function-azure>mvn azure-functions:deploy
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------------< com.example:hello >--------------------------
[INFO] Building Hello Spring Function on Azure 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- azure-functions:1.22.0:deploy (default-cli) @ hello ---
[INFO] Auth type: AZURE_CLI
Default subscription: Subscription(158b8345XXd98-95c5-f21815dd048f)
Username: userid
//Removed few logs
[INFO] Function App(rkfn) is successfully created
[INFO] Starting deployment...
[INFO] Trying to deploy artifact to rkfn...
[INFO] Successfully deployed the artifact to https://functionname.azurewebsites.net
[INFO] Deployment done, you may access your resource through rkfn.azurewebsites.net
[INFO] Syncing triggers and fetching function information
[INFO] Querying triggers...
[INFO] HTTP Trigger Urls:
[INFO] hello : https://functionname.azurewebsites.net/api/hello
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:22 min
[INFO] Finished at: 2024-12-19T16:40:02+05:30
[INFO] ------------------------------------------------------------------------
传送门:
回复:
前往
https://functionname.azurewebsites.net/api/hello
的路线: