26

I am using maven-compile plugin to compile classes. Now I would like to add one jar file into the current classpath. That file stays in another location (let's say c:/jars/abc.jar . I prefer to leave this file here). How can I do that?

If I use classpath in the argument:

<configuration>
 <compilerArguments>
  <classpath>c:/jars/abc.jar</classpath>
 </compilerArguments>
</configuration>

it will not work because it will override the current classpath (that includes all the dependencies)

yegor256
  • 102,010
  • 123
  • 446
  • 597
David
  • 3,538
  • 9
  • 39
  • 50
  • Does this jar need to be at exact that location or do you just need a way to include local jars? – Gamlor Aug 04 '10 at 23:13
  • 2
    Duplicate of [Maven, how to add additional libs not available in repo](http://stackoverflow.com/questions/2479046/maven-how-to-add-additional-libs-not-available-in-repo), [Maven. What to do with “homeless” jars?](http://stackoverflow.com/questions/2916949/maven-what-to-do-with-homeless-jars), [Local jars are not included in class path](http://stackoverflow.com/questions/3280834/local-jars-are-not-included-in-class-path/3281409#3281409) and many others. – Pascal Thivent Aug 05 '10 at 10:39
  • 2
    Did you find a way to add dir? Instead of adding each and individual jar in classpath? – SJunejo Aug 03 '16 at 02:05

4 Answers4

11

This might have been asked before. See Can I add jars to maven 2 build classpath without installing them?

In a nutshell: include your jar as dependency with system scope. This requires specifying the absolute path to the jar.

See also http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

Community
  • 1
  • 1
michid
  • 10,536
  • 3
  • 32
  • 59
  • 11
    I wonder when people will stop suggesting abusing the `system` scope See Brian's [answer](http://stackoverflow.com/questions/364114/can-i-add-jars-to-maven-2-build-classpath-without-installing-them/764684#764684) in the question you linked to. See also [this previous answer](http://stackoverflow.com/questions/3280834/local-jars-are-not-included-in-class-path/3281409#3281409). – Pascal Thivent Aug 05 '10 at 10:38
  • 1
    one more question. If i need to add a folder (contains many .class file) into classpath. how can i do it. – David Aug 05 '10 at 15:03
  • 1
    @Pascal Thivent -- well, it will end when people stop doing nonsense like the bin.zip contained in the org.bytedeco javacv-0.9 project in maven central. If you talk about normal maven behavior, well, as a user I cannot fix the maven upload..... maybe I should complain at maven central. – user1050755 Oct 30 '14 at 02:25
  • this won't work for a folder or dir of jars or classes unfortunately! – kisna Sep 27 '19 at 20:59
4

The classpath setting of the compiler plugin are two args. Changed it like this and it worked for me:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.6.1</version>
    <configuration>
      <compilerArgs>
         <arg>-cp</arg>
         <arg>${cp}:${basedir}/lib/bad.jar</arg>
      </compilerArgs>
    </configuration>
   </plugin>

I used the gmavenplus-plugin to read the path and create the property 'cp':

<plugin>
        <!--
          Use Groovy to read classpath and store into
          file named value of property <cpfile>

          In second step use Groovy to read the contents of
          the file into a new property named <cp>

          In the compiler plugin this is used to create a
          valid classpath
        -->
        <groupId>org.codehaus.gmavenplus</groupId>
        <artifactId>gmavenplus-plugin</artifactId>
        <version>1.12.0</version>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <!-- any version of Groovy \>= 1.5.0 should work here -->
            <version>3.0.6</version>
            <type>pom</type>
            <scope>runtime</scope>
          </dependency>
        </dependencies>
        <executions>
          <execution>
            <id>read-classpath</id>
            <phase>validate</phase>
            <goals>
              <goal>execute</goal>
            </goals>
          </execution>

        </executions>
        <configuration>
          <scripts>
            <script><![CDATA[
                    def file = new File(project.properties.cpfile)
                    /* create a new property named 'cp'*/
                    project.properties.cp = file.getText()
                    println '<<< Retrieving classpath into new property named <cp> >>>'
                    println 'cp = ' + project.properties.cp
                  ]]></script>
          </scripts>
        </configuration>
      </plugin>
Paul Verest
  • 60,022
  • 51
  • 208
  • 332
Zikzak
  • 41
  • 1
3

From docs and example it is not clear that classpath manipulation is not allowed.

<configuration>
 <compilerArgs>
  <arg>classpath=${basedir}/lib/bad.jar</arg>
 </compilerArgs>
</configuration>

But see Java docs (also https://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/tooldocs/solaris/javac.html)

-classpath path Specifies the path javac uses to look up classes needed to run javac or being referenced by other classes you are compiling. Overrides the default or the CLASSPATH environment variable if it is set.

Maybe it is possible to get current classpath and extend it,
see in maven, how output the classpath being used?

    <properties>
      <cpfile>cp.txt</cpfile>
    </properties>

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.9</version>
    <executions>
      <execution>
        <id>build-classpath</id>
        <phase>generate-sources</phase>
        <goals>
          <goal>build-classpath</goal>
        </goals>
        <configuration>
          <outputFile>${cpfile}</outputFile>
        </configuration>
      </execution>
    </executions>
  </plugin>

Read file (Read a file into a Maven property)

<plugin>
  <groupId>org.codehaus.gmaven</groupId>
  <artifactId>gmaven-plugin</artifactId>
  <version>1.4</version>
  <executions>
    <execution>
      <phase>generate-resources</phase>
      <goals>
        <goal>execute</goal>
      </goals>
      <configuration>
        <source>
          def file = new File(project.properties.cpfile)
          project.properties.cp = file.getText()
        </source>
      </configuration>
    </execution>
  </executions>
</plugin>

and finally

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.6.1</version>
    <configuration>
      <compilerArgs>
         <arg>classpath=${cp}:${basedir}/lib/bad.jar</arg>
      </compilerArgs>
    </configuration>
   </plugin>
Paul Verest
  • 60,022
  • 51
  • 208
  • 332
  • 3
    Surprisingly, there is no easy way to add an external folder of non-maven dependencies to maven's classpath. None of the approaches here seem to work, they fail with invalid flag: classpath=/pathtojar.jar:/anotherjar.jar – kisna Sep 27 '19 at 19:13
2

We mixed two of the answers found here to solve a similar problem. Our project needs a JAR only in compile stage, but add a local dependency, using system scope, it is unuseful because Maven refuse the artifact publication with an error related to a missing dependency.

The snippets used are the following:

  <properties>
    <classpathfile>${basedir}/classpathfile.classpath</classpathfile>
  </properties>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.9</version>
        <executions>
          <execution>
            <id>build-classpath</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>build-classpath</goal>
            </goals>
            <configuration>
              <outputFile>${classpathfile}</outputFile>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.codehaus.gmaven</groupId>
        <artifactId>gmaven-plugin</artifactId>
        <version>1.4</version>
        <executions>
          <execution>
            <phase>generate-resources</phase>
            <goals>
              <goal>execute</goal>
            </goals>
            <configuration>
              <source>
                def file = new File(project.properties.classpathfile)
                project.properties.originalClassPath = file.getText()
              </source>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <compilerArgs>
            <arg>-cp</arg>
            <arg>${originalClassPath}${path.separator}${basedir}/../../../bin/POM_RUNTIME_PLACEHOLDER/ExtraJar.jar</arg>
          </compilerArgs>
        </configuration>
      </plugin>

Maven is able to compile and successfully deploy the artifacts. If anyone is interested the full POM is available in GitHub under project NuReflector, defaultPOM.template under src/NuReflector.

domusmagister
  • 147
  • 1
  • 4