This week's book giveaway is in the Design and Architecture forum.
We're giving away four copies of Communication Patterns: A Guide for Developers and Architects and have Jacqui Read on-line!
See this thread for details.
  • 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
  • Ron McLeod
  • Paul Clapham
  • Devaka Cooray
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Carey Brown
  • Mikalai Zaikin
Bartenders:
  • Lou Hamers
  • Piet Souris
  • Frits Walraven

Running standalone maven-built apps

 
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When you build a web application with maven, its is kind enough to take your dependencies and pack them into the target/web-inf/lib folder since it would defeat the purpose of maven to make you gather all of your dependencies when you want to run it. I'm developing an application that will not be run in an app server, just a jar with a shell/batch script to start it going. How can I get the same utility out of maven?

Ideally I would like maven to put all my dependencies into a target/lib folder (or something equivalent) so that my script can add that folder to the classpath when running the app. I think that the mvn exec:java plugin will run an app with the appropriate classpath, but I do not want to require my end user to have maven installed for the application to run.

Thanks,
 
Ranch Hand
Posts: 959
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Try this.

 
Emilio Kazwell
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you!
 
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I forget the target at the moment, but you can also have it jar up the entire application including dependencies.
 
Saloon Keeper
Posts: 28073
198
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

David Newton wrote:I forget the target at the moment, but you can also have it jar up the entire application including dependencies.



There's an executable jar plugin that does that. In fact, I think there are 2 different plugins for that. The one I use, at least, works quite well.
 
Emilio Kazwell
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Newton wrote:I forget the target at the moment, but you can also have it jar up the entire application including dependencies.



And it specifies the jarred dependencies in the manifest? If you remember what this is please post it. It would be very useful. Thanks.
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It doesn't need to; the libraries are exploded and jarred.
 
Emilio Kazwell
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It just puts all the dependencies' .class files in with mine? That seems like an unnecessary jumbling of code to me when I may want to un-jar a jar sometime and see what dependencies were added to it when troubleshooting, but oh well. It would still be useful if you remember the name. Thanks.
 
David Newton
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You determine dependencies from the dependency target of the POM--that's how you'd determine the dependencies of any Maven project, not by looking at build artifacts, no?
 
Emilio Kazwell
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In a happy-path, of course. I'm just saying that in the event I had some wacky error (like a linkage error) I would like to go to the actual end product and see what's there. Maybe this plug-in decides one day to slip up and put the wrong version of a dependency in my jar. If they weren't exploded it may be easier to figure that out and I could report the bug to the developers. I'd also guess it is also a bit more time consuming to un-jar these (possibly many) dependencies than it is to append ":/lib/" to the manifest's class-path and drop them there.

Mainly though I'm just confused as to why the developers would take the time to add this extra step when I don't see the upside to it. Obviously there could be a reason I'm not seeing, since I didn't have to design and code it myself, but it seems like an unnecessary destruction of information on the assumption that the end user would not need it and I generally dislike assumptions that remove my investigative powers.
 
Tim Holloway
Saloon Keeper
Posts: 28073
198
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
The only way you can build a single executable jar and still retain the identities of the included jars is if the application being executed provides itself with a custom classloader. The standard Java class loading mechanism doesn't look inside jars embedded within jars.

Such classloaders aren't that uncommon. For example, Tomcat does exactly that in order to resolve references to jars in the WEB-INF/lib directories of WARs. Likewise, container frameworks such as the old Avalon Phoenix system did that. It's just that you don't get that feature free with the language, nor is there a standard classloader bundled with the stock JVM that provides that capability. Although it's not that difficult (speaking from experience) to write one.

The way you determine the pedigree of a jar that's been exploded and merged into another jar is another matter. Since all well-written utility jars have distinct package names, it's usually not too difficult to track back a class or resource to the the original jar, especially when it's a Maven dependency. Getting the jar's metadata (version, etc.) could be a little more difficult, however, depending on whether the explode process made any attempt to preserve such metadata.

Maven, however, is designed to make the forward projection of builds fully deterministic, so the only time when you absolutely couldn't figure out what the versions of the contributions were would be if either fuzzy version requests were made (not considered good practice), or when the creating POM wasn't available. Most Maven projects are either open-source (meaning the POM is usually published on the Internet) or in-house (meaning that a well-run shop should have been keeping it under version control). For the relatively rare case where you'd get a Maven-build artifact with closed source, you're at the mercy of the vendor. But then, that's a problem with closed source in general. Knowing what version of the log4 jar is in the project is not really going to gain you that much if the core application source is not available anyway.
 
Emilio Kazwell
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:The only way you can build a single executable jar and still retain the identities of the included jars is if the application being executed provides itself with a custom classloader. The standard Java class loading mechanism doesn't look inside jars embedded within jars.

Such classloaders aren't that uncommon. For example, Tomcat does exactly that in order to resolve references to jars in the WEB-INF/lib directories of WARs. Likewise, container frameworks such as the old Avalon Phoenix system did that. It's just that you don't get that feature free with the language, nor is there a standard classloader bundled with the stock JVM that provides that capability. Although it's not that difficult (speaking from experience) to write one.



That's really interesting, Tim. I code in Java for a living but I don't really get the chance to get into the guts of the implementation i.e. writing ClassLoaders, compilers, etc. I hope I have more of those types of opportunities at some point to see it from a different perspective.
 
If somebody says you look familiar, tell them you are in porn. Or in these tiny ads:
We need your help - Coderanch server fundraiser
https://coderanch.com/wiki/782867/Coderanch-server-fundraiser
reply
    Bookmark Topic Watch Topic
  • New Topic