WAS 6 steps to follow to support MQ 7 features - java

I have problem with EAR module deployed in WAS6.
To support the MQ 7 features in my App. I follow the below steps:
Put Class loader policy as PARENT_LAST.
Placed all MQ 7 related jars in the root of EAR.
EAR contains Web module. When I try to start the application, I got following exception:
javax.servlet.jsp.JspException: Can't get definitions factory from context.
at org.apache.struts.taglib.tiles.InsertTag.processDefinitionName(InsertTag.java:575)
at org.apache.struts.taglib.tiles.InsertTag.createTagHandler(InsertTag.java:474)
at org.apache.struts.taglib.tiles.InsertTag.doStartTag(InsertTag.java:436)
at com.ibm._jsp._home._jspx_meth_tiles_insert_0(_home.java:106)
at com.ibm._jsp._home._jspService(_home.java:81)
The War contains the following jars.
xstream-1.3.1.jar,xercesImpl.jar, xalan.jar,struts.jar, standard.jar,commons-validator.jar, commons-net-1.4.0.jar, commons-fileupload.jar, commons-digester.jar, commons-collections.jar, commons-beanutils.jar,resolver.jar,jstl.jar, jfreechart-1.0.2.jar, jcommon-1.0.5.jar, jaxen-full.jar, jakarta-oro.jar.
EAR contains the following Jars,
com.ibm.mqjms.jar, com.ibm.mq.jmqi.jar, com.ibm.mq.jar, com.ibm.mq.headers.jar, com.ibm.mq.commonservices.jar,log4j.jar,dhbcore.jar.
And I set the class-path attribute in my Manifest file of the WAR with log4j.jar
Please anyone suggest me how Websphere's classloading policy works for where I went wrong.
Karthik

Some time ago I did something similiar. I wanted to use a specific version of a library which was already used within the WebSphere Application Server. That is the reason why you have to put your libraries in the EAR file and set the application server to PARENT_LAST class loader order.
Correct me if I am wrong, but you also have to specify your custom MQ client libraries in Manifest of your WAR file. You only mentioned Log4J. It should look somehting like this:
Class-Path: com.ibm.mqjms.jar com.ibm.mq.jmqi.jar [...] log4j.jar
Anyway, you can always check what libraries are in the Classpath of you application if you log into the Integrated Solutions Console (aka Admin Console) and check the Troubleshooting section. There is a classloader viewer. Just click yourself through the tree and check which library path are mentioned and which you would expect.
Finally, as Dylan already mentioned in his comment: WebSphere Application Server version 6.1 runs out of support September 30, 2012. :)

Related

"Unable to parse class file" ear deployment issue weblogic

I am trying to deploy an ear file in weblogic 12 but it gives the following error while trying to deploy the ear:
<Error> <J2EE> <BEA-160248> <Unable to parse class file: zip:D:/Weblogic/user_projects/domains/..../tmp/.appmergegen_1/lib/log4j-api-2.9.0.jar!/META-INF/versions/9/org/apache/logging/log4j/util/ProcessIdUtil.class.
<Error> <J2EE> <BEA-160248> <Unable to parse class file: zip:D:/Weblogic/user_projects/domains/...../tmp/.appmergegen_1/lib/log4j-api-2.9.0.jar!/META-INF/versions/9/org/apache/logging/log4j/util/StackLocator.class.
I have built the project using java 1.8.0_121.Also have placed the log4j-api-2.9.0 in lib of the server.
The log4j-api-2.9.0.jar is a multiple release jar. This feature was added from JDK9. The java 8 which is present in your environment does not support it, therefore these files can not be parsed and WebLogic reports BEA-160248.
The https://docs.oracle.com/javase/9/docs/specs/jar/jar.html#Backward_Compatibility states that
The new class loading scheme is totally backward compatible with applications developed on top of the current extension mechanism. When the class loader loads the first jar file and an INDEX.LIST file is found in the META-INF directory, it would construct the index hash table and use the new loading scheme for the extension. Otherwise, the class loader will simply use the original linear search algorithm.
and according to the Doc ID 2629550.1
This message is harmless and can be ignored.
You should built the project using java 1.7. Weblogic support Java EE 7 for now.

wildfly migration from AS 7 to WF10

I am new to WildFly Server. I am upgrading server from AS7 to Wildfly10. How to add JARS in WILDFLY10. In Error Log: i am getting missing Dependencies(Is this because of not reading JARS?).
you need to add jars like it is given on their wiki.
Sometimes you need to add a module (if it is a jar that is not
shipped with Wildfly and define it in
jboss-deployment-structure.xml).
Sometimes, in case it is already shipped (you may have to search inside the modules directory) and add it in jboss-deployment-structure.xml
Again it depends what is it saying. which dependency etc?
https://docs.jboss.org/author/display/WFLY10/Class+Loading+in+WildFly
Actually we need to delete the servlet-mappings in web.xml and use annotations to direct to java classes
1. #webservlet for Servlet classes.
2. #path for resources.
Also we need to delete some unneccessary jars, which wildfly have inbuilt.

WSDL parsing exception creating Webservice client with CXF JaxWSClientFactoryBean

I've written some code to create and run webservice client using CXF. I used JaxWsClientFactoryBean (not sure it's the best solution) to create client from .wsdl file.
The goal here was to do this programmatically avoiding Spring etc. Just pure code with Java and CXF.
JaxWsClientFactoryBean cfb = new JaxWsClientFactoryBean();
cfb.setAddress(getServiceProperty(intClass, PROPERTY_KEY_URL_SUFFIX));
cfb.setServiceClass(intClass);
cfb.setOutInterceptors(getOutInterceptors(intClass));
cfb.setServiceName(SERVICE_NAME);
cfb.setWsdlURL("classpath:wsdl/" + intClass.getSimpleName() + ".wsdl");
cfb.setEndpointName(ENDPOINT_NAME);
Client client = cfb.create();
ClientProxy cp = new ClientProxy(client);
I intService = (I)
Proxy.newProxyInstance(intClass.getClassLoader(), new Class[] { intClass }, cp);
I'm really not sure if this is done correctly, but it works when I run this code locally and when I deploy it on Tomcat.
Unfortunatelly I need to run this code on Weblogic and this results in strange exception:
Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was
made to insert a node where it is not permitted.
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:235)
at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:186)
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:92)
... 26 more
Caused by: org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at com.sun.org.apache.xerces.internal.dom.ParentNode.internalInsertBefore(ParentNode.java:356)
at com.sun.org.apache.xerces.internal.dom.ParentNode.insertBefore(ParentNode.java:284)
at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.insertBefore(CoreDocumentImpl.java:399)
at com.sun.org.apache.xerces.internal.dom.NodeImpl.appendChild(NodeImpl.java:235)
at org.apache.cxf.staxutils.StaxUtils.readDocElements(StaxUtils.java:1019)
at org.apache.cxf.staxutils.StaxUtils.readDocElements(StaxUtils.java:939)
at org.apache.cxf.staxutils.StaxUtils.read(StaxUtils.java:866)
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:226)
... 28 more
This happens during application deployment. It looks like there is something wrong with .wsdl file, but wait... It was working on Tomcat!
I think that there could be some difference in com.sun.org.apache.xerces.* classes implementation within Weblogic with its JRockit VM and standard JVM, but I have no idea how to solve it.
I spent many hours trying differend ways of client creation. Most of them worked locally and in Tomcat, but none on WebLogic.
Any hints what to try next? I'm kinda tired of this topic :D
I agree with your suspicion that the problem is related to the used version of Xerces. The stacktrace shows that the Sun implementation of Xerces which is derivative of the Apache Xerces is used in your case.
Please check the Apache CFX Application Server Configuration Guide instructions related to WebLogic.
WebLogic ClassLoading
In WebLogic Server, any .jar file present in the system classpath is loaded by the WebLogic Server system classloader. All applications running within a server instance are loaded in application classloaders which are children of the system classloader. In this implementation of the system classloader, applications cannot use different versions of third-party jars which are already present in the system classloader. Every child classloader asks the parent (the system classloader) for a particular class and cannot load classes which are seen by the parent.
For example, if a class called com.foo.Baz exists in both $CLASSPATH as well as the application EAR, then the class from the $CLASSPATH is loaded and not the one from the EAR. Since weblogic.jar is in the $CLASSPATH, applications can not override any WebLogic Server classes.
In order to use an alternate version of Xerces you have to create a FilteringClassLoader.
Usage of FilteringClassLoader
The FilteringClassLoader provides a mechanism for you to configure deployment descriptors to explicitly specify that certain packages should always be loaded from the application, rather than being loaded by the system classloader. This allows you to use alternate versions of applications such as Xerces and Ant.
The FilteringClassLoader sits between the application classloader and the system. It is a child of the system classloader and the parent of the application classloader. The FilteringClassLoader intercepts the loadClass(String className) method and compares the className with a list of packages specified in weblogic-application.xml file.
In conclusion, check the steps included in the Apache CFX Application Server Configuration Guide and take care to explicitly specify that the org.apache.xerces.* package is loaded from the application, rather than being loaded from the system classloader.
For example the weblogic-application.xml file in the META-INF should look like:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90">
<application-param>
<param-name>webapp.encoding.default</param-name>
<param-value>UTF-8</param-value>
</application-param>
<prefer-application-packages>
<package-name>javax.jws.*</package-name>
<package-name>org.apache.xerces.*</package-name>
</prefer-application-packages>
</weblogic-application>
I hope this helps.

CXF on WebSphere 6.1 Class Loading Problem

I have a project with the following configuration:
WebSphere Application Server 6.1.0.19
wsdl4j-1.6.2.jar at the $WAS_ROOT/java/jre/lib/ext directory, (to overwrite wsdl4j-1.6.1 included in WAS 6.1).
cxf-2.4.0.jar (and others dependencies) at the $WAS_ROOT/lib/ext directory.
An EAR 'X' with a Web Module 'Y'.
The Web Module 'Y' has a JAR Module 'Z' (at the WEB-INF/lib directory).
'Z' has a set of classes that implement a SOAP Web Service generated using CXF's wsdl2java.
'Y' has a business class (at the WEB-INF/classes directory) that calls the SOAP Web Service Client at 'Z'.
This configuration works well at my development enviroment (Rational Application Developer with a WebSphere AS 6.1 runtime). But at the QA enviroment, I had the following exception, (please pay attention at bolds in the stack trace):
org.apache.cxf.bus.extension.ExtensionException
at org.apache.cxf.bus.extension.Extension.loadInterface(Extension.java:134)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.loadAndRegister(ExtensionManagerImpl.java:160)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.getBeansOfType(ExtensionManagerImpl.java:256)
at org.apache.cxf.bus.CXFBusImpl.getExtension(CXFBusImpl.java:99)
at org.apache.cxf.endpoint.ClientImpl.notifyLifecycleManager(ClientImpl.java:186)
at org.apache.cxf.endpoint.ClientImpl.(ClientImpl.java:117)
at org.apache.cxf.frontend.ClientFactoryBean.createClient(ClientFactoryBean.java:104)
at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:92)
at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:152)
at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:142)
at org.apache.cxf.jaxws.ServiceImpl.createPort(ServiceImpl.java:464)
at org.apache.cxf.jaxws.ServiceImpl.getPort(ServiceImpl.java:331)
at org.apache.cxf.jaxws.ServiceImpl.getPort(ServiceImpl.java:318)
at javax.xml.ws.Service.getPort(Service.java:46)
at web.service.client.implementation.at.z.module.method(Unknown Source)
at business.class.at.y.web.module.method(AvisoCobroDAO.java:86)
... 32 more
Caused by: java.lang.ClassNotFoundException: org.apache.cxf.endpoint.ClientLifeCycleManager
at com.ibm.ws.classloader.CompoundClassLoader.findClass(CompoundClassLoader.java:472)
at com.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:373)
at java.lang.ClassLoader.loadClass(ClassLoader.java:561)
at org.apache.cxf.bus.extension.Extension.loadInterface(Extension.java:132)
... 51 more
Seems like the CompoundClassLoader (which works at application level) is trying to load a CXF's class which exists at the server runtime level.
I hope somebody help me with this issue. I'll be very very grateful.
Placing Jars in the WAS_HOME/lib/ext should be your last resort.
Always try the PARENT_LAST classloader mode and have your classes/jars picked up first.
This would avoid a number of problems for you.
The App Server start up would use this directory extensively and if there are clashes it might not even start up.
THe best way to troubleshoot is to turn on classloading and look at the native_stdout/stderr file and see who is loading the class(es) that is in question.
Bkail,
Did you mean to say things differently? This path is high up the class loader chain so it would be checked earlier (with the default PARENT_FIRST) class loading policy.
This would be in the second rung (after the BOOT CLassloader of the JDK) and it's extensions.
HTH
Manglu

Controlling the classpath in a servlet

My servlet application includes a number of library .jars, some of which contain embedded log4j.xml or log4j.properties files. I'd like to ensure that log4j finds my log4j.xml first! I've tried searching for some specification of the priorities of the various classpath elements in a servlet (e.g. does WEB-INF/classes always precede WEB-INF/lib?), or some way to configure or tweak the servlet's classloader so that a given resource directory appears early in the classpath. So far, I've drawn a blank. Any suggestions on ensuring that a servlet .war file loads the correct log4j.xml via the classloader?
Tomcat 8.5
Ditto Tomcat 8.0.
See documentation: Class Loader HOW-TO.
Tomcat 8.0
The answer is simple, taken from the Tomcat documentation page, Class Loader HOW-TO. In particular notice the use of the /WEB-INF/ directory/folder.
Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order:
Bootstrap classes of your JVM
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
System class loader classes (described above)
Common class loader classes (described above)
If the web application class loader is configured with <Loader delegate="true"/> then the order becomes:
Bootstrap classes of your JVM
System class loader classes (described above)
Common class loader classes (described above)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
Tomcat 6
Excerpted from Tomcat 6 page, Class Loader HOW-TO.
Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order:
Bootstrap classes of your JVM
System class loader classes (described above)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
$CATALINA_HOME/lib
$CATALINA_HOME/lib/*.jar
As far as I understand the resource selection from the classpath is non-deterministic (from the point of view of the app developer). Even if the same file is loaded consistently the behaviour could change:
1. When you upgrade the version of your current container.
2. If you switch containers.
The simplest solution will be to remove embedded log4j config files from library jars. It is almost never a good idea to embed log4j config's as it leads to the problem you are seeing here...
Are they third party jars or jars you developed?
We the Spring Log4jConfigListener in our web.xml file.
You can specify as a context parameter the location of the log4j config file, i.e. you could set it as /WEB-INF/log4j.xml
Would this be an option for you? If you're not using Spring I know that you can set the Log4j location programatically which might also work.
In my experience, WEB-INF/classes typically takes precedence over jars in WEB-INF/lib, however, that also depends on the servlet container you use (I could never figure out the behavior of JRun, for instance). It would help immensely if you could tell me which container you're using.
Also, are you certain that the offending log4j configuration is in a jar in WEB-INF/lib? Typically, when I've run into classpath problems in a servlet container situation, it's because of libraries that reside outside of the web app.
The servlet specs recommend that web app classloaders load their own classes before delegating to the container's classloader (SRV.9.7.2), but since this is counter to the Java spec, not all vendors do this by default (in fact Tomcat is the only container I've used that does this by default). With that said, it's always possible to configure your container's web app classloading behavior. If you tell me which container you're using, I may be able to help you (specifically, I have done this successfully before on WebLogic, WebSphere, Glassfish and JRun)).
If you're unable to control the classpath, since Tomcat is setting it for you, are you at least able to set a system property for log4j.configuration? I believe that location pointed to by that property can be set outside of the classpath.
If not, another approach, although an ugly one, would be to explicitly run one of the configurators yourself in your application code.
You need to have log4j.properties in your CLASSPATH. The best place is under WEB-INF/classes.
You also have to make sure that you use your version of log4j.jar. So, put it in WEB-INF/lib, just to make sure you are not using one from tomcat folders, since it may cause strange classloading issues.

Categories