简体   繁体   English

hk2居民文件被uber-jar程序集覆盖

[英]hk2 inhabitant files are being overwritten by uber-jar assembly

I'm trying to build an executable jar ( uberjar ) using the maven-assembly-plugin . 我正在尝试使用maven-assembly-plugin构建一个可执行jar( uberjar )。 The project uses HK2 as the provider for dependency injection. 该项目使用HK2作为依赖项注入的提供者。

@Service s are defined in the project as well as in some of the dependencies. @Service在项目以及某些依赖项中定义。 The HK2 service locator is populated from inhabitant files at META-INF/hk2-locator/default , generated at compile/build time. HK2服务定位器由在编译/构建时生成的META-INF/hk2-locator/default 居民文件填充。 I'm using the hk2-metadata-generator . 我正在使用hk2-metadata-generator

My problem is that the default assembly strategy jar-with-dependencies unpacks everything before building the jar. 我的问题是默认的组装策略jar-with-dependencies在构建jar之前会解压缩所有内容。 This overwrites META-INF/hk2-locator/default with whatever was unpacked last... As a result, the service locator cannot find all services. 这将用最后解压缩的内容覆盖META-INF/hk2-locator/default 。因此,服务定位器无法找到所有服务。

I have explored different solutions and am looking for guidance which one is the best. 我探索了不同的解决方案,并正在寻找最佳的指南。

1. Aggregate different inhabitant files during assembly 1.在组装过程中汇总不同的居民文件

I've created an assembly descriptor that combines all inhabitant files into one: 我创建了一个程序集描述符,将所有居民文件合并为一个:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
    <id>uberjar</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <containerDescriptorHandlers>
        <!-- remove this element and the following file-aggregator generates an empty file -->
        <!-- see https://issues.apache.org/jira/browse/MASSEMBLY-815 -->
        <containerDescriptorHandler>
            <handlerName>metaInf-services</handlerName>
        </containerDescriptorHandler>

        <containerDescriptorHandler>
            <handlerName>file-aggregator</handlerName>
            <configuration>
                <filePattern>META-INF/hk2-locator/default</filePattern>
                <outputPath>META-INF/hk2-locator/default</outputPath>
            </configuration>
        </containerDescriptorHandler>
    </containerDescriptorHandlers>
    <dependencySets>
        <dependencySet>
            <unpack>true</unpack>
            <scope>runtime</scope>
            <useProjectArtifact>true</useProjectArtifact>
        </dependencySet>
    </dependencySets>
</assembly>

Apart from the silly bug in the assembly plugin, this results in a combined inhabitant file that looks good. 除了程序集插件中的愚蠢错误外,这还会生成一个看起来不错的组合居民文件。 However, when I ask the Service locator to dump its descriptors, my project's services are detected several times. 但是,当我要求服务定位器转储其描述符时,将多次检测到我项目的服务。 I don't know if that is a problem, particularly for singleton services. 我不知道这是否有问题,特别是对于单例服务而言。

2. Don't unpack the dependencies 2.不要解压缩依赖项

The idea behind this was to leave the dependencies in their own jar-files, not touching their META-INF -files. 其背后的想法是将依赖项保留在其自己的jar文件中,而不涉及其META-INF文件。 I followed this post to build the jar, but I had classloading issues: dependencies could not be loaded despite the MANIFEST.MF specifying the jars in the classpath. 我按照这篇文章来构建jar,但是遇到了类加载的问题:尽管MANIFEST.MF在类路径中指定了jar,但是无法加载依赖项。

This feels like the cleanest solution, if only I could fix the classloading. 如果只有我可以解决此类问题,这似乎是最干净的解决方案。

3. Use runtime discovery instead of inhabitant files 3.使用运行时发现而不是居民文件

This solution is also promising. 该解决方案也很有希望。 Problem is that it doesn't work for my tests using hk2-testng (and I don't understand what is different here). 问题是它不适用于使用hk2-testng测试(我不明白这里有什么不同)。


If you have advice on the individual solutions or how best to proceed, I'd be very happy to hear from you. 如果您对单个解决方案或最佳方法有任何建议,我很高兴收到您的来信。

You can also go with a fourth option which is to run hk2-inhabitant-generator over the finished jar as the last step, something like: 您还可以使用第四个选项,即在完成的jar上运行hk2-inhabitant-generator作为最后一步,例如:

java org.jvnet.hk2.generator.HabitatGenerator --file *my-uber.jar*

When you run the HabitatGenerator like that it'll scan through all the files in the jar and will add the META-INF/hk2-locator/default file in the jar with all of the hk2 services. 当您像这样运行HabitatGenerator时,它将扫描jar中的所有文件,并将META-INF/hk2-locator/default文件添加到具有所有hk2服务的jar中。

This is a better option if your uber jar is parts and pieces of other jars rather than the entire thing because it is guaranteed to be more accurate (it won't contain services that aren't in the uber jar) 如果您的超级罐子是其他罐子的一部分而不是整个罐子,那么这是一个更好的选择,因为它可以保证更加准确(它不会包含非超级罐子中的服务)

HK2 inhabitant files are designed to work properly when concatenated together so option #1 above works. HK2居民文件被设计为在串联在一起时可以正常工作,因此上面的选项1有效。 We use that option when putting full modules together 当将完整的模块放在一起时,我们使用该选项

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM