Spring:在maven插件项目中请求加载属性,但使用插件中使用的项目文件

时间:2017-04-26 06:23:55

标签: java spring maven properties-file

我编写了maven插件,它正在使用spring上下文依赖注入。

在某些时候,spring必须使用属性文件初始化其中一个bean。在测试中一切正常。但是当插件在构建过程中构建并在不同项目中使用时,会抛出FileNotFoundException。

使用以下方法打印当前类路径条目时

ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url: urls){
    System.out.println("CLASSPATH: " + url.getFile());
}

我得到的只有:

CLASSPATH: /path/to/mavendir/boot/plexus-classworlds-2.5.2.jar

通常通过以下代码加载属性:

Resource resource = springContext.getResource("classpath:/myPluginConfig.properties");
Properties properties = PropertiesLoaderUtils.loadProperties(resource);

但找不到档案。

我已在使用我的插件的项目中的 / src / main / resources / 中正确命名了文件“ myPluginConfig.properties ”。

在进程资源阶段,文件被复制到目标/类目录(我已经检查过它)。所以文件就在那里,但是类路径在某种程度上被破坏了。

我的插件仅作为快照在本地安装,因此我可以快速更新并重新安装。

有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

当我们在diffrent项目中使用jar时,资源路径应该是这样的:classpath *:myPluginConfig.properties

答案 1 :(得分:0)

回答我的问题是:

  1. 在初始化spring上下文之前的maven插件项目 修改类路径,将maven运行时类路径添加到系统上下文类路径original solution on how to do this,并稍稍修改我的
  2. 这应该在mojo执行期间被称为我的maven。最好尽早。

        private void enhanceClassloaderAndInitSpring() {
            try {
                Set<URL> urls = new HashSet<>();
                List<Stream<String>> streams = new ArrayList<>();
                streams.add(project.getRuntimeClasspathElements().stream());
                streams.add(project.getCompileClasspathElements().stream());
                streams.add(project.getSystemClasspathElements().stream());
    
                for (String element : streams.stream().flatMap(s -> s).collect(Collectors.toList())) {
                    System.out.println("Adding element to classpath: " + element);
                    urls.add(new File(element).toURI().toURL());
                }
    
                ClassLoader contextClassLoader = URLClassLoader.newInstance(
                        urls.toArray(new URL[0]),
                        Thread.currentThread().getContextClassLoader());
    
                Thread.currentThread().setContextClassLoader(contextClassLoader);
    
                // springContext is just local field in class
                springContext = initSpringContext();
            } catch (DependencyResolutionRequiredException e) {
                throw new RuntimeException(e);
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            }
        }
    
    1. Init spring context
    2. 使用java classloader或spring上下文获取资源,但不要在资源字符串前加“classpath:”(至少在我的情况下它不起作用)

      Resource resource = springContext.getResource("myPluginConfig.properties");
      if (!resource.exists()) {
          throw new RuntimeException("Resource does not exist and resource object pointing to nothing was created");
      }
      
      Properties properties = PropertiesLoaderUtils.loadProperties(resource);