I have multiple web applications each using spring-hibernate and other open source libraries and portlets, so basically now each war file includes those jar files. How do I move these jars to a common location so that I don't have to put these in each war file? My jars are places in D:/ directory.
I tried creating modules but no success. e.g. if I added jar
<resources>
<resource-root path="mylib.jar"/>
</resources>
and mylib.jar needs another ABC class. That ABC class is in my WAR class-path. Here I get exception while loading this module. mylib.jar could not find ABC class and throws exception.
If those libraries are reused in several applications, probably the best solution would be to create JBoss modules.
For example, OJDBC library is used in several projects I'm developing. So, I added a new module to JBoss 7: https://community.jboss.org/wiki/CreateAModuleForOracleDatasourceInJBoss711Final (it's just an example).
But you said, that you tried creating modules, but with no luck. What was the problem? Did you get some errors?
EDIT
Answer updated in connection with updated question.
So, if I understood correctly, we can divide your libraries into two categories:
First category is "standard libraries": Spring, Hibernate, Log4j etc. So, these libraries might be added as modules into JBoss AS and reused in every WAR (scope=provided in Maven's dependency).
Any other non-standard libraries (i.e. written by yourself) might be added as modules as well. If these libraries require some other dependencies - these dependencies must be listed in module's XML file, as described in: https://docs.jboss.org/author/display/MODULES/Module+descriptors
Hope this helps at least a bit :)
Related
I am reading Maven documentation and came across the name uber-jar.
What does an uber-jar mean and what are its features/advantages?
Über is the German word for above or over (it's actually cognate with the English over).
Hence, in this context, an uber-jar is an "over-jar", one level up from a simple JAR (a), defined as one that contains both your package and all its dependencies in one single JAR file. The name can be thought to come from the same stable as ultrageek, superman, hyperspace, and metadata, which all have similar meanings of "beyond the normal".
The advantage is that you can distribute your uber-jar and not care at all whether or not dependencies are installed at the destination, as your uber-jar actually has no dependencies.
All the dependencies of your own stuff within the uber-jar are also within that uber-jar. As are all dependencies of those dependencies. And so on.
(a) I probably shouldn't have to explain what a JAR is to a Java developer but I'll include it for completeness. It's a Java archive, basically a single file that typically contains a number of Java class files along with associated metadata and resources.
ubar jar is also known as fat jar i.e. jar with dependencies.
There are three common methods for constructing an uber jar:
Unshaded: Unpack all JAR files, then repack them into a single JAR.
Works with Java's default class loader. Tools maven-assembly-plugin
Shaded: Same as unshaded, but rename (i.e., "shade") all packages of all dependencies. Works with Java's default class loader. Avoids some (not all) dependency version clashes. Tools maven-shade-plugin
JAR of JARs: The final JAR file contains the other JAR files embedded within. Avoids dependency version clashes. All resource files are preserved. Tools: Eclipse JAR File Exporter
for more
Paxdiablo's definition is really good.
In addition, please consider delivering an uber-jar is sometimes quite useful, if you really want to distribute a software and don't want customer to download dependencies by themselves. As a draw back, if their own policy don't allow usage of some library, or if they have to bind some extra-components (slf4j, system compliant libs, arch specialiez libs, ...) this will probably increase difficulties for them.
You can perform that :
basically with maven-assembly-plugin
a bit more further with maven-shade-plugin
A cleaner solution is to provide their library separately; maven-shade-plugin has preconfigured descriptor for that. This is not more complicated to do (with maven and its plugin).
Finally, a really good solution is to use an OSGI Bundle. There is plenty of good tutorials on that :)
For further configuration, please read those topics :
Should you provide dependent libraries in client jar?
Best practices in building and deploying Clojure applications: good tutorials?
The different names are just ways of packaging java apps.
Skinny – Contains ONLY the bits you literally type into your code editor, and NOTHING else.
Thin – Contains all of the above PLUS the app’s direct dependencies of your app (db drivers, utility libraries, etc).
Hollow – The inverse of Thin – Contains only the bits needed to run your app but does NOT contain the app itself. Basically a pre-packaged “app server” to which you can later deploy your app, in the same style as traditional Java EE app servers, but with important differences.
Fat/Uber – Contains the bit you literally write yourself PLUS the direct dependencies of your app PLUS the bits needed to run your app “on its own”.
Source: Article from Dzone
Reposted from: https://stackoverflow.com/a/57592130/9470346
A self-contained, executable Java archive. In the case of WildFly Swarm uberjars, it is a single .jar file containing your application, the portions of WildFly required to support it, an internal Maven repository of dependencies, plus a shim to bootstrap it all. see this
According to uber-JAR Documentation Approaches:
There are three common methods for constructing an uber-JAR:
Unshaded Unpack all JAR files, then repack them into a single JAR.
Tools: Maven Assembly Plugin, Classworlds Uberjar
Shaded Same as unshaded, but rename (i.e., "shade") all packages of all dependencies.
Tools: Maven Shade Plugin
JAR of JARs The final JAR file contains the other JAR files embedded within.
Tools: Eclipse JAR File Exporter, One-JAR.
For Java Developers who use SpringBoot, ÜBER/FAT JAR is normally the final result of the package phase of maven (or build task if you use gradle).
Inside the Fat JAR one can find a META-INF directory inside which the MANIFEST.MF file lives with all the info regarding the Main class. More importantly, at the same level of META-INF directory you find the BOOT-INF directory inside which the directory lib lives and contains all the .jar files that are the dependencies of your application.
I am reading Maven documentation and came across the name uber-jar.
What does an uber-jar mean and what are its features/advantages?
Über is the German word for above or over (it's actually cognate with the English over).
Hence, in this context, an uber-jar is an "over-jar", one level up from a simple JAR (a), defined as one that contains both your package and all its dependencies in one single JAR file. The name can be thought to come from the same stable as ultrageek, superman, hyperspace, and metadata, which all have similar meanings of "beyond the normal".
The advantage is that you can distribute your uber-jar and not care at all whether or not dependencies are installed at the destination, as your uber-jar actually has no dependencies.
All the dependencies of your own stuff within the uber-jar are also within that uber-jar. As are all dependencies of those dependencies. And so on.
(a) I probably shouldn't have to explain what a JAR is to a Java developer but I'll include it for completeness. It's a Java archive, basically a single file that typically contains a number of Java class files along with associated metadata and resources.
ubar jar is also known as fat jar i.e. jar with dependencies.
There are three common methods for constructing an uber jar:
Unshaded: Unpack all JAR files, then repack them into a single JAR.
Works with Java's default class loader. Tools maven-assembly-plugin
Shaded: Same as unshaded, but rename (i.e., "shade") all packages of all dependencies. Works with Java's default class loader. Avoids some (not all) dependency version clashes. Tools maven-shade-plugin
JAR of JARs: The final JAR file contains the other JAR files embedded within. Avoids dependency version clashes. All resource files are preserved. Tools: Eclipse JAR File Exporter
for more
Paxdiablo's definition is really good.
In addition, please consider delivering an uber-jar is sometimes quite useful, if you really want to distribute a software and don't want customer to download dependencies by themselves. As a draw back, if their own policy don't allow usage of some library, or if they have to bind some extra-components (slf4j, system compliant libs, arch specialiez libs, ...) this will probably increase difficulties for them.
You can perform that :
basically with maven-assembly-plugin
a bit more further with maven-shade-plugin
A cleaner solution is to provide their library separately; maven-shade-plugin has preconfigured descriptor for that. This is not more complicated to do (with maven and its plugin).
Finally, a really good solution is to use an OSGI Bundle. There is plenty of good tutorials on that :)
For further configuration, please read those topics :
Should you provide dependent libraries in client jar?
Best practices in building and deploying Clojure applications: good tutorials?
The different names are just ways of packaging java apps.
Skinny – Contains ONLY the bits you literally type into your code editor, and NOTHING else.
Thin – Contains all of the above PLUS the app’s direct dependencies of your app (db drivers, utility libraries, etc).
Hollow – The inverse of Thin – Contains only the bits needed to run your app but does NOT contain the app itself. Basically a pre-packaged “app server” to which you can later deploy your app, in the same style as traditional Java EE app servers, but with important differences.
Fat/Uber – Contains the bit you literally write yourself PLUS the direct dependencies of your app PLUS the bits needed to run your app “on its own”.
Source: Article from Dzone
Reposted from: https://stackoverflow.com/a/57592130/9470346
A self-contained, executable Java archive. In the case of WildFly Swarm uberjars, it is a single .jar file containing your application, the portions of WildFly required to support it, an internal Maven repository of dependencies, plus a shim to bootstrap it all. see this
According to uber-JAR Documentation Approaches:
There are three common methods for constructing an uber-JAR:
Unshaded Unpack all JAR files, then repack them into a single JAR.
Tools: Maven Assembly Plugin, Classworlds Uberjar
Shaded Same as unshaded, but rename (i.e., "shade") all packages of all dependencies.
Tools: Maven Shade Plugin
JAR of JARs The final JAR file contains the other JAR files embedded within.
Tools: Eclipse JAR File Exporter, One-JAR.
For Java Developers who use SpringBoot, ÜBER/FAT JAR is normally the final result of the package phase of maven (or build task if you use gradle).
Inside the Fat JAR one can find a META-INF directory inside which the MANIFEST.MF file lives with all the info regarding the Main class. More importantly, at the same level of META-INF directory you find the BOOT-INF directory inside which the directory lib lives and contains all the .jar files that are the dependencies of your application.
I'm migrating a project from JBoss 5 to 6.4. In the process I've updated several jar files in my build. I had several ClassCastExceptions which I resolved by taking the version of the specific classes from a jar in the JBoss system modules and using that in my app build. I've done so with two jars, jbossweb-7.5.26.Final-redhat-1.jar and jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar which contain the classes org.apache.catalina.connector.Request and javax.servlet.http.HttpServletRequest respectively. I'm using both of those jars as libs in my app build and all is compiling without error or warning. I've confirmed that when I remove those libs the app fails to compile as it can't find the included refernced classes, so I know I'm not actually referencing some other copy of those classes in my build. The app is deploying fine, but when I try hitting it I get an exception
JBWEB001018: An exception or error occurred in the container during
the request processing: java.lang.IncompatibleClassChangeError: Class
org.apache.catalina.connector.Request does not implement the requested
interface javax.servlet.http.HttpServletRequest
When I look at the class definitions from the jars in my editor (JDeveloper 12c) I can see that org.apache.catalina.connector.Request as defined in jbossweb-7.5.26.Final-redhat-1 does in fact implement javax.servlet.http.HttpServletRequest as defined in jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar.
I turned on verbose logging of classloading (JAVA_OPT -verbose:class), and confirmed that as JBoss is loading those two classes they are in fact being loaded from those two jar files, not some other one I didn't know about. I can see in my developer tool that the .class files I'm including in my project are from those same two jar files.
Possibly relevant, the classloading logs say JBoss is loading org.apache.catalina.connector.Request from RedHat/JBoss/EAP-6.4.0/modules/system/layers/base/.overlays/layer-base-jboss-eap-6.4.18.CP/org/jboss/as/web/main/. I'm not sure why it's using that copy/location rather than RedHat\JBoss\EAP-6.4.0\modules\system\layers\base\org\jboss\as\web\main.
So what gives? What I read on the error would suggest to me that jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar was compiled against a different version of HttpServletRequest than jbossweb-7.5.26.Final-redhat-1 includes.
Is that interpretation or the error correct? Does JBoss 6.4 really ship with incompatible jar files in its system modules? If so what versions of these jars do I need and how to I check compatibility? And can I safely switch to a different jar file without introducing more incompatibilities with other jars? What other causes might I be missing? Any help much appreciated here.
1/ You shouldn't depend on servlet API implementation
2/ You shouldn't include those implementation classes in your application are they are provided by the server itself
3/ You shouldn't put API jars or their implementation in your application or if you do this you need to exclude those modules from your application using a jboss-deployment.xml
Looks like the issue was that I was not using the modules.xml correctly. I needed to add dependencies for the two packages in my module.xml file
<dependencies>
<module name="org.jboss.as.web"/>
<module name="javax.servlet.api"/>
</dependencies>
I had previously added those modules to my war file's jboss-deployment-structure.xml and that did not do the trick and left me with ClassNotFoundExceptions. My Jboss-deployment-structure.xml now just references my own custom module as a dependency, which in turn has dependencies of its own.
I still don't understand what was causing the previous error, as it's all the same versions of the jar files in question so I don't know where a conflict was, but this got the error to go away and no more ClassNotFoundExceptions.
I have a web application developed in JAVA and I have a jar file. I would like to add the jar file to the application class-path. I know a web application includes libraries from WEB-INF/lib/* but I want to include a jar under this location C:/myLib.jar. Is that possible, if it does how can I do it?
regards,
micuss
ok, jboss is a bit difficult on classloading, but its definitely possible.
you need to add a new jboss module for your external jar and then declare your web application to depend on that module.
there's a complete guide for this here.
its possible to define a module to reference a jar file completely outside the jboss folder (c:\mylib.jar in your case) but it'll be easier on you if youre willing to move the jar into /modules
see here for complete documentation on how to write module descriptors. you can set the path to lead to your external jar (but its gonna be ugly)
Resin java server has a neat feature they call pomegranate ( http://www.caucho.com/projects/pomegranate/ ) which allows to just put various jar dependencies in server's directory (project-jars/) and then it loads them for a web-app from its pom.xml file.
Question is: how should I put the jars to resin's project-jars ? (just copying them doesn't work)
Details:
I have a working project with maven, with all dependencies configured in
projects pom.xml file. I can build a webapp war etc.
I copied the jar files to resin's project-jars/ as they were generated by maven for this particular web-app.
When I deploy the war, resin spots pom.xml and tries to resolve
dependencies; unfortunately it cannot find any artifacts in its
repository (project-jars).
I suppose this is because all the jars I have put there do not have
META-INF/maven/pom.xml files packed in them. They are just normal jars
like those downloaded by maven.
On pomegranate website they say resin scans project-jars for jars with pom.xml files, to determine their versions.
How should I create jars with pom.xml files included?
Or should I manually copy the foo-bar-1.0.pom files from the repository on my devel
machine to the resin's project-jars directory? (which kind of beats the purpose of all the auto-magic)
Thanks for answer,
Best regards
Horace
My understanding of the Pomegranate Draft specification is that:
Servlet containers can use pomegranate as an extension to the WEB-INF/lib with the following benefits:
Shared .jar files in a common repository, simplifying management and reducing .war sizes
Library dependency resolution, including the ability to handle sub-module incompatibilities
Familiar Maven pom.xml files, to take advantage of current development practices.
Optional integration with Servlet web-app containers
Optional integration with Java CanDI (JSR-299) managers
[...]
The web-app may contain an optional WEB-INF/pom.xml declaring the web-app's own dependencies.
So I guess the idea is to mark the dependencies as "provided" in the war pom.xml and to add them in WEB-INF/pom.xml for a deployment on Resin. I've not tested this though, so I might be wrong.
Actually, this pomegranate looks interesting but I don't get it entirely for now. While I understand its benefits, it seems to make the WAR not portable which is a big drawback. I'll dig it a bit further...
(EDIT: I'm putting an answer to a comment from the OP below)
To be honest, I don't find the spec draft very clear. However, I found this pomegranate modules post on Caucho's blog that details a bit more how to get it working for a webapp:
Pomegranate is designed to solve the
module versioning and classloader
issues from an enterprise-application
perspective. Although we’re doing a
bit of classloader magic behind the
scenes, the developer perspective is
fairly simple and clean:
remove jars from your .war
drop them in Resin’s project-jars directory
declare jar dependencies in Maven pom files
import them to your web-app with WEB-INF/pom.xml or in your
resin-web.xml
At least, I understand these steps and they answer your question: you have to drop the jars manually in Resin's project-jars directory. That's not what I was expecting but I think that I was misunderstanding what pomegranate is all about. If I'm not wrong, pomegranate is a kind of alternative to OSGI, it is about module bundling and classloading voodoo. It uses Maven's conventions to describe dependencies but it's not about dependencies management.