I'd like to use PrimeFaces in my Java EE 6 (Jboss AS 7.1.1Final) application with this structure:
EAR
|- lib/
| |- primefaces-4.0.jar
|
|- ejb-module.jar
|- webbapp1.war
|- webapp2.war
However, when deploying to JBoss AS 7, I'm getting several exceptions such as:
java.lang.LinkageError: Failed to link org/primefaces/context/PrimeFacesContextFactory
(Please see the full stack trace here on PasteBin)
For EAR's pom.xml, I'm using this Maven dependency for PrimeFaces:
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>4.0</version>
<type>jar</type>
</dependency>
However, when I put the dependency into pom.xml of one WAR, it works, but I want to share the primefaces library between multiple WARs.
I've googled a lot but have not found any solution. Thank you for any advice.
You cannot. Webapp libraries do not belong in EAR/lib, but in WAR/WEB-INF/lib. The EAR/lib is never intented as a "shared library" for all WAR projects of the EAR. It's that only for all EJB projects (the business services) of the EAR.
The LinkageError on a PrimeFaces-specific class which you're facing is caused because the (default) webapp-specific libraries like JSF API/impl are not available to the classloader as used by EAR/lib. This causes all libraries in the EAR/lib which have a (virtual) dependency in WAR/WEB-INF/lib to fail with class loading errors like LinkageError.
If you really really need a "shared library" for all WAR projects, then your best bet is putting the library in Java EE container itself (like as by default already done for JSF API/impl libraries). In case of JBoss, that's called a "module". I however wouldn't recommend that as that makes the webapp unportable across containers without specifically configuring the container by the serveradmin. Just give each webapp its own set of webapp libraries.
Related
I need to bundle JSF implementation in my WAR file due to known bug in the original mojarra implementation.
I am not allowed to replace the JSF implementation in the modules, so i am using the useBundledJsf property.
Running Payara Version: Payara Server 4.1.1.164 #badassfish (build 28)
This versions should support useBundledJsf properly.
I have added this to my glassfish-web.xml:
<class-loader delegate="false" />
<property name="useBundledJsf" value="true" />
and added the javax.faces dependecy to my pom:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.2.13</version>
</dependency>
I am getting the following error and all injections are failing.
SEVERE: JSF1051: Service entry 'org.glassfish.faces.integration.GlassFishInjectionProvider' does not extend DiscoverableInjectionProvider. Entry will be ignored.
I have tried to add the weld-integration.jar to my project but it still produces the JSF1051 error following by:
Unable to create a new instance of 'org.jboss.weld.jsf.ConversationAwareViewHandler'
The dependency for the weld-integration i have used:
<dependency>
<groupId>org.glassfish.main.web</groupId>
<artifactId>weld-integration</artifactId>
<version>4.1.2</version>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
There is an extra feature to make this easier in Payara Server 171 which was added specifically to make these scenarios work properly.
From the documentation:
It’s possible to configure an extreme isolation level on the class loading delegation for deployed applications. With this extreme isolation behavior, a deployed application can force the server to load only classes from libraries included on Payara Server that belong to whitelisted packages defined on its deployment descriptors.
To configure whitelist packaging you can use the <whitelist-package> element on the glassfish-web.xml (WAR artifacts) or the glassfish-application.xml (EAR artifacts). This element can be included multiple times to whitelist multiple packages. Here is an example of whitelisting both the Google Guava and Jackson packages for a WAR application:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
...
<whitelist-package>com.google.guava</whitelist-package>
<whitelist-package>com.fasterxml.jackson</whitelist-package>
</glassfish-web-app>
The whitelist syntax is simple: Define the name of the package which contains the classes in question. For example writing com.google would whitelist all Google libraries included on the server, while writing com.google.guava would only whitelist the Google Guava library instead.
Extreme Classloading Isolation
I've created portlet project in RSA, and set target runtime as WebSphere Portal 7 which I use. But now I want to create managed bean, to use JSF. But I cant import annotation. What I've missed?
If you are using maven you need to include this dependency to get the code to compile:
<dependency>
<groupId>javax.faces</groupId>
<artifactId javax.faces-api</artifactId>
</dependency>
Otherwise download the jar from maven central at http://search.maven.org/#search|ga|1|javax.faces.api and it to your project's build classpath in RSA.
I want to use OmniFaces 1.7 in my Jave EE 7 application. My application is an EAR that contains JARs and a skinny WAR. Some of my JARs have a dependency to OmniFaces, so the OmniFaces artifact must be in the EAR but not in WEB-INF/lib in the WAR.
Here is how my EAR looks like:
EAR
+-- lib
| +-- [some 3rd party JARs]
| `-- omnifaces.jar
+-- myEJBs.jar
`-- myWAR.war
When I put it this way, OmniFaces converters (like GenericEnumConverter) are not registered with JSF and won't work. The reason for this is discussed here and here. Basically according to the JSF 2.0 Spec (section 11.5.1 Requirements for scanning of classes for annotations), only the WARs WEB-INF/lib directory is scanned.
So my question is: how should I include OmniFaces in my application?
Including it twice (in EAR/lib and WARs WEB-INF/lib) could possibly work but feels clumsy. I tried it some time ago with RichFaces 4.3.5 (same problem) which didn't work but led to IllegalArgumentException: duplicate key: class javax.faces.convert.ByteConverter.
OmniFaces is a JSF utility library with dependencies on JSF, EL and Servlet APIs, which are normally only available inside a WAR, not an EAR. Even more, your EJBs (business services in general) are not supposed to have any dependencies on specific front-end APIs such as JSF, EL and Servlet APIs. It would make them unreusable on other front-ends such as JAX-RS, Spring MVC, etc.
You need to put JSF utility and component libraries such as OmniFaces and PrimeFaces in WAR, not in EAR. See also Installation section of OmniFaces homepage:
OmniFaces is designed as a WAR library (web fragment library) and therefore can't be placed elsewhere in the webapp's runtime classpath outside WAR's own /WEB-INF/lib, such as EAR's /lib or even server's or JRE's own /lib. When OmniFaces JAR file is misplaced this way, then the webapp will be unable to find OmniFaces-bundled JSF/CDI annotated classes and throw exceptions related to this during deploy or runtime. To solve it, put back OmniFaces in WAR's /WEB-INF/lib.
See also:
JSF Service Layer
#FacesComponent on shared library
#Eager is unavailable. The EagerBeansRepository could not be obtained from CDI bean manager
Reading the documentation of redhat (https://access.redhat.com/site/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Development_Guide/chap-Class_Loading_and_Modules.html) I found that the application server classloader
has a priority list when loading classes that are used to avoid any conflict between
loaded classes, The order is as below
Implicit dependencies.
These are the dependencies that are added automatically by JBoss Enterprise Application Platform 6, such as the JAVA EE APIs. These dependencies have the highest class loader precedence because they contain common functionality and APIs that are supplied by JBoss Enterprise Application Platform 6.
Refer to Section 3.7.1, “Implicit Module Dependencies” for complete details about each implicit dependency.
Explicit dependencies.
These are dependencies that are manually added in the application configuration. This can be done using the application's MANIFEST.MF file or the new optional JBoss deployment descriptor jboss-deployment-structure.xml file.
Refer to Section 3.2, “Add an Explicit Module Dependency to a Deployment” to learn how to add explicit dependencies.
Local resources.
Class files packaged up inside the deployment itself, e.g. from the WEB-INF/classes or WEB-INF/lib directories of a WAR file.
Inter-deployment dependencies.
These are dependencies on other deployments in a EAR deployment. This can include classes in the lib directory of the EAR or classes defined in other EJB jars.
I tried to test this order by using a JSF webapp (rich faces) in my EAR archive
My ear is as below :
sample.ear
--- sport.war
--- mysql.jar
--- lib
Usescase 1 : I added the JSF jars under the webapp (sport.war/WEB-INF/lib): [jsf-api-2.1.14.jar/jsf-impl-2.1.14.jar/portletbridge-api-3.1.2.Final.jar/portletbridge-impl-3.1.2.Final.jar], the jboss server started well and I don't have any exception
Usescase2: I added the JSF jars under sample.ear/lib
==> When I start the jboss server I get an exception (it sounds that the application server loaded the module JSF provided by jboss Implicit dependencies instead of the one in my sample.ear/lib)
I can't understand why in the 1srt usescase the Class Loading Precedence is not respected while in the 2sd usescase the Class Loading Precedence is respected?
Could you please clarify me this point
ENV
JBoss EAP 6.1.0.GA (AS 7.2.0.Final-redhat-8)
JDK 6
Without seeing the exact deployment exception that you got it is difficult to diagnose the issue.
In the first scenario the packaged libraries are loaded in the same class loader as your application.
In the second scenario the packaged libraries are loaded in a separate module and class loader.
The above means that , The deployment issue you were having fo not have to be related to Class Loading Precedence they could also be related to Class Loading Isolation.
Also Jboss and EAP already come with a prepackaged implementation of JSF, and you might be experiencing collisions due to version mismatch
If you were looking to replace the default JSF implementation on JBoss the better option to do so would have been to put the new JSF implementation in a static module, just like the default one , and have Jboss load it on demand.
I have made a jsf 1.1 portlet in weblogic 10.3, but in one scenario I need tomahawk library help. I just dropped the jar file and supporting ones in lib folder in WEB-INF in my portal application, but when I hit the url it gives me error of NoClassdef..... exception for classes in tomahawk jar and jsp compilation fails.
I am new to weblogic, I'll really appreciate if someoe can suggest what I might be doing wrong.
The setup is that whole application goes as ear. Ear contains app-inf and weblogic specific xml files, main portal web application goes as war inside this ear. I am using workshop that ships with weblogic portal 10.3. Well this project was migrated from weblogic portal 9.3.
Note: I dont want to but this jar in domain/lib, when I did so I dont know why it loaded my application and all the class defined in servlet startup with load-on-startups got fired well before time and none of the classes were found by server.
Jsf libraries currently used are in shared mode.
java.lang.NoClassDefFoundError means the runtime version of the class in the classpath is not the same as that at compile time.
Note: it's not a ClassNotFoundException.
Your problem is in fact multiple versions of the class being found.
Also, JSF 1.2 libraries are bundled with Weblogic server, so it can cause this exception if one of those classes is again added into the WEB-INF/lib. Which is the exact class on which the error is thrown, do you have multiple versions of Tomahawk lying around in WEB-INF and domain/lib?
Remove the extras and keep one in WEB-INF/lib only.
Update:
The docs state that Separate JSF 1.2 and JSTL 1.2 JAR files and implementation JAR files are also provided in the WL_HOME/server/lib/api.jar file.
Check for that class javax/faces/webapp/UIComponentELTag in this jar.
I still think you should use the weblogic.xml setting to force the WEB-INF/lib class to get loaded in preference to that in server/lib with
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
Being new to weblogic and infrastructure I messed up with different versions. Figured out it was just because of incompatible jars.