• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Maven, dependencies and classpath tales of woe

 
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This post is a follow-on discussion/question of this one:
https://coderanch.com/t/668699/java/java/NoClassDefFoundError

I've got a Maven project in ~/mvn/phrases. In that dir I have this pom.xml file:


When I build the package then run the code I get this:

Sure enough there is no reference to LoggerFactory in my jar file. Shouldn't this dependency in pom.xml cause a jar file to be built or retrieved?

I don't see any evidence in the output of "mvn package" that it did anything with that dependency. And, there's no slf4j jar or anything in any of the project directories.

I appreciate the help.



 
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If I remember correctly, you have to add Maven's local repo to your classpath: ~.m2/repository

There is a way of including the dependencies in the jar; I'll look into that next.  I generally use Maven from the Eclipse IDE so I'm not used to the command line.
 
Stan Lederer
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the engagement. I'm not following you, though. When I build the package shouldn't maven in reading pom.xml see my dependencies and retrieve/build whatever I need? I see no evidence of it having done that so I don't see what adding my local repo to the classpath would accomplish.

Thanks.
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When you say "retrieve/build what I need", if you mean "put all the dependencies into one jar file", the answer is no.  Maven builds the jar in a way that allows you to specify your library directory, so that your different projects can share library (jar) files.  This library need to be in the classpath.  If you want one, executable jar with all the dependencies in it, I think the best way is to use the Shade plugin.  At least that's the way I did it.  Here is the relevant part of my pom file:
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If seeing the whole project in context makes more sense to you, you can do that here.
 
Stan Lederer
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's the core question, forgetting about building a single fat jar file for now. Where is slf4j-api? I listed it as a dependency but Maven didn't retrieve it, or build it, or do anything with it as far as I can tell. So, I have no jar file to add to my classpath.
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It isn't in ~.m2/repository/org/slf4j/slf4j-api ?
 
Stan Lederer
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Aha! That explains absolutely everything! I didn't understand that maven creates one repository for all of my projects. Yesterday I had created a project and it downloaded opennlp for it. Today when I created a new project that uses opennlp it didn't have to retrieve it off the net because it was already there. And, I see the slf4j-api jar there. I've added it to my classpath.

I'm good now. Thanks VERY much for your help.
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome.  It is confusing at first.
 
Rancher
Posts: 4801
50
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why are you creating a classpath (referencing your other thread)?

You have this in your pom:


You've asked Maven to produce an executable jar file, with the classpath included (well, the jar file names anyway).
If all the jar files are in the same place you could just add the classpathPrefix entry to stick the directory path in.
 
Stan Lederer
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dave, I was playing around with addClasspath but didn't get it to work. I do have a variety of jar files sprinkled here and there. I ended up writing a shell script with a long "java -cp" line that works for me. I use that script to launch the Java code.
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ideally, you would have one entry in your -cp option: the local Maven repository.  Your dependencies go there and the install phase should write any projects of yours to the repository too.
 
Stan Lederer
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah, that's an intriguing idea. I did "mvn install" and it copied my application jar file into my Maven repository. Then I try to run the thing:
I get this error:
The jar file is there.

Any idea why Java isn't finding the class?

 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You will need to add a dependency to the other project(s):

We're right on the edge of my knowledge of Maven, so hopefully that works.  There is a more complete explanation here using the Eclipse IDE.
 
Stan Lederer
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmmm... There really only is the one project. It has dependencies on OpenNLP and SF4J. The jar file is in the Maven repository and the jar file has the right class in it. I'm going to give up on this and someday figure it out. I am able to run the code by adding the jar file to the "java -cp" command so I'm good.

Thanks for your help.
 
Saloon Keeper
Posts: 27807
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm doing a superficial reading of this thread, so I may be getting it all wrong, but it sounds like the goal is to create an executable JAR.

An executable JAR that has dependencies (library JARs) has problems. That's because you cannot just include a JAR within another JAR. The JVM classloader won't look in those JARS - they are not part of the classpath, per the Java specs. Hence ClassNotFound and NoClassDefinition exceptions.

The way around that is to build a JAR that contains a custom classloader that will look inside embedded JARs. There is a Maven plugin that will do this.

It's a fairly common thing, so search this forum for "executable jar" and you'll probably find something useful.
 
Knute Snortum
Sheriff
Posts: 7125
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are two Maven plugins that will create executable jars and I would recommend the Shade plugin.
 
Stan Lederer
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, everyone. I will look into executable jars.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic