Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven project depending on two versions of the same artifact

Tags:

java

maven

I have a project with two seperate modules that uses sqlline and another library(say OtherLib) that depends on jline. However on different versions.

External Libraries

Module1 uses Sqlline depends on jline 2.10
Module2 uses OtherLib depends on jline 0.9.94

And the two versions are incompatible. Therefore I have set the classpaths such that Module1 will search in $HOME/lib/module1 folder first and Module2 in $HOME/lib folder first.

Is there a way to specify maven to download the artifact to a source directory first(say ../resources/lib) and then copy it to package during packaging time in assembly.xml?

I know that for copying from source directory the following code can be used.

<fileSets>
   <fileSet> 
        <directory>../resources/lib</directory>
        <outputDirectory>${HOME}/lib/module1</outputDirectory>
        <directoryMode>755</directoryMode>
        <fileMode>644</fileMode>
        <includes>
            <include>*.jar</include>
        </includes>
    </fileSet>
</fileSets>

Also to get maven to download the dependency I can use (for Module2)

 <dependencySets>
    <dependencySet>
        <useProjectArtifact>false</useProjectArtifact>
        <outputDirectory>${HOME}/lib</outputDirectory>
        <directoryMode>755</directoryMode>
        <fileMode>644</fileMode>
        <includes>
            <include>jline:jline:jar:0.9.94</include>
        </includes>
    </dependencySet>
<dependencySets>

How can I make sure jline:jline:jar:2.10 is downloaded to ../resources/lib folder first?

like image 613
Sach Avatar asked Nov 26 '14 11:11

Sach


2 Answers

I found a an answer here using maven-dependency-plugin

In pom.xml

<build>
   <plugins>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-dependency-plugin</artifactId>
         <version>2.1</version>
         <executions>
           <execution>
               <id>copy-model</id>
               <phase>package</phase>
               <goals>
                  <goal>copy</goal>
               </goals>
               <configuration>
                 <artifactItems>
                   <artifactItem>
                       <groupId>jline</groupId>
                       <artifactId>jline</artifactId>
                       <version>2.10</version>
                       <type>jar</type>
                   </artifactItem>
                 <artifactItems>
                 <outputDirectory>../../resources/lib</outputDirectory>
               </configuration>
           </execution>
        </executions>
     </plugin>
   <plugins>  
 <build>
   

And in assembly.xml

   <fileSet>
        <directory>../../resources/lib</directory>
        <outputDirectory>${HOME}/lib/module1</outputDirectory>
        <directoryMode>755</directoryMode>
        <fileMode>644</fileMode>
        <includes>
            <include>jline-*</include>
        </includes>
    </fileSet>

jline-0.9.94 is included in a dependencySet as any other dependency. I hope this helps. :)

like image 55
Sach Avatar answered Oct 03 '22 15:10

Sach


If you're absolutely sure, what you're doing, you can repackage one of the version using something like maven-shade-plugin. But please be absolutely sure, what you're doing.

With maven-shade-plugin you could create a new Maven module, say jline:jline_2_10:jar:1.0 and use jline:jline:jar:2.10 as a dependency. The maven-shade-plugin would then package it in your jline_2_10-1.0.jar.

Since your new artifact has its own groupId:artifactId combination, there will be no conflicts with the other jline:jline:jar:0.9.94 artifact, so you'll happily have both in the classpath.

like image 20
lexicore Avatar answered Oct 03 '22 17:10

lexicore