2

I have a maven project that besides using normal repos also uses a local jar. The jar is defined in the manifest this way:

    <dependency>
        <groupId>com.mirrorworlds</groupId>
        <artifactId>lstnef</artifactId>
        <version>1.0.0</version>
        <optional>false</optional>
        <scope>system</scope>
        <systemPath>${basedir}/lib/lstnef-1.0.0.jar</systemPath>
    </dependency>

The install script works successfully, but after the app is launched I get this:

Exception in thread "main" java.lang.NoClassDefFoundError: 
com/mirrorworlds/lifestreams/mail/tnef/internet/TnefMultipart 
at ...processMails(MailProcessor.java:57)
at ...main(MailReader.java:42)

When I look inside the target jar I can't find these classes as well, though they are supposed to be inside lstnef-1.0.0.jar

I'll be thankful for any suggestions on solving this mystery.

2
  • 2
    Use a local repository manager and install this jar into it and than you can use it as a usal dependency. Makes life easier. Commented Oct 4, 2013 at 11:44
  • @khmarbaise, I'm totally new to maven and got this project to introduce some updates. It used to work somehow, but now I can't make it all get back together. Commented Oct 4, 2013 at 11:51

5 Answers 5

7

Check the Maven docs: http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

system
This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.

You will need to manually provide this JAR to the runtime environment yourself.

Or, and I would reccommend this approach, setup your own repository that you can add JARS to and manage them in the normal maven way

Sign up to request clarification or add additional context in comments.

6 Comments

Could you please explain this part: you have to provide the JAR which contains it explicitly? I did provide the jar in ${basedir}/lib/lstnef-1.0.0.jar when the target jar was compiled and the compilation was a sucess. I also tried to provide it with the target jar, but I keep getting this exception. What am I missing here?
The JAR you are providing is being used in the build process. But because its scope is equivalent to "provided" it is not included in the final build, so it expects the runtime to provide it.
The jar's scope is system, not provided
As per my quote "This scope is similar to provided". Meaning it behaves the same way, just that you need to provide the actual jar at build time
there is no problem with the jar at build time. The app fails to find classes at runtime.
|
1

Possible solution I use is installing this system JAR into the local Maven repository before compilation phase and then reference this JAR as a Maven artifact. I.e.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-install-plugin</artifactId>
    <version>2.2</version>
    <executions>
        <execution>
            <id>your-file</id>
            <inherited>false</inherited>
            <phase>validate</phase>
            <configuration>
                <file>${pom.basedir}/lib/your-file-4.8.jar</file>
                <repositoryLayout>default</repositoryLayout>
                <groupId>your-file</groupId>
                <artifactId>your-file</artifactId>
                <version>4.8</version>
                <packaging>jar</packaging>
                <generatePom>true</generatePom>
            </configuration>
            <goals>
                <goal>install-file</goal>
            </goals>
        </execution>
    </executions>
</plugin>

And then reference it:

<dependency>
    <groupId>your-file</groupId>
    <artifactId>your-file</artifactId>
    <version>4.8</version>    
</dependency>

Comments

1

Using the system scope tells maven that the dependency is available during maven "working-hours" at the system location that you provide (this is the difference to the provided scope that makes use of normal dependency resolution instead). After that you have to "provide" the file by yourself - eg by putting it into the CLASSPATH (hence the similarity to the provided scope). To install the file to your local repository cache you could refer to this article:

http://maven.apache.org/plugins/maven-install-plugin/examples/specific-local-repo.html

You can just ommit the localrepository path and maven will install in his local "cache" where it looks up any dependencies before going to remote repositories.

Maven will also suport you when you build a manifest.mf with Class-Path entry (e.g. when your application is running on localhost): To see how it works read here.

Comments

0

you need to use shade plugin http://maven.apache.org/plugins/maven-shade-plugin/

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.1</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <manifestEntries>
                    <Main-Class>org.sonatype.haven.ExodusCli</Main-Class>
                    <Build-Number>123</Build-Number>
                  </manifestEntries>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

1 Comment

Well, I don't actually need to keep the library as a jar inside jar. If it is unpacked, it's also fine with me.
0

To install local jar to local repository, do something like below.

mvn install:install-file -Dfile=lib/ojdbc6.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.4 -Dpackaging=jar

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.