Order of JAR loading inside EAR's APP-INF/lib - java

Will adding a MANIFEST.MF file with Class-Path attribute to META-INF directory inside EAR influence the order of loading of JARs located in APP-INF/lib under WebLogic 8.1?

I don't believe you can control the APP-INF/lib order via ClassPath attribute of MANIFEST.MF.
I've done this a couple different ways, depending on the client.
Add the patch jar to the system classpath for WLS. If you examine domain/bin/setDomainEnv.sh (or .cmd) there should pre, post, patch classpath environment variables. You could try to add your patch jar to the classpath here. This makes it available for all apps, which might not be what your client wants.
Patch somejar.jar & name it somejar-patched.jar. Replace the jar in APP-INF/lib with the "-patched" version.

I thought the class loader read JARs as they're required by your application.
I have two questions for you:
Why are you still using WebLogic 8.1? It's off support now, and the current version is 10.x. You're two versions behind. Is this a legacy app that hasn't migrated yet? You'll get a big boost by upgrading, because you'll be using JDK 5 or 6 with the -server option. I'd recommend it.
Why should you care about the order of loading? It should be immaterial to your app how the container loads and manages the beans.
UPDATE:
That sounds different, almost as if you were having conflicts with server JARs. There's that prefer-web-inf-classes setting for that situation. Is that what you mean?

I agree with duffymo
You shouldn't have to worry about the order of class loading, if this is due to conflicting classes you can always exclude the conflicting classes from Jars using Maven or a similar tool.
For instance this is a very simple example of adding jersey-spring4 jar but I'm excluding its dependencies so I can use a different version of the spring framework library.
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring4</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-web</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-aop</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>

Related

Using slf4j logger in a simple mvc Spring web project

I am learning spring web mvc project from online resources, i came across this logger slf4j, and i want to use it in my application.
I don't have any idea on how to add this. what i am thinking is i should remove commons-logging.jar from lib folder, and add another jar file to lib folder, but then i don't know which jar file i should add as there are many jar files present in slf4j.zip that i have downloaded from its official site.
I have searched and read few posts/articles about integrating slf4j but they all were related to maven, and i don't have maven, i simply started working with adding spring framework jars to dynamic web project.
Please tell me how and what files i should add in lib folder for logging purpose. or how to configure the slf4j logger.
thanx folks!!
The official source of information on logging in Spring is the Spring Reference.
If you want to use SLF4J, this document suggests using the following Maven dependencies:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.6.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>
In other words, you need four .jar files, and you need to make sure that the Commons Logging library is NOT on your classpath.
If you do not use Maven, you can download these .jars from the Maven Central Repository manually. Enter groupId, artifactId and version on that page, press Search, and download the .jar file (not sources.jar!). Here are direct links to these .jar files: jcl-over-slf4j, slf4j-api, slf4j-log4j12, log4j.
You will also need to create and put on your classpath the configuration file for log4j (log4j.xml or log4j.properties).
I think that by not using Maven you make your life harder, not easier. It's better to spend some time learning it, than spend a lot of time trying to avoid learning it.
I would actually argue against using pure SLF4J to begin with, because its own creators have already created a successor.
Reasons to use it instead of SLF4J are given on http://logback.qos.ch/reasonsToSwitch.html
And the "First baby steps" in the manual are at http://logback.qos.ch/manual/introduction.html

java.lang.NoClassDefFoundError: Could not initialize class org.apache.commons.logging.LogFactory

I am new to Google App Engine. I am getting this error :
java.lang.NoClassDefFoundError: Could not initialize class
org.apache.commons.logging.LogFactory at
org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:282) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) at
org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548) at
org.mortbay.jetty.servlet.Context.startContext(Context.java:136) at ...
I have added slf4j dependencies and excluded commons-logging in spring-context dependency but still getting this error. The app works perfectly fine on my local machine but gives me this error when deployed to the App Engine.
Thanks to this blog , I was able to resolve this issue :
Commons-logging is a dependency of many frameworks, Spring included. On the local server, everything runs fine. In the cloud, Google App Engine infrastructure replaces the commons-logging-1.1.1.jar with a JAR of its own that has a different package structure. In effect, that means you get funny NoClassDefFoundError on org.apache.commons.logging.LogFactory even though you included the JAR as a dependency. The solution is to still include the classes, but to give the JAR another name.
Since I use Maven, I removed the commons-logging dependency from the WAR with the exclusion tag for Spring and MyFaces artifact. Then, I added a dependency on commons-logging:commons-logging-api:1.1:jar with the runtime scope. This jar won’t be replaced.
So you should exclude commons-logging from Spring :
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Then add a dependency on commons-logging-1.1 with runtime scope:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging-api</artifactId>
<version>1.1</version>
<scope>runtime</scope>
</dependency>
You are missing a required jar in your /war/WEB-INF/lib/ folder. It's not enough to have it in your classpath.
If you use Eclipse, you should see a warning in the Problems tab. Right click on it, Quick Fix, select " Copy ...". Or add this jar to the /lib folder manually.

Maven ejb-client generation dependency exclusion

We have a solution where our UI projects are including quite a bunch of business services by using the EJB client dependencies. The problem with this on Maven is that even though the client .jar usually contains about 1-2 classes, they bring with them the full dependency stack of the entire service application. This can get a bit ugly, when the .ear files start growing up to 50-100Mb a pop and there are from time to time pesky errors thanks to irrelevant dependencies sneaking their way into the UI application.
Of course, we can always exclude the dependencies on the client end, but then we have to write the same bunch of lines to each client project using those services and that's a lot of needless repetition. Plus, people come up with the weirdest error messages and use a lot of time tracking them down before remembering to mention that they included some client jar and didn't check what additional dependencies it brought into the equation.
Example:
<dependency>
<groupId>fi.path.to.service</groupId>
<artifactId>customermanagement-common</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>fi.path.to.service</groupId>
<artifactId>customermanagement-service</artifactId>
<classifier>client</classifier>
<exclusions>
<exclusion>
<groupId>fi.path.to.dependency</groupId>
<artifactId>internal-dependency-#1</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.castor</groupId>
<artifactId>castor</artifactId>
</exclusion>
<exclusion>
<groupId>fi.path.to.dependency</groupId>
<artifactId>internal-dependency-#2</artifactId>
</exclusion>
<exclusion>
<artifactId>internal-dependency-#3</artifactId>
<groupId>fi.path.to.dependency</groupId>
</exclusion>
<exclusion>
<artifactId>internal-dependency-#4</artifactId>
<groupId>fi.path.to.dependency</groupId>
</exclusion>
<exclusion>
<artifactId>internal-dependency-#5</artifactId>
<groupId>fi.path.to.dependency</groupId>
</exclusion>
<exclusion>
<artifactId>castor-xml</artifactId>
<groupId>org.codehaus.castor</groupId>
</exclusion>
<exclusion>
<artifactId>castor-codegen</artifactId>
<groupId>org.codehaus.castor</groupId>
</exclusion>
<exclusion>
<artifactId>castor-xml-schema</artifactId>
<groupId>org.codehaus.castor</groupId>
</exclusion>
<exclusion>
<artifactId>internal-dependency-#6</artifactId>
<groupId>fi.path.to.dependency</groupId>
</exclusion>
</exclusions>
<version>2.6</version>
</dependency>
That is just one service client being included, imagine having several of these in several different applications and you get the picture, writing up all the excludes each time is quite annoying and the project POMs start getting fairly longwinded.
I would mark the dependency as provided, but there are a couple dependencies that do crash on runtime, if they don't exist. Say ones that include another service call to yet another app with an external Exception class, which isn't for one reason or another wrapped inside the service project and will cause a ClassNotFoundException on runtime, if not present.
Therefore, I know it's possible to exclude/include classes from an ejb client during its generation through the usage of pom.xml specs on the maven-ejb-plugin, but is there any way to exclude dependencies as well?
Seems that Maven just doesn't support building multiple jars out of one module very well.
Thus the only reasonable way around this that we've found is to create another module (break xxx-service into xxx-service and xxx-service-client) and configure the xxx-service-client module to have only the EJB client/delegate class & minimal dependencies. That way the project can be built with a single execution.
I have the same problem here. I think one solution could be using profiles, since in each profile you could specify the dependencies (see http://blog.sonatype.com/people/2010/01/how-to-create-two-jars-from-one-project-and-why-you-shouldnt/)
In my case, this doesn't work, because I need to generate both JARs (ejb and ejb-client) in a single execution of Maven. :)

Yui compressor StringIndexOutOfBoundsException on jboss

When minimising yui with 2.4.6, I get this problem:
java.lang.StringIndexOutOfBoundsException: String index out of range: 232
at java.lang.String.substring(String.java:1934)
at com.yahoo.platform.yui.compressor.JavaScriptCompressor.printSourceString(JavaScriptCompressor.java:267)
at com.yahoo.platform.yui.compressor.JavaScriptCompressor.parse(JavaScriptCompressor.java:330)
at com.yahoo.platform.yui.compressor.JavaScriptCompressor.<init>(JavaScriptCompressor.java:533)
It works when started through my IDE but when deployed to jboss it doesn't. This place: http://yuilibrary.com/forum/viewtopic.php?p=20086 has some discussion of the same problem.
Apparently the issue is around org/mozilla/javascript/Parser being in the two jars that are pulled in from my maven config:
<dependency>
<groupId>com.yahoo.platform.yui</groupId>
<artifactId>yuicompressor</artifactId>
<version>2.4.6</version>
</dependency>
Is there any way I can solve this using maven exclusions etc. or by upgrading my version of YUI. It seems daft that it just doesn't work and I don't want to have to write a custom classloader.
Please help!
Workaround: For JBoss AS 7.1.1.Final and YUICompressor 2.4.7
Exclude rhino from dependency:
<dependency>
<groupId>com.yahoo.platform.yui</groupId>
<artifactId>yuicompressor</artifactId>
<version>${yuicompressor.version}</version>
<exclusions>
<exclusion>
<groupId>rhino</groupId>
<artifactId>js</artifactId>
</exclusion>
</exclusions>
</dependency>
Why? See https://github.com/greenlaw110/greenscript/pull/29#issuecomment-4017147
Note: if you have a rhino in classpath by some other way, so seems like you'll get this error again.
I solved this problem by repackaging yuicompressor myself to include most of the rhino source. See my reply to Howard M. Lewis Ship.
The repackaged source can be found here : http://viscri.co.uk/labs/tapestry/yuicompressor-rhino-bugfix-5.0.jar. Just add this to your pom:
<dependency>
<groupId>yuicompressorbugfix</groupId>
<artifactId>yuicompressor-rhino-bugfix</artifactId>
<version>5.0</version>
</dependency>
If you don't run your own version of nexus, you'll have to install it on the machine that you want to build on. This is the command you need I think: http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html
You'll also need to exclude the yuicompressor version that tapestry pulls in:
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-yuicompressor</artifactId>
<version>5.3.2</version>
<exclusions>
<exclusion>
<groupId>com.yahoo.platform.yui</groupId>
<artifactId>yuicompressor</artifactId>
</exclusion>
</exclusions>
This should work.
The selected answer's (as of 9/26/2014) jar doesn't exist anymore.
So, I created a fork of yuicompressor where entire rhino package is embedded into the yuicompressor package and namespaced it under yui.
https://github.com/timothykim/yuicompressor
Just clone the repo and run ant to obtain the jar.
Hope this helps anyone else who stumbles unto this problem.
Really, you're having class loader problems in JBoss?
You're going to have to do some kind of exclusion on the competing rhino JAR file. Why is Rhino on the classpath? It may be an optional feature of JBoss you can turn off and avoid the conflict that way.

ClassCastException while parsing XML with WebLogic

I'm getting the following error message:
java.lang.ClassCastException: weblogic.xml.jaxp.RegistryDocumentBuilderFactory cannot be cast to javax.xml.parsers.DocumentBuilderFactory
I've gone through some forums researching this. They said to remove xml-apis.jar or that JAR files were conflicting. But even though I did all the suggested steps, I'm getting the same error.
It's always the xml-apis.jar. Remove them from your classpath (e.g. remove them from WEB-INF/lib of your webapp).
Remove xml-beans-1.xb2 to the lib directory. Modified the POM so it does not include that jar file with the following:
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.0.b2</version>
<scope>provided</scope>
</dependency>
I think Banang is right. Forum http://forum.springsource.org/showthread.php?t=22597 describes solution for similar problem.
Typically such problems happen when there are several versions of the same class in class path while those versions are loaded by different class loaders. One version of DocumentBuilderFactory was loaded by system class loader, other by class loader of your enterprise application. When you are calling the XML parser the parent's version of the class is used. When you are casting yours private version is utilized. These versions are incompatible that causes ClassCastException.
The reason for this issue is you are having multiple jars with same class name in library.
Go to WEB-INF/lib and remove xml-apis-1.0.b2.jar and stax-api-1.0.1.jar or remove them from you pom.xml itself and you would be good to go.
I wanted make a slight addition to the previous answers to this question, in the event that anyone else is in the same situation I was. I had the same problem on our WebLogic 9.2 server due to my use of CXF 2.2.3. In addition to the removal of the xml-apis.jar mentioned previously, I also had to remove a xmlParserAPIs library.
As I am using Maven2 it was just a simple matter of adding another inclusion.
<!-- CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-bundle</artifactId>
<version>${dependency.version.cxf}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>xml-apis</artifactId>
<groupId>xml-apis</groupId>
</exclusion>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
<exclusion>
<artifactId>xmlbeans</artifactId>
<groupId>org.apache.xmlbeans</groupId>
</exclusion>
<exclusion>
<artifactId>xmlParserAPIs</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
Hope this helps someone!
We also has such trouble. The reason of error was in gwt library. Receipe: exlude all gwt client libraries from distr.
As for my case, I managed to solve this issue by removing xml-apis library and also upgrading an XML processing library:
From
org.apache.xmlbeans/xmlbeans/2.4.0
Into
org.apache.xmlbeans/xmlbeans/2.6.0
FYI, I'm using Weblogic 10.3.6.0.

Categories