aspose file tools*
The moose likes Ant, Maven and Other Build Tools and the fly likes Running standalone maven-built apps Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Engineering » Ant, Maven and Other Build Tools
Bookmark "Running standalone maven-built apps" Watch "Running standalone maven-built apps" New topic
Author

Running standalone maven-built apps

Emilio Kazwell
Ranch Hand

Joined: Aug 28, 2009
Posts: 37
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,
Freddy Wong
Ranch Hand

Joined: Sep 11, 2006
Posts: 959

Try this.



SCJP 5.0, SCWCD 1.4, SCBCD 1.3, SCDJWS 1.4
My Blog
Emilio Kazwell
Ranch Hand

Joined: Aug 28, 2009
Posts: 37
Thank you!
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

I forget the target at the moment, but you can also have it jar up the entire application including dependencies.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16142
    
  21

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.


Customer surveys are for companies who didn't pay proper attention to begin with.
Emilio Kazwell
Ranch Hand

Joined: Aug 28, 2009
Posts: 37
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
Rancher

Joined: Sep 29, 2008
Posts: 12617

It doesn't need to; the libraries are exploded and jarred.
Emilio Kazwell
Ranch Hand

Joined: Aug 28, 2009
Posts: 37
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
Rancher

Joined: Sep 29, 2008
Posts: 12617

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

Joined: Aug 28, 2009
Posts: 37
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

Joined: Jun 25, 2001
Posts: 16142
    
  21

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

Joined: Aug 28, 2009
Posts: 37
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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Running standalone maven-built apps