JDesktop应用:如何配置Resource Map路径适配Gradle项目结构?
我来帮你搞定这个getResourceMap()加载属性时的NullPointerException问题,不用改动现有项目结构也能解决。
先说说问题根源:org.jdesktop.application的getResourceMap()默认会从当前类所在的包路径下查找匹配的资源文件(比如你的MyView在myproject包下,它会优先找类路径中myproject包下的MyView.properties或Application.properties这类文件)。但你的资源现在放在main/resources根目录,不在类路径的myproject包下,所以默认查找逻辑找不到对应的资源项,调用getInteger("timeout")就抛出了NPE。
下面给你两种不用改项目结构的解决方案:
方案一:通过Gradle配置自动映射资源到目标包路径
你可以在Gradle构建脚本里配置sourceSets,让main/resources根目录下的资源文件在编译时自动复制到类路径的myproject包下,这样默认的getResourceMap()就能正常找到它们。
Groovy DSL(build.gradle):
sourceSets { main { resources { // 保留原有资源目录配置 srcDirs = ['src/main/resources'] // 把根目录下的.properties资源复制到myproject包路径 from('src/main/resources') { include '*.properties' // 可根据需求调整匹配规则 into 'myproject' } } } }
Kotlin DSL(build.gradle.kts):
sourceSets { main { resources { srcDirs("src/main/resources") from("src/main/resources") { include("*.properties") into("myproject") } } } }
配置完成后执行gradle build,根目录下的资源文件会被打包到类路径的myproject包下,getResourceMap()就能顺利读取到timeout属性了。
方案二:显式指定资源路径加载ResourceMap
如果不想修改Gradle配置,也可以直接在代码里显式指定资源加载路径,跳过默认的包路径查找逻辑:
public MyView(SingleFrameApplication app) { super(app); initComponents(); // 显式加载根目录下的资源文件(示例中资源文件为app.properties) ResourceMap resourceMap = getResourceMap(getClass().getClassLoader(), "app"); // 也可以通过应用类定位根目录下的Application.properties // ResourceMap resourceMap = app.getResourceMap(MyApp.class, "Application"); // 建议先检查属性是否存在,避免再次抛出NPE Integer timeout = resourceMap.containsKey("timeout") ? resourceMap.getInteger("timeout") : 30; }
这里的"app"是你的资源文件基名(比如app.properties就用"app"),通过类加载器从类路径根目录查找资源,不用移动资源文件就能正常加载。
额外提示
为了避免后续出现类似NPE,建议在获取属性前先调用resourceMap.containsKey("key")做存在性检查,或者使用带默认值的重载方法(如果API支持的话),比如resourceMap.getInteger("key", defaultValue)。
内容的提问来源于stack exchange,提问作者Tien Do Nam

