Azure Function App调用Azure Digital Twin出现NoClassDefFoundError如何解决
问题根因
这个报错是Reactor/Netty依赖版本冲突导致的:Azure Function App的Java运行环境本身预载了旧版本的Reactor、Netty组件,本地运行时你项目引入的依赖优先级更高所以运行正常,部署到云端后环境预载的低版本包优先加载,和你手动引入的高版本Reactor/Netty包不兼容,最终触发HttpClientConfig类初始化失败的NoClassDefFoundError。
修复步骤
- 第一步:删除pom.xml中手动声明的多余依赖,以下依赖全部删掉即可,Azure Digital Twins SDK已经自带了匹配版本的传递依赖,手动指定版本反而会导致冲突:
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.49.Final</version> </dependency> <dependency> <groupId>io.projectreactor.netty</groupId> <artifactId>reactor-netty</artifactId> <version>1.0.7</version> </dependency> <dependency> <groupId>io.projectreactor.netty</groupId> <artifactId>reactor-netty-http</artifactId> <version>1.0.7</version> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-bom</artifactId> <version>Dysprosium-SR20</version> <type>pom</type> </dependency>
- 第二步:在你的pom.xml里找到
azure-functions-maven-plugin的配置,添加运行时优先加载应用包依赖的配置,示例如下:
<plugin> <groupId>com.microsoft.azure</groupId> <artifactId>azure-functions-maven-plugin</artifactId> <version>${azure.functions.maven.plugin.version}</version> <configuration> <!-- 你原来的其他配置比如appName、resourceGroup、runtime等保留 --> <appSettings> <!-- 新增这个配置项 --> <FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS>True</FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS> <!-- 其他的应用配置比如连接字符串也可以放在这里 --> </appSettings> </configuration> </plugin>
- 第三步:优化客户端初始化逻辑(可选,推荐):
DigitalTwinsClient是线程安全的,不需要每次函数触发都重新构建,你可以将其定义为类静态变量,只初始化一次,提升运行性能同时避免频繁创建连接带来的额外开销:
public class Function { // 静态初始化客户端,仅触发一次 private static final DigitalTwinsClient ADT_CLIENT; static { String adtUrl = System.getenv("ADT_SERVICE_URL"); ADT_CLIENT = new DigitalTwinsClientBuilder().credential(new ClientSecretCredentialBuilder() .tenantId("my_tenant_id").clientId("my_client_id") .clientSecret("my_client_secret").build()).endpoint(adtUrl).buildClient(); } @FunctionName("eventGridMonitorString") public void eventHubProcessor( @EventHubTrigger(name = "msg", eventHubName = "", connection = "EventHubConnectionString") String message, final ExecutionContext context) { context.getLogger().info("ADTURL : " + adtUrl); Iterable<DigitalTwinsModelData> modelList = ADT_CLIENT.listModels(); Iterator<DigitalTwinsModelData> it = modelList.iterator(); while (it.hasNext()) { DigitalTwinsModelData model = it.next(); context.getLogger().info("" + model.getDtdlModel()); } for (DigitalTwinsModelData model : modelList) { context.getLogger().info("Created model: " + model.getModelId()); } } }
全部修改完成后执行mvn clean package重新打包,再部署到Azure Function App即可正常运行。
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

