Load external library in java web application - java

My scenario is the following:
I have a WebApp.war that is deployed to a servlet container. This WebApp.war contains in WEB-INF/lib the following libraries:
lib_a.jar
lib_b.jar
I have one other library, say lib_vendor.jar, that I cannot deploy within WebApp/WEB-INF/lib because of licensing issues so I let our customers to copy this library in tomcat/lib after application installation. But since lib_vendor.jar requires lib_a.jar and lib_b.jar that are loaded in the web application class loader, I cannot use lib_vendor.jar.
How can I load an external library (not in WEB-INF/lib) in the same classloader of a web application?

Since you are using Tomcat, you could leverage the VirtualWebappLoader.
Add a META-INF/context.xml whith
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/somepath/myapp">
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="/somedir/*.jar"/>
</Context>
Remember also that the virtualClasspath attribute must be a absolute path, as correctly stated in the comment below.

Related

weblogic classloading problem with custom class loaders

I have been trying to convert a legacy web application to maven.
I have created a war file (contains all dependencies in WEB-INF/lib) and trying to deploy it as war file to weblogic 12c.
I have an issue with Class loading that all classes (including classes in jars) loaded by weblogic.utils.classloaders.ChangeAwareClassLoader
In somewhere in the libraries (these are custom local libraries) there is a code part that trying to cast classloader of a class to our custom class loader. So I'am getting an error like weblogic.utils.classloaders.ChangeAwareClassLoader can not be cast to xxx.myCustomClassLoader
I have a weblogic.xml file refers that use WEB-INF libraries for application.
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
<context-root></context-root>
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
</weblogic-web-app>
Can i make weblogic to use my customclassloader while loading classes?

Java configure context root of web application

I have a Java web application using Wicket 6, Spring 3.2 and WildFly 8.2.0. Right now i'm setting the context root of my web application in the jboss-web.xml file like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 5.0//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_5_0.dtd">
<jboss-web>
<context-root>/myCustomContextRoot</context-root>
</jboss-web>
The jboss-web.xml file is compiled into the war. Now some clients want to change this context root to an empty context root. So i hace to recompile a version of my app per different context root. Is there a way to set the context root of my application from outside .war, programatically from a .properties file, or any other way for example in standalone.xml of WildFly 8.2.0?
Set the runtime name when deploying your web application. Suppose your WAR is called myapp-1.0.0-SNAPSHOT.war. Using a runtime name of foo.war, the context root will be /foo.
Using a runtime name of ROOT.war, the context root will be /.
The runtime name can be set when deploying via the Web Console or via the CLI.
Thanks for your Answer Harald Wellmann. It answers the question and pointed me into the right direction!
Some things I had to find out on my own and which may help others:
the exact syntax in jboss-cli to specify a runtime-name is:
deploy path_to_war_file --runtime-name=wantedName.war
This leads to a context-root of /wantedName/ for the webapp.
The runtime-name does not have any effect on the context-root, if the war file contains a jboss-web.xml in WEB-INF which in turn contains a context-root tag.
That is, if you want to control the context-root of your web-app in WildFly at deployment time, you must not specify any context-root in jboss-web.xml.
It is ok to have a jboss-web.xml without a context-root tag if you want to take advantage of the runtime-name to control the context-root.
I tested this on WildFly 9.0.1 and 9.0.2:
Hope this helps!

Adding jars to an application in application.xml?

I have a java application which needs to be deployed in the weblogic server. I am currently making the ear file for that application. My ear file has an ejb jar inside. I want to add log4j2 jars to this application. So my folder structure is
> Project-Name-
> --Ear-Content
> --APP-INF
> --lib -> log4j2 jars
> --classes - > log4j2.xml
> --META-INF->application.xml, MANIFEST.MF, weblogic-application.xml
> --Project-Name.jar
Currently I have put the jars in APP-INF folder/lib and in META-INF/application.xml I have put the jars in modules. Here is my application.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN' 'http://java.sun.com/dtd/application_1_3.dtd'>
<application>
<display-name>ProjectName</display-name>
<description>ProjectName</description>
<module>
<ejb>ProjectName.jar</ejb>
</module>
<module>
<java>lib/log4j-api-2.1.jar</java>
</module>
<module>
<java>lib/log4j-core-2.1.jar</java>
</module>
</application>
But it is not taking the log4j jars. Any solutions ??
If you are only packaging up one application, I would highly recommend using a war file instead of an ear since it is simpler. Otherwise you may need to package your current Project-Name.jar into a war file and then package that into the ear.
See a tutorial like the one here
That said - you should not need to explicitly reference the log4j libraries in your application.xml file with module tags. From the Oracle docs:
The classes and libraries stored under APP-INF/classes and APP-INF/lib
are available to all modules in the Enterprise Application. The
application classloader always attempts to resolve class requests by
first looking in APP-INF/classes, then APP-INF/lib.
Last but not least, if it seems like Weblogic is not using the classes you want it to and is instead using the defaults, in your case log4j 1.2 vs log4j 2, you will need to set the following in your application.xml to tell Weblogic which one to use:
<prefer-application-packages>
<package-name>org.apache.log4j.*</package-name>
</prefer-application-packages>

How to force jboss to load classes from jars in webapp's lib

I am trying to deploy my web application on jboss-6.0.0Final, which is currently deployed on apache tomcat.
I have two jars one that contains same package which is org.apache.axis. I am putting one jar in <Jboss-home>/server/default/lib & another jar in <my-app-war>WEB-INF/lib.
It is required to put both jars in the class path. No way to remove one of the jar. So I need to keep both jars. & It is giving me following error
java.lang.ClassCastException: org.apache.axis.attachments.AttachmentsImpl cannot be cast to org.apache.axis.attachments.Attachments
at org.apache.axis.AxisFault.makeFault(AxisFault.java:101)
at org.apache.axis.client.Call.invoke(Call.java:1828)
I think it is due to conflict of same classes in two different jars.
Now, I want to know the way by which I can force jboss to load classes of this particular package from axis.jar exist in /WEB-INF/lib.
How can I do that?
This helped me:
http://www.mastertheboss.com/jboss-configuration/solving-jboss-5-classloading-issues
Explode your war,
In your Exploded WAR web-inf directory add this xml file: jboss-classloading.xml
with content:
(domain is your war name)
<classloading xmlns="urn:jboss:classloading:1.0"
name="mywar.war"
domain="mywar_domain" <!-- (domain is your war name) -->
parent-domain="Ignored"
export-all="NON_EMPTY"
import-all="true">
</classloading>
I'll share quite simple and straight forward process which I had followed when I came across same situation.
1> Create a jboss-web.xml file.
<class-loading java2classloadingcompliance="false">
<loader-repository>
com.rts:archive=DTH_PROD.war
<loader-repository-config>
java2ParentDelegation=false
</loader-repository-config>
</loader-repository>
</class-loading>
</jboss-web>
Points:,
Begin the xml with tag which is not visible in the code I'm posting
Check 3rd line of above code,
com.rts - This is your package name.
DTH_PROD.war - Name of bundle you wish to keep
2> Now place this xml file into WEB-INF directory of your project and voilla!!
Further more you may wish to refer this article for detailed info. Also comment below if you face any difficulty solving this.

How do I tell JBoss 4.2.3.GA to load jars in my war file lib directory first?

I deploy a web archive and that war references a jar file that conflicts with those in $JBOSS_HOME/server/default/lib. I can go and remove the offending jars manually, but I'd prefer a solution that allows me to specify my jars over JBoss's. I would even like to just tell JBoss to exclude specific jars, if that's even possible.
The closest I've come was to add something in jboss-web.xml in my war's META-INF directory, but I'm clearly not doing something right there. This is what I have so far:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<class-loading java2ClassLoadingCompliance="false">
<loader-repository>com.amce:archive=WHATEVER</loader-repository>
<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
</class-loading>
</jboss-web>
This fails spectacularly with errors like this:
ERROR [13]] Exception sending context initialized event to listener instance of class org.jboss.web.jsf.integration.config.JBossJSFConfigureListener
java.lang.ClassCastException: org.apache.xerces.jaxp.SAXParserFactoryImpl cannot be cast to javax.xml.parsers.SAXParserFactory
at javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:128)
at com.sun.faces.config.ConfigureListener$WebXmlProcessor.getConfiguredFactory(ConfigureListener.java:697)
at com.sun.faces.config.ConfigureListener$WebXmlProcessor.scanForFacesServlet(ConfigureListener.java:669)
...
That error leads me to believe I'm just specifying the jboss-web syntax incorrectly (is there an xml schema somewhere)? However I'm not even sure I'm heading down the right path. Is there anyway I can do this without modifying JBoss in anyway?
java2ParentDelegation=false. Read here for more details.
Java EE class loading details: Java EE class loading standard
jboss-web.xml belongs in your app's WEB-INF directory, not META-INF. your xml file looks right, I compared it to WAR i have deploye to Jboss-4.x

Categories

Resources