Websphere hates multi-release jars - java

This problem is duplicate to similar problems in Jetty, but I could not find literature about Websphere
https://github.com/eclipse/jetty.project/issues/1797
Error scanning entry "module-info.class" when starting Jetty server
I have a Websphere 8.5.5.7 running over Java 7. Only today we discovered that upgrading log4j from 2.7 to 2.10 breaks the startup. Following is one of the many stack traces:
[01/03/18 10.12.14:154 CET] 000003d9 ecs W com.ibm.ws.ecs.internal.scan.context.impl.ScannerContextImpl scanJAR unable to open input stream for resource module-info.class in archive WEB-INF/lib/log4j-api-2.10.0.jar
java.lang.IllegalArgumentException
at org.objectweb.asm.ClassReader.<init>(Unknown Source)
at org.objectweb.asm.ClassReader.<init>(Unknown Source)
at org.objectweb.asm.ClassReader.<init>(Unknown Source)
at com.ibm.ws.ecs.internal.scan.impl.ClassScanner.scanInputStream(ClassScanner.java:147)
at com.ibm.ws.ecs.internal.scan.impl.ClassScanner.scanInputStream(ClassScanner.java:124)
at com.ibm.ws.ecs.internal.scan.impl.ClassScanner.scanInputStream(ClassScanner.java:120)
at com.ibm.ws.ecs.internal.scan.context.impl.ScannerContextImpl.scanJAR(ScannerContextImpl.java:275)
at com.ibm.ws.ecs.internal.scan.context.impl.ScannerContextImpl.scanJARs(ScannerContextImpl.java:315)
at com.ibm.ws.ecs.internal.scan.context.impl.WARScannerContext.scanInternal(WARScannerContext.java:76)
at com.ibm.ws.ecs.internal.scan.context.impl.ScannerContextImpl.scan(ScannerContextImpl.java:87)
at com.ibm.ws.ecs.internal.scan.context.impl.ScannerContextImpl.getScannedClasses(ScannerContextImpl.java:70)
at com.ibm.ws.webcontainer.webapp.WebAppImpl.scanForHandlesTypesClasses(WebAppImpl.java:760)
at com.ibm.ws.webcontainer.webapp.WebAppImpl.initializeServletContainerInitializers(WebAppImpl.java:601)
at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:406)
Basically the log4j developers had the great (but unlucky) idea of using multi-release jars for Java 9 to accommodate older Java runtimes.
Our installation cannot be upgraded. Those are the versions and we must keep them. I have tried to google around for multirelease jars with websphere but there seems to be no literature.
I would like to ask if there is any configuration workaround to disable massive scanning of jars at least in selected packages in the targeted version of websphere.

There is an existing APAR for this. See APAR PI89708.
If that does not fix the problem, you should open a PMR so that IBM can fix it.
WebSphere Application Server traditional does provide a mechanism to reduce the amount of scanning of JAR files. However, that might (or might not) be a workaround for this problem, since not all components of WAS respect the annotation scanning filters. Though it is still worth looking at since reducing the scanning activity can improve deployment time.
Take a look at the amm.filter.properties file under WAS_HOME/properties.
Add names of JAR files that you do not want scanned to the "Ignore-Scanning-Archives" property. There are more options for specifying JARs to be filtered from scanning. You can find more information here.
Also note that WAS 8.5.5 was released before multi-release JARs existed. So the support, or more accurately tolerance, has to be added in service. I say tolerance, because Java 9 is not supported at this time. For now, WAS simply has to tolerate the existence of classes under the META-INF directory.
If you absolutely cannot upgrade or patch the application server, then the simplest option is to modify the log4J JAR file, removing the classes under the META-INF directory. I know that is not desirable either, since you shouldn't have to modify a third-party JAR, but I have doubts that the filter will work in this case. So, without patching the application server, it might be the only option.
As you pointed out in your comment, in this particular case, since LOG4J does not have JAVA EE annotations, the warning message can be ignored. The application should start and function normally. If however, the JAR contained Java EE annotations, then those annotations would not have been processed. If that were the case, I would expect the application to start, but it might not function correctly.
>
Additional APARs were added since the original answer to this question. Here is the complete list of APARs:
PI89708, PI93744, PI96826, PH02014, PH03710.

Related

Tomcat 6 Classloader : Which Jar is it reading?

I have a huge web application that I have to support. Recently when I downloaded the latest source from SVN and try to run it locally on Tomcat 6, I get the following error from one of the background batch jobs that the application runs...
2014-12-23 18:08:27 [taskScheduler-4] TaskUtils$LoggingErrorHandler [ERROR] Unexpected error occurred in scheduled task.
java.lang.NoSuchMethodError: javax.xml.stream.XMLEventFactory.newFactory()Ljavax/xml/stream/XMLEventFactory;
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor$HeadersProcessor.<clinit>(ReadHeadersInterceptor.java:275)
So I believe the problem is the Apache class ReadHeadersInterceptor which my application's code calls is trying to call the newFactory() method from XMLEventFactory but is not finding that method, probably because it is reading an older version of XMLEventFactory.
I think this is happening because there are some JARs in my lib folder I need to remove or add. Problem is I don't know which one. I see there are several JARs which have XMLEventFactory including..
woodstox-core-asl-4.2.0
stax2-api-3.1.1
And it is also part of Java 6 in the rt.jar.
So out of all these Jars which one is it trying to read and not find that method it needs?
Thanks.
This is a problem with specific version of JDK/JRE 1.6 (I mean the update). It may looks weird but the JDK API change for specific major version.
Please take a loot at the following link. You can see there that with change from version 1.6.0.17 to 1.6.0.18 the new methods have been added on the XMLEventFactory class.
Probably you have the JRE version less thank 1.6.0.18. I've had the same problem with Apache CXF and dynamic proxies. The update of JRE 1.6.0.14 to 1.6.0.19 fixed the issue.
I hope it helps.

Reload jars from lib directory when using Trinidad (JRuby and RoR 3)

Has anyone achieved hot-deployment of Java libraries (or even compiled Java classes) when using Trinidad?
My Rails application runs on Trinidad and depends on a Java backend that is packed as many jars under my-rails/lib/java. When one of these jars changes, Trinidad server doesn't reload it. touch tmp/restart.txt only reloads the app context.
Please note that my question is not related to config.autoload_paths, because as far as I know this option is used only to reload Ruby files.
UPDATED
I failed to achieve hot-deployment of my java dependencies and gave up. The only help for me were unit tests which I was launching locally every time to check my code.
I think if the .jar does not get reloaded than it's probably a Trinidad bug (since during context restarts jars should be re-added - assuming Tomcat does this by default - I'm not sure) ... would be great to know details (in Trinidad's tracker) e.g. if the jar is named the same, how does the configuration look like (if any).
The other option would be to try out a rolling restart since than a brand new context is created - thus it should pick up anything that the context depends on from the file-system.
Please note that auto-reloading on file changes such as changing a .jar file even though might work with Tomcat is on purpose disabled in Trinidad - you need to "explicitly" (touch ...) to request a restart.

Keeping Project JAR Files Up To Date

When using multiple APIs in a single project, the JAR files required for each API are added to the project in addition to other needed libraries such as Apache Commons, logging, etc. that are already used by the project. This sometimes results in a large number of jar files.
When a certain API or library is no longer used, it would be nice to remove the JAR files associated with it. However, there is a risk that another API or library requires it. This would NOT always become apparent during the building of the project. Sometimes, JARs that are missing throw errors only at runtime.
I have the following questions:
What is the best way to deal with this issue? In other words, be able to remove JARs without running the risk of runtime errors later?
I have been told that Maven solves this problem. Does it? Would it work if the external APIs used are not Maven-based? Would I be able to remove JARs without worrying about runtime errors? Do I need to rewrite my entire project to be based on Maven?
How do non-JVM platforms deal with the issue of shared libraries and removing them? Is Java lacking in this area or it is a common issue for all platforms?
Yes I agree Maven could help you in this case. Basically in Maven compile & runtime dependencies for each artifact (jar/war/ear/etc) are declared on pom.xml file. If multiple dependencies depends on same artifacts the latest version is used -- for example:
A-1.0.jar -- depends on --> C-2.0.jar
B-1.0.jar -- depends on --> C-2.1.jar
Only C-2.1.jar is is included in your project.
If a required dependency couldn't be found / taken out, Maven build will automatically fail. So to avoid runtime dependency missing, you can declare a dependency in runtime scope to a particular artifact -- and when you no longer need it you just take it out
There is an old trick I used to use on UNIX many years ago, it might still work for you. First use UNIX "touch" to set the date/time on all your files to the current date/time. Then wait for at least one minute. Then run your application. Then run UNIX "ls -lut" to list all your files, but this time the ones that were not used will have the date/time set in the first step whereas those that were used will have a more recent date/time due to the "u" switch reporting the last used date/time.

hbase + gwt multi module app, issues with slf4j and resources

I've found a lot of articles/questions dealing with this problem, but there was no answer that worked for me yet.
I'm using GWT 2.5 with the eclipse plugin. eclipse version is Juno with Java7.
Everytime I start the app it first tells me that log4j was not configured properly (no appenders...) and also my HBaseAdmin can't connect to HBase (which is running).
All of the answers tell me that I have to put the resources into WEB-INF/classes directory. In order to do that automatically I added the files into the root src directory. But still nothing.
Maybe it's worth mentioning that I don't use maven (b/c all the other projects are no maven projects either, and there is no time to introduce maven at the moment)
Thank you for any hints what might be missing.
EDIT:
somehow I don't get any warning anymore, but I didn't do anything except restarting over and over. Thus this should be working now. But, Zookeeper now throws
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
I divided the gwt app up to the UI part, the executing implementation of the service is a seperate project, also the model is seperate. I first just added the required libraries to the projects that really need them. Know I also added them to the main GWT app, but that didn't help either. Any ideas?
LoggerFactory classes you are using is from slfj-api-1.6.1.jar . Try adding that jar into your WEB-INF/lib and classpath. Also we usually use it conjunction with slf4j-log4j12-1.6.1.jar .
Note: We are using version 1.6.1 as indicated by GWT sample examples available with gwt downloads.

Java xerces DocumentBuilderFactoryimpl not found - What to do?

I get this message :
javax.xml.parsers.FactoryConfigurationError:
Provider
org.apache.xerces.jaxp.DocumentBuilderFactoryImp
but i can't seem to solve the problem. I have googled, but can't find any good solutions.
Does anyone have an idea of what could be wrong?
And maybe how to solve it :)
The org.apache.xerces is from the Apache Xerces package, and something in your application has a dependency on it. Try downloading it (latest version is 2.9.0) and adding it to your application's classpath.
DocumentBuilderFactory has a multi-step process for finding the actual parser implementation, as described in the linked JavaDoc. Your error message is almost certainly coming from there.
I suspect that your JBoss startup script is setting the javax.xml.parsers.DocumentBuilderFactory system property incorrectly (I've seen this happen before, used to avoid a bug in the released library). I would start by grepping the JBoss configuration directory for that property, followed by explicitly setting the jaxp.debug property (also described in the link). Assuming that your startup script is indeed explicitly setting the property, find out who made that change and ask him/her if you can delete it (or to provide you with the correct JARs if not).
As you've tagged your question JBoss, I'll assume your code is running in the JBoss container.
JBoss may have already loaded a version of Xerces for it's own use and you're trying to load a different version in your code (either explicitly or through some dependency) and the configuration for your version is not compatible with the version that's already loaded.
This JIRA Ticket on JBoss.org suggests deleting the xercesimpl.jar in jasperserver/WEB-INF/lib folder to allow your version to be used.

Categories

Resources