17

I have a project that uses "system" scope to specify a jar file included in my project's WEB-INF/lib dir. This artifact is not in any of the maven repositories, so I must include it as part of my project. I do so with the following:

    <dependency>
        <groupId>com.example</groupId>
        <artifactId>MySpecialLib</artifactId>
        <version>1.2</version>
        <scope>system</scope>
        <systemPath>${basedir}/src/main/webapp/WEB-INF/lib/MySpecialLib-1.2.jar</systemPath>
    </dependency>

This has worked great for most things.

But now I'm trying to run some code on the command line (outside of my webapp, via a main() method I have added) and mvn exec:java can't resolve code in MySpecialLib because it's not included in the "runtime" classpath.

How can I either:

  • add MySpecialLib to the runtime classpath

or

  • tell mvn exec:java to also use the system classpath ?

I've tried mvn exec:java -Dexec.classpathScope=system, but that leaves off everything that's on runtime.

George Armhold
  • 30,824
  • 50
  • 153
  • 232

4 Answers4

16

Use 'compile' scope to run maven exec plugin - mvn exec:java -Dexec.classpathScope=compile. This will include system-scoped dependencies.

E.G.
  • 181
  • 2
  • 9
3

As E.G. pointed out, the solution is to use the compile scope when running exec.

On each invocation:

mvn exec:java -Dexec.classpathScope=compile

or directly in the exec-plugin-configuration:

     <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        ...
        <configuration>
              <classpathScope>compile</classpathScope>
        </configuration>
    </plugin>
Tommy
  • 739
  • 8
  • 24
1

Interesting to know that classpathScope=system drops runtime dependencies. I found that by including it as a plugin in the pom.xml works as an alternative. Could you please try and let me know if it works for you too?

So I added a system level dependency to commons-collection as an example like you have for your artifact:-

 <dependency>
        <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.0</version>
        <scope>system</scope>
        <systemPath>C:\\<some_path>\\commons-collections-3.0.jar</systemPath>
    </dependency>

Then in the <build> tag I have the exec-maven-plugin plugin to be executed in the install phase:-

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>exec-maven-plugin</artifactId>
   <version>1.1</version>
   <executions>
    <execution>
     <phase>install</phase>
     <goals>
      <goal>java</goal>
     </goals>
     <configuration>
      <mainClass>com.stackoverflow.test.App</mainClass>
     </configuration>
    </execution>
   </executions>
  </plugin>

Then I ran mvn install. I also made sure com.stackoverflow.test.App class has some code that invokes a class from commons-collections-3.0.

Hope this helps.

CoolBeans
  • 20,654
  • 10
  • 86
  • 101
0

The right answer is to use the maven-install-plugin and Put The Jar Into Your Local Repo. Or, better yet, run nexus or artifactory and use the deploy plugin to put the jar into there. System classpath is just a world of hurt.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
  • 2
    The problem with adding it to your local repo is that it's out of sight and out of mind- easy to forget that it's something custom you've added to your build, and easy to lose. Also other devs on your team must be instructed to do the same manual install. Nexus is a giant hammer of a solution for what ought to be a simple problem- adding a customized artifact to your build. I do agree with you on the world of hurt however. :-) – George Armhold Mar 13 '11 at 14:11
  • I have written makefiles that script installing to the local repo to make it unforgettable. Also, free nexus is a tiny hammer that provides a wealth of useful features, in my view. – bmargulies Mar 13 '11 at 15:27