In posts like https://stackoverflow.com/a/4076706/5467214 or https://stackoverflow.com/a/8743562/5467214 I keep reading about "servletcontainer specific libraries", that shouldn't be included manually in JavaEE projects, if I understood it correctly. Libraries like servlet-api.jar, jsp-api.jar, el-api.jar, j2ee.jar or javaee.jar are mentioned, but normally followed by an "etc.".
Is there a good explanation what "servletcontainer specific" means or perhaps an exhaustive list of which libraries are servletcontainer specific for Catalina, for example? Or for other servletcontainers? For example, jstl-1.1.2.jar gets explicitely loaded via the pom.xml in a project I am working on that runs on a Tomcat7. Is this "servletcontainer specific library"?
Related
My target platform is a WebLogic 12c application server.
I have an ear-project, which on startup requires e.g. org.apache.commons.logging.LogFactory.
I know that this class - an related classes - can be found in <WL_HOME>/modules/com.bea.core.apache.commons.logging.api_1.1.1.jar, but it is not by default available on the classspath.
In such cases - am I supposed to somehow make the jar file in <WL_HOME>/modulesavailable on the classpath - or should I provide whatever jar file I find suitable - either bundled in the application, or placed in <WL_HOME>/user_projects/domains/<mydomain>/lib?
If I am to use the one in the <WL_HOME>/modules folder - how do I configure my domain to make it available?
To me it seems reasonable that the jar files in the modules folder should be considered provided dependencies, but so far I have been unable to find the right way to enable them as such - I have been browsing for an answer for hours:-)
UPDATE:
I know I can simply add them to the CLASSPATH variable in the server startup script - my question is more like - should I? Is there a better way - or should I completely forget about <WL_HOME>/modules?
That's a short-sighted approach.
you need to reboot the server to upgrade libraries
every app on the server must be okay with those libraries in their claspath
Weblogic has the concept of Shared JEE Libraries (example). In short, you add extra lines to MANIFEST.MF and configure the jar differently, then you can reference it in other apps using weblogic-application.xml or whatever.
The point is that you can upgrade the library without restarting the server (provided you gave it a version like 1.1 (there were bugs last time I named it 1.1.1 - it needed to be able to cast it to a floating-point number to seamlessly upgrade)).
If you just want to include some libraries but not share them outside the app, then just specify the correct <prefer-application-packages> or < prefer-web-inf-classes> element, depending on whether you have an EAR or a WAR.
Background:
I have the following problem: I have several WAR files I need to have deployed on same Websphere server. The WAR files use libraries that depend on having a specific version of XMLSec regisered as the XML Signature Provider (with the Java Security class). Currently I bundle this library with each WAR file (since the WAR files also need to work standalone and on Tomcat's without any special shared library configuration etc.). Each WAR files registers the provider with Security.addProvider() in a ServerContextListener. But this causes problems in the multi-WAR setup, because if one WAR file does the registration with Security.addProvider) and another WAR files tries to fetch it using the XMLSignatureFactory class (which is actually a javax.* class contained inside the XMLSec JAR itself, but which ultimately calls back to the global provider list configured with Security.addProvider), then it causes a ClassCastException inside XMLSignatureFactory, because this class does a cast of what it gets from Security into to its own version of the provider classes, which doesn't work. The exact stack trace is as follows:
Caused by: java.lang.ClassCastException:
org.apache.jcp.xml.dsig.internal.dom.DOMXMLSignatureFactory
incompatible with javax.xml.crypto.dsig.XMLSignatureFactory at
javax.xml.crypto.dsig.XMLSignatureFactory.findInstance(XMLSignatureFactory.java:202)
at
javax.xml.crypto.dsig.XMLSignatureFactory.getInstance(XMLSignatureFactory.java:292)
By the way this is not a case of conflict with different versions of XMLSec being in play or conflicts with Websphere's own version. There is only one version albeit it is loaded from different WAR's.
Of course the solution is to have the xmlsec library loaded with a common classloader so that there is only one version of the classes loaded that all WAR files see, which would avoid ClassCastExceptions etc.. But here is the rub: I also need to have each application loaded with the "parent last" policy - or rather, I need the JAR files inside each application to take precedence over Websphere's built-in version of the libraries (for instance Axis2 that I also include in the WAR filesetc.). Furter, I would prefer that I can keep the xmlsec library in each WAR files' WEB-INF/lib folder, so that the WAR files can still work stand-alone (i.e. in other environments which might not have the shared library configured etc.).
So basically I want to have a common class loader loading the XMLSec library, say, somewhere from disk. Let's denote that [SHARED XMLSEC]. Then I want each application classpath to ultimately appear like this:
App1: [SHARED XMLSEC][App1 WEB-inf/lib][Websphere libraries][JDK libraries]
App2: [SHARED XMLSEC][App2 WEB-inf/lib][Websphere libraries][JDK libraries]
etc.
In such a configuration it doesn't matter if App1+App2 themselves contain the XMLSec library since the shared one will take precedence so they will use the common one. At the same time, App1+App2 are still free to override other built-in Websphere libraries (Axis2).
Is it possible to realize this configuration and what options do I need to set? Do you see alternative ways to achieve the same objective?
Since you have a conflict between classes here, I would suggest going for isolated class loaders for each application. On the server side, setting the class loader policy to 'Multiple' should provide isolation between applications.
Once you have this set, configure class loading at the application level to the 'Parent last' configuration for both the applications.
The following Knowledge Center link has the relevant instructions [Steps 2,3 & 4 under the 'Procedure' section] :
http://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/trun_classload.html
[Note: The version of WAS in use is not specified in the question. The Knowledge Center link refers to version 8.5.5.]
I'm currently using hibernate-4.1.4 and jersey-2.22. These have javassist-3.15 and javassist-3.18 respectively.
I included both hibernate and jersey in my project and to my surprise, there were no dependency conflicts between the said javassists.
I was wondering how Java tells hibernate to use 3.15 and how it tell jersey to use 3.18 since both are in the build path. Is one javassist not being used?
Follow up question: Let's say that javassist-3.15 and javassist-3.18 have a conflict with each other. How do I resolve this? Do I disable both javassists and include one externally?
EDIT: My app is a web app that runs on Tomcat 7. We don't use Maven/Gradle. We just configure the dependencies by putting the jars in the build path using Eclipse.
JAVA loads classes through ClassLoaders ... Many applications servers, as Tomcat or Wildfly, implement and use their own class loaders (not the regular ones of the common JDK) ... So you must check the Tomcat documentation to read about its classloading behaviour...
After saying that, is very likely that Tomcat is loading libraries in alphabetical order. I Explain...
Suppose that you use a class named: Dummy, and this class is contained at the libraries: dummy-1.0.jar and dummy-1.1.jar ... when the class Dummy is requested, the Tomcat ClassLoader search for that class definition, looking first at dummy-1.0.jar and later at dummy-1.1.jar ... given that dummy-1.0.jar contains that class, Tomcat stops looking a returns that class version ... If dummy-1.0.jar would not have the target class, the dummy-1.1.jar class version would be returned instead...
(I suggest to try this to validate the container behaivour, it's not so hard to implement)...
And yes, if javassist-3.15 and javassist-3.18 conflicts with each other, you should remove them and pick the javassist JAR more
suitable for both libraries (jersey and hibernate).
As thumb rule, I tend to pick the newest library (the one with greater version), but this scheme not always work...
The problem consist some strategies!
The project this manager dependencies "maven" and "Sonatype Nexus"
There are same artifact, in this case call: core.
That core contains twos class special called SysSpringBoot and SysSpringConfig
This one special class SysSpringConfig, it's need rewrite for last project to use this artifact.
This artifact use for many projects, where each project that use should say which packages scan.
when start this project has one directory it's seems
--webapp
-- pages .xhtml (web pages)
-- WEB_INF
-- web.xml
-- classes
-- SysSpringConfig.class
-- lib
-- my-artifact-core-1.0.0.0.jar
(in my file .jar also contains SysSpringConfig.class (old version))
The classLoader tomcat 8(last version, in old version not has this problem), ready first
../classes/SysSpringConfig.class, then not found all dependencies for use,
at now, find in files *.jar, but in *.jar also find SysSpringConfig.class that time ready another class with the first time!
Same suggest kind implement personality MyClassLoader to solve this problem with Spring classLoader.
sorry with my English
I am confused between the difference of javax.faces-2.1.14.jar from jsf-api-2.2.0-m05.jar and jsf-impl-2.2.0-m05.jar
I am trying to make a jsf project without using maven and while searching for examples I saw different jar dependencies on different tutorials. The tutorial from coreservlets uses javax.faces-2.1.14.jar and the other tutorial I saw from a different site uses 2 jar files jsf-api-2.2.0-m05.jar and jsf-impl-2.2.0-m05.jar
Id like to know the difference of these two set of dependencies.
Thanks in advance guys.
The jsf-api-xxx.jar contains classes that are under packages java package javax.faces. The classes in this jar are implementation of standard API defined by JSF specification. The jsf-impl-xxx.jar contains classes that are under java package com.sun.faces, which as the java package indicates, is Sun's own class for JSF implementation.
The javax.faces-xxx.jar actually merges the previous two jar files together. In the Maven repository, it is under org.glassfish groupId. You will find both javax.faces and com.sun.faces java package inside.
So what should you use for your development? Actually you can use both. But the recommended way is to include jsf-api-xxx.jar only in the compilation classpath. Thus your own application does not depend on any classes under com.sun.faces package to achieve the portability to other JSF implementations. If you are using an application such as GlassFish, the container should already provide the JSF implementation at runtime. You should not package the above JSF jar files with your war or ear file, as server will provide all of them. If you use a container that does not come with a JSF implementation by default such as Tomcat, you need to package javax.faces-xxx.jar or (jsf-api-xxx.jar + jsf-impl-xxx.jar) in the WEB-INF/lib.
They are different versions.
javax.faces-2.1.14.jar is a combined JAR file for 2.1.14
jsf-api-2.2.0-m05.jar and jsf-impl-2.2.0-m05.jar are separate JARs for 2.2.0-m05.
The differences between the versions can be found in the release notes, but 2.2 and 2.1 are non-trivially different.