Java 如何在不使用重量级框架的情况下解决Jar地狱?

Java 如何在不使用重量级框架的情况下解决Jar地狱?,java,jar,Java,Jar,我如何避免或解决?不使用诸如众所周知的框架之类的重型框架。 假设我们有两个不再受支持的必需依赖项,它们在同一库的不同版本中稳定工作?我需要所有的员工一起工作。即将推出,并且将成为Java 9的一部分 ->我使用sonatype jarjar maven插件自动创建重命名为不同包的从属类的副本 这将为您的库提供其依赖项的私有副本,从而防止与部署它的任何其他库发生版本冲突 请记住,某些软件的许可条件可能会阻止您对其进行修改 例如,以下两条规则创建Apache commons-lang3的私有副本。A

我如何避免或解决?不使用诸如众所周知的框架之类的重型框架。
假设我们有两个不再受支持的必需依赖项,它们在同一库的不同版本中稳定工作?我需要所有的员工一起工作。

即将推出,并且将成为Java 9的一部分


->

我使用sonatype jarjar maven插件自动创建重命名为不同包的从属类的副本

这将为您的库提供其依赖项的私有副本,从而防止与部署它的任何其他库发生版本冲突

请记住,某些软件的许可条件可能会阻止您对其进行修改

例如,以下两条规则创建Apache commons-lang3的私有副本。Apache commons lang通常部署在名为
org.Apache.commons.lang3
的包中,但这里我在包
com.lexicalscope.fluentreflection.internal.lang3
中创建了它的副本。该插件自动修复了我的库使用Apache commons-lang3链接到副本的所有位置

<rule>
    <pattern>org.apache.commons.lang3.**.*</pattern>
    <result>com.lexicalscope.fluentreflection.internal.lang3.@1.$@2</result>
</rule>
<rule>
    <pattern>org.apache.commons.lang3.*</pattern>
    <result>com.lexicalscope.fluentreflection.internal.lang3.$@1</result>
</rule>

org.apache.commons.lang3.**
com.lexicalscope.fluentreflection.internal.lang3@1.$@2
org.apache.commons.lang3*
com.lexicalscope.fluentreflection.internal.lang3.$@1

您可以使用相同的方法使用第三方库自己的依赖项的私有副本重新打包第三方库

以下是maven构建配置的完整示例:

<plugin>
    <groupId>org.sonatype.plugins</groupId>
    <artifactId>jarjar-maven-plugin</artifactId>
    <version>1.5</version>
    <executions>
        <execution>
            <id>jarjar-classes</id>
            <phase>process-test-classes</phase>
            <goals>
                <goal>jarjar</goal>
            </goals>
            <configuration>
                <overwrite>true</overwrite>
                <input>{classes}</input>
            </configuration>
        </execution>
        <execution>
            <id>jarjar-testclasses</id>
            <phase>process-test-classes</phase>
            <goals>
                <goal>jarjar</goal>
            </goals>
            <configuration>
                <overwrite>true</overwrite>
                <input>{test-classes}</input>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <overwrite>true</overwrite>
        <includes>
            <include>com.google.inject:guice</include>
            <include>com.googlecode.lambdaj:lambdaj</include>
            <include>org.apache.commons:commons-lang3</include>
            <include>com.google.guava:guava</include>
        </includes>
        <rules>
            <rule>
                <pattern>com.google.common.**.*</pattern>
                <result>com.lexicalscope.fluentreflection.internal.guava.@1.$@2</result>
            </rule>
            <rule>
                <pattern>com.google.common.*</pattern>
                <result>com.lexicalscope.fluentreflection.internal.guava.$@1</result>
            </rule>
            <rule>
                <pattern>com.google.inject.**.*</pattern>
                <result>com.lexicalscope.fluentreflection.internal.guice.@1.$@2</result>
            </rule>
            <rule>
                <pattern>com.google.inject.*</pattern>
                <result>com.lexicalscope.fluentreflection.internal.guice.$@1</result>
            </rule>
            <rule>
                <pattern>ch.lambdaj.**.*</pattern>
                <result>com.lexicalscope.fluentreflection.internal.lamdaj.@1.$@2</result>
            </rule>
            <rule>
                <pattern>ch.lambdaj.*</pattern>
                <result>com.lexicalscope.fluentreflection.internal.lamdaj.$@1</result>
            </rule>
            <rule>
                <pattern>org.apache.commons.lang3.**.*</pattern>
                <result>com.lexicalscope.fluentreflection.internal.lang3.@1.$@2</result>
            </rule>
            <rule>
                <pattern>org.apache.commons.lang3.*</pattern>
                <result>com.lexicalscope.fluentreflection.internal.lang3.$@1</result>
            </rule>
        </rules>
    </configuration>
</plugin>

org.sonatype.plugins
JarMaven插件
1.5
jarjar类
过程测试类
贾贾尔
真的
{classes}
jarjar测试类
过程测试类
贾贾尔
真的
{测试类}
真的
注入:guice
com.googlecode.lambdaj:lambdaj
org.apache.commons:commons-lang3
番石榴:番石榴
com.google.common.**
com.lexicalscope.fluentreflection.internal.guava@1.$@2
com.google.common*
com.lexicalscope.fluentreflection.internal.guava.$@1
com.google.inject.**
com.lexicalscope.fluentreflection.internal.guice@1.$@2
com.google.inject*
com.lexicalscope.fluentreflection.internal.guice.$@1
兰姆达吉**
com.lexicalscope.fluentreflection.internal.lamdaj.@1.$@2
兰姆达斯先生*
com.lexicalscope.fluentreflection.internal.lamdaj.$@1
org.apache.commons.lang3.**
com.lexicalscope.fluentreflection.internal.lang3@1.$@2
org.apache.commons.lang3*
com.lexicalscope.fluentreflection.internal.lang3.$@1

您已经进行了哪些研究?编辑:这个解决方案真的是任何人都可以很容易地实现的。只需了解类是如何被发现的,并制作自己的类装入器和类查找。看起来很有帮助。还要看孩子先加载,家长最后加载。替代什么?我相信这篇文章谈到了它是什么,以及可以做些什么,我已经搜索了很多。我找到了一些方法来尝试自己实现(使用类装入器indepth)或使用OSGi容器,这意味着重大的架构更改。我想找到一些轻量级的库,将此作为主要目标使用连贯的语言,如C#。问题解决了。@Krythic,你可能想更深入地研究C#,谢谢你的完整答案!您的解决方案肯定适用于我控制下的“我的组件”,我可以为其选择“类路径中的正确代码”。两个不再受支持的必需依赖项在同一库的不同版本中稳定工作,这两个依赖项如何?(更新了我的问题)您可以使用相同的方法使用第三方库自己的依赖项的私有副本重新打包第三方库。据我所知,这将意味着大量的手动分析和maven工作。无论如何,谢谢你的工作解决方案。我想知道实现/重用简单库是否可行,它可以改变在运行时查找类的方式:不是保留唯一的副本(在类路径树中可能更高的副本),而是将所有版本保持在适当的类加载器下,并在运行时选择适当的类加载器。就像OSGi一样。我不知道如果没有与OSGi或Jigsaw重量相当的东西,你怎么能在运行时做到这一点。也许maven shade插件可以减少您需要做的maven工作:OSGi非常重,因为目标区域非常宽。我认为,如果这个问题,正在讨论中,将是一些更烦人和值得花时间,我们会看到一些可怕的解决方案,如谷歌果汁相比,春天。