java - EAR 类加载器看不到位于 jar 中的 ApplicationInsights.xml
问题描述
我有以下问题:我尝试在 jar 文件中部署 Azure 遥测配置,该文件位于 main ear 内的 war 文件中。不幸的是,在服务器启动期间,由于找不到 ApplicationInsights.xml,会发生一些错误。我对其进行了调试,发现 com.microsoft.applicationinsights.internal.config.ConfigurationFileLocator.getConfigurationFile() 无法读取它。
我的模块有一个结构:
azure
|_ src
|_ main
|_ java
| |_ mypackage
| |_ MicrometerRegistryConfigurationListener.java
|_ resources
|_ ApplicationInsights.xml
有MicrometerRegistryConfigurationListener.java:
@WebListener
public class MicrometerRegistryConfigurationListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
MeterRegistry azureMeterRegistry = new AzureMonitorMeterRegistry(new AzureMonitorConfig() {
@Override
public String get(String key) {
return null;
}
@Override
public Duration step() {
return Duration.ofSeconds(5);
}
}, Clock.SYSTEM);
new JvmThreadMetrics().bindTo(azureMeterRegistry);
new JvmMemoryMetrics().bindTo(azureMeterRegistry);
new JvmGcMetrics().bindTo(azureMeterRegistry);
servletContextEvent.getServletContext().setAttribute("AzureMonitorMeterRegistry", azureMeterRegistry);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
并且有一个ear的结构:
ear
|_ war
|_ WEB-INF/lib
|_ azure.jar
|_ ApplicationInsights.xml
当然,azure.jar 还包含类,即 MicrometerRegistryConfigurationListener。
到底是怎么回事?为什么 ApplicationInsights.xml 不可见?
解决方案
因为 jar 是一个文件,它不是一个文件夹。加载器尝试访问文件系统路径,但它无法访问 JAR 中的路径。因此,您可以使用该resource.getInputStream()
方法将其作为 InputStream 检索。您可以从此文档中获取详细信息:Java: Load file from classpath in Spring Boot。
示例代码:
public class EnvResolver {
private ResourceLoader resourceLoader;
public EnvResolver(){
resourceLoader = new DefaultResourceLoader();
}
public List GetEnvConfig() throws IOException {
Yaml yaml = new Yaml();
Resource resource = resourceLoader.getResource("classpath:test-environment.yml");
System.out.println("FileName: " + resource.getFilename());
InputStream inputStream = resource.getInputStream();
Map<String, Map<String, String>> result = yaml.load(inputStream);
List<TestEnvVo> envList = new ArrayList<>();
for (String key : result.keySet()) {
TestEnvVo testEnvVo = new TestEnvVo();
testEnvVo.setEnvName(result.get(key).get("name"));
testEnvVo.setDomain(result.get(key).get("domain"));
envList.add(testEnvVo);
}
inputStream.close();
return envList;
}
}
经过搜索,我找到了另一种配置方式,在您的 POM 文件中添加resources
配置。你可以试一试。
<resources>
<resource>
<directory>src/main/resource</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
希望这可以帮助你。
更新:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
public class Hello {
public static void main(String[] args) throws IOException {
InputStream resourceInputStream = null;
URL resourceURL = Hello.class.getClassLoader().getResource("resources/hello.json");
if(resourceURL == null) {
System.out.println("Get the InputStream of file in IDE");
resourceInputStream = new FileInputStream(Hello.class.getClassLoader().getResource("").getPath()+"../../src/main/resources/hello.json");
} else {
System.out.println("Get the InputStream of file from runnable jar");
resourceInputStream = Hello.class.getClassLoader().getResourceAsStream("resources/hello.json");
}
System.out.println();
StringBuilder builder = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(resourceInputStream));
String line = null;
while((line = br.readLine()) != null) {
builder.append(line+"\n");
}
br.close();
System.out.println(builder.toString());
}
}
推荐阅读
- python - 当 slice 有一行结果时返回 pandas.DataFrame
- elasticsearch - Elasticsearch 中的映射爆炸
- javascript - Javascript 在移动设备上冻结身体(不允许任何滚动等)
- android - 有什么办法可以实现 Flutter 顶级小吃吧?
- apache - Apache 代理访问配置
- angular - 如何将图标添加到 mat-table 中的 mat-sort-header
- web-services - 关闭应用程序时,Android 服务无法连接到 Web 服务
- hyperledger-fabric - 在 Hyperledger Fabric 中,如果无法使用 peer channel fetch 命令,如何加入频道?
- rxjs - 更新订阅中的值
- c# - 通过 web api 授权 azure 活动目录