Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Maven 如何创建赢得';t依赖项版本与其他版本冲突链接它n_Maven_Jar_Java - Fatal编程技术网

Maven 如何创建赢得';t依赖项版本与其他版本冲突链接它n

Maven 如何创建赢得';t依赖项版本与其他版本冲突链接它n,maven,jar,java,Maven,Jar,Java,我想为java库创建一个jar(我们称之为mylibrary)。MyLibrary有许多依赖项,是用maven构建的。例如,假设mylibrary依赖于一个名为foo的jar,mylibrary使用foo的1.1版 我想把这个java库分发给其他人。他们将在我的库中链接并使用它提供的API 当用户构建他们的项目(让我们称之为他们的库)时,假设他们想要使用foo的1.2版。因此,他们的项目包含两个依赖项: 我的图书馆1.0 foo 1.2 这会导致jar版本冲突,因为mylibrary使用的是Fo

我想为java库创建一个jar(我们称之为mylibrary)。MyLibrary有许多依赖项,是用maven构建的。例如,假设mylibrary依赖于一个名为foo的jar,mylibrary使用foo的1.1版

我想把这个java库分发给其他人。他们将在我的库中链接并使用它提供的API

当用户构建他们的项目(让我们称之为他们的库)时,假设他们想要使用foo的1.2版。因此,他们的项目包含两个依赖项: 我的图书馆1.0 foo 1.2 这会导致jar版本冲突,因为mylibrary使用的是Foo1.1,而他们的Library使用的是Foo1.2,通常不起作用

可以在maven中使用一个特殊的构建目标来解决这个问题吗?也就是说,mylibrary中的所有内容都将绑定到一个jar中,并且只能在mylibrary jar中加载其他类

而且他们的库从mylibrary jar加载的类只包括mylibrary打算公开的API,而不包括其依赖项。如果用户想要使用Foo1.2,那么他们可以自由使用

基本上我不希望我的图书馆1.0把Foo1.1强加到他们的图书馆里。他们的图书馆应该可以免费使用Foo1.2,如果它想这样做的话

我已经研究过类加载器作为一种解决方案,但我认为这不会奏效。似乎类装入器只允许类的实例化器拥有控制权。也就是说,他们的图书馆可以使用类加载器来解决这个问题,但我认为我不能从我的图书馆做很多事情。我不想强迫他们的图书馆在代码中使用类加载器


这在java中可能吗?或者这是java的一个缺点?

如果我理解您的问题,您应该在依赖项中使用提供的
范围。这意味着将使用您的库的库/应用程序应该提供
foo
的版本

<dependency>
  <groupId>...</groupId>
  <artifactId>foo</artifactId>
  <!-- this version is applicable only in your project -->
  <version>1.1</version> 
  <scope>provided</scope>
</dependency>

...

.

您可以使用Maven shade插件(请参阅)的类重新定位功能

这样,“foo”的所有类都将被重新定位到另一个包(在本例中为myprivate.org.foo),实际上创建了一个新的foo私有实例,该实例仅由您的库使用:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.2</version>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
        <configuration>
          <relocations>
            <relocation>
              <pattern>org.foo</pattern>
              <shadedPattern>myprivate.org.foo</shadedPattern>
            </relocation>
          </relocations>
        </configuration>
      </execution>
    </executions>
  </plugin>

org.apache.maven.plugins
maven阴影插件
2.2
包裹
阴凉处
org.foo
myprivate.org.foo
然而,请注意,这种技术会导致罐子大量爆炸。通常情况下,Foo1.2和1.1应该足够兼容,以便您的库能够与1.2SO兼容。因此,他们的图书馆仍然可以免费使用1.2。shade插件的重新定位是针对版本之间不兼容的情况(例如ASM1.x和2.x)

请考虑是否真的需要阴影。


另一种使用不同类加载器的方法是使用OSGI,它允许相同的库以不同的版本出现。

这是否会阻止您在mylibrary的实现中选择foo的版本。我认为这个解决方案不如我想象的那么有效。如果我的图书馆更改了版本1.2,我的图书馆最终将使用版本1.2而不是1.1。对的感谢您的帮助。您选择测试的版本在mylibrary的pom中声明。您可以尝试在多个版本中再次自动化一些测试。但是我想我不理解你的问题,因为你想让用户选择foo版本,而现在你要求我阻止foo版本(我很困惑)。