JSF 2.2 Tomcat JSF expression not rendered [duplicate] - java

I'm creating my first project Java EE 7, but I'm having trouble. Appreciate any help.
Tomcat 7.0.34
JSF 2.2
Primefaces 3.5
javaee-api-7.0.jar
When the application start, the Tomcat log shows the following message:
"validateJarFile (C:\...\build\web\WEB-INF\lib\javaee-api-7.0.jar)-jar not loaded. See Servlet 2.3 Spec, section 9.7.2. Offending class: javax/servlet/Servlet .class"
when I click on the button that calls the managed bean, I get the error:
AdvertĂȘncia: /index.xhtml #18,66 value="#{indexMB.user}": Target Unreachable, identifier 'indexMB' resolved to null
javax.el.PropertyNotFoundException: /index.xhtml #18,66 value="#{indexMB.user}": Target Unreachable, identifier 'indexMB' resolved to null
IndexMB
#Named("indexMB")
#RequestScoped
public class IndexMB {
private String password;
private String user;
public String loginTest(){
return (this.user.equals("admin") ? "adminPage" : "inOutPage");
}
// getters and setters
}
index.xhtml
<html ...>
<f:loadBundle basename="i18n" var="bundle" />
<h:head>
<title>#{bundle['index_title']}</title>
</h:head>
<h:body>
#{bundle['index_appname']}
<br />
<h:form id="frmIndex">
<p:panelGrid columns="2">
<p:outputLabel for="user" value="#{bundle['lblUser']}" />
<p:inputText id="user" value="#{indexMB.user}" />
<p:outputLabel for="password" value="#{bundle['lblPassword']}" />
<p:password id="password" value="#{indexMB.password}" />
</p:panelGrid>
<p:commandButton action="#{indexMB.loginTest}" value="#{bundle['btn_login']}" />
</h:form>
</h:body>
faces-config.xml
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<application>
<locale-config>
<default-locale>pt_BR</default-locale>
<supported-locale>en</supported-locale>
<supported-locale>fr</supported-locale>
</locale-config>
</application>
These topics have not helped me:
Java EE 6 #javax.annotation.ManagedBean vs. #javax.inject.Named vs. #javax.faces.ManagedBean
Target Unreachable identifier resolved to null
Target Unreachable, identifier resolved to null
javax.el.PropertyNotFoundException : Target Unreachable, identifier 'login' resolved to null Spring + JSF
http://www.andrejkoelewijn.com/blog/2010/03/05/jee-cdi-tip-target-unreachable-identifier-resolved-to-null/

Tomcat as being a barebones JSP/Servlet container doesn't support CDI out the box. It is not correct to drop jakartaee-api.jar or javaee-api.jar in /WEB-INF/lib just to get your code to compile. The JEE API JAR contains solely the API classes, not the concrete implementation. Get rid of the whole JAR. It can cause many other portability troubles like as the ones described in this answer: How do I import the javax.servlet / jakarta.servlet API in my Eclipse project? You should actually be installing the concrete implementation along with the specific API.
You have 2 options:
Drop Tomcat and go for a true Jakarta EE container. As you're using Tomcat, just step over to TomEE. It's really simple, download the TomEE web profile zip file, extract it and integrate it in Eclipse exactly the same way as you did for Tomcat. Don't forget to remove the Jakarta EE JAR file from webapp and alter the Targeted Runtime property in project's properties from Tomcat to TomEE so that Jakarta EE dependencies are properly resolved. See also What exactly is Java EE?
No additional JARs or configuration is necessary. You can even remove the manually installed JSF/JSTL/CDI/BV/JPA/EJB/JTA/JSONPJAX-RS/etc/etc libraries from your webapp. TomEE as being a true Jakarta EE container already provides them all out the box. In case you're using Maven, the below coordinate is sufficient.
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version><!-- e.g. 10.0.0 or 9.1.0 --></version>
<scope>provided</scope>
</dependency>
Note the importance of provided and its meaning as in "the target runtime already provides this out the box". See also How to properly configure Jakarta EE libraries in Maven pom.xml for Tomcat? for detailed pom.xml examples of Tomcat and normal JEE containers.
If you want to stick to Tomcat, then you need to manually install a true CDI implementation via the webapp. Below instructions assume Tomcat 10+. Weld is one of the available CDI implementations. In the Weld installation guide you can find instructions how to integrate it in Tomcat. For sake of completeness and future reference, here are the steps:
For Tomcat 10.1.x, drop the weld-servlet-shaded.jar of version 5.x in webapp's /WEB-INF/lib. In case you're using Maven, use this coordinate:
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-shaded</artifactId>
<version>5.1.0.Final</version>
</dependency>
For Tomcat 10.x, use weld-servlet-shaded.jar of version 4.x instead:
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-shaded</artifactId>
<version>4.0.3.Final</version>
</dependency>
Optionally, create a /META-INF/context.xml file in webapp with following content:
<Context>
<Resource name="BeanManager"
auth="Container"
type="jakarta.enterprise.inject.spi.BeanManager"
factory="org.jboss.weld.resources.ManagerObjectFactory"/>
</Context>
This step is is only necessary when the CDI-dependent library tries to manually find it in JNDI. This step is not necessary when you're using for example Jakarta Faces / JSF version 2.3 or newer.
Create a /WEB-INF/beans.xml file in webapp to trigger activation of CDI. It can be kept empty.
That's it.
In case you prefer OpenWebBeans above Weld as CDI implementation, or need to install CDI in Tomcat 9.x or older, head to this blog for detailed Maven installation instructions: How to install CDI in Tomcat?

Other possible option is leaving beans.xml in your deployment.

Related

Hibernate 5 + Glassfish 4.1.1: java.lang.NoSuchMethodError: org.jboss.logging.Logger.debugf(Ljava/lang/String;I)V

When I add Hibernate 5 to my website, I can't get it to work in Glassfish 4.1.1. I always get an error
java.lang.NoSuchMethodError:
org.jboss.logging.Logger.debugf(Ljava/lang/String;I)V
I've tried to replace the jboss-logging library in Glassfish' modules folder, like I read in an answer to a similar problem, but it didn't change anything. I also tried to use Hibernate 4, but that gave an other error.
In my case, I was running the Hibernate 5 with JPA annotations on tomcat and stop working when I changed to glassfish 4.1
The error:
hibernate.properties not found
Make sure: src/main/resources/hibernate.cfg.xml exists
And if you only have the dependency of hibernate-core, I was using hibernate-annotations and hibernate-common-annotations and it was creating conflict. The hibernate 5 doesnt need these two, I had read somewhere.Try to remove ;)
After that a new error appears:
java.lang.NoSuchMethodError: org.jboss.logging.Logger.debugf(Ljava/lang/String;I)V
The reason was the oldest jboss-logging.jar at:
"YOUR_GLASSFISH_FOLDER/glassfish/modules"
Why? The hibernate 5 has dependency with the newest version of
jboss-logging, and the glassfish 4 uses the oldest version even if you
declare inside your POM file the newest version. Actually I'm using:
org.jboss.logging jboss-logging 3.3.0.Final
Then I downloaded it and replace the old .jar inside the modules path
and it back to work, I spent 2 days trying to solve that and I hope it
helps some future issues =D
I used this link to help me: https://medium.com/#mertcal/using-hibernate-5-on-payara-cc242212a5d6#.npq2hdprz
Another solution, in my case, could be back to the last Hibernate 4 version (4.3.11.Final) but it is already too old in my opinion
I had a similar issue, I was able to fix it by creating a glassfish-web.xml file in the WEB-INF directory. The contents of the file are shown below:
<?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>
 <class-loader delegate="false"/>
</glassfish-web-app>
This ensures that glassfish does not load it's internal libraries, but libraries from your project..
Try to clean glassfish osgi-cache folder in your domain. You can find details in this Payara github issue: https://github.com/payara/Payara/issues/554 (Payara is a fork of Glassfish with additional features, so basic mechanics remain the same as in Glassfish)

virtualClasspath equivalent in tomcat 8

I am deploying instance of tomcat 8 and trying to find equivalent of virtualClasspath.
Below is the snippet of configuration descriptor I had in Tomcat 7,
<Context path="/path">
<Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="/home/kedar/third_party_jars/*.jar" />
</Context>
How can I specify the similar thing in tomcat 8. To be more specific, how to include multiple third party jars(as above) under classpath in the configuration descriptor of tomcat 8?
We can include each jar one by one in the following way, but I am looking some regex kind of way to include multiple jars.
<Resources className="org.apache.catalina.webresources.StandardRoot">
<PostResources className="org.apache.catalina.webresources.JarResourceSet"
base="/home/kedar//third_party_lib/xyz.jar"
internalPath="/"
webAppMount="/WEB-INF/classes" />
</Resouces>
Thanks in advance

Jackson 2 annotations ignored in EJB Jar with JBoss (6.2.0 GA)

I am migrating a web app from Websphere 7 (JEE5) to JBoss EAP 6.2.0 (JEE6). It currently works fine in Glassfish 3 & WAS.
The web interface consumes/produces JSON - so am using Jackson2 with Spring 3 MVC MappingJackson2HttpMessageConverter to handling (de)serialisation in a simple controller class.
In JBoss I see Jackson2 annotations #JsonProperty etc are being ignored in the ejb module - (they are applied to JPA entities only), but are being applied in the web module. So responses come back with different field names for some objects in JBoss which trips up our user interface.
I've tried every permuation of jboss-deployment-structure.xml to no avail (see below). I'm aware that JBoss ships with Jackson 1.x as an internal module. However, this doesn't seem to be the problem, otherwise the web module annotations would be ignored as well ? E.g.: Jackson annotations ignored after deployment to JBOSS
The app is structured as 3 maven modules - war, ejb (jar) & the ear container.
I'm going to refactor the code to remove the annotations from the JPA entities, but really it would be good to find a coherent solution, as there are several other apps to migrate.
JBoss descriptor I've tried below, makes no difference.
<jboss-deployment-structure>
<ear-subdeployments-isolated>false</ear-subdeployments-isolated>
<deployment>
<exclusions>
<module name="org.codehaus.jackson.jackson-core-asl"/>
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
</exclusions>
</deployment>
<sub-deployment name="my-war.war">
<exclusions>
<module name="org.codehaus.jackson.jackson-core-asl"/>
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
</exclusions>
</sub-deployment>
<sub-deployment name="my-ejbs.jar">
<exclusions>
<module name="org.codehaus.jackson.jackson-core-asl"/>
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
</exclusions>
</sub-deployment>
</jboss-deployment-structure>
Initial Workaround (reverted now)
Whilst it does not address what the original problem was caused by, I have solved this by adding a Jackson Mixin within the web module to rename/suppress the fields concerned. I've tested this and it works fine.
The point about all this, is that by using a Jackson Mixin, the scope of the customisation of the serialisation has been confined to the web module, and thereby avoided possible class loading issues due to ejb-jar sub-deployment. No jboss-deployment-structure.xml is being used.
Add a Mixin
public interface MyMixin {
#JsonIgnore
String getUnwantedField();
#JsonProperty(value = "newName")
String getOldName();
}
Then in the startup of my web controller I wire in the Mixin to the Jackson ObjectMapper which is autowired into the controller and defined in my dispatcher servlet xml config.
#Autowired
private ObjectMapper objectMapper;
#PostConstruct
void configObjectMapper() {
objectMapper.addMixInAnnotations(MyEjbJar.class, MyMixin.class);
}
Dispatcher servlet:
.
.
<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>
I have tracked this down (via IDE debugger & adding logging) to different classloaders being used for the war module and ejb jar module. This is expected default behaviour with JBoss AS 7 according to the docs. The war uses the war ModuleLoader, and the ejb jar uses the ear ModuleLoader.
What happens is the Class for the annotation differs depending on which class loader loads the annotation. Also see: similar issue on SO
By "differs" I mean they are the same annotation, sourced from the same jar & version, but they are not deemed equivalent according to the contract for equals, their hashcodes differ, therefore the JacksonAnnotationIntrospector does not locate annotations even though they show as held against the JPA POJO class.
Workaround
I have worked around this by making the ear ModuleLoader be a common loader for jackson 2. I did this by making the com.fasterxml.jackson.core databind dependency provided scope in the war & ejb jar, and marking it as a normal compile scope dependency in the ear POM.
This kind of approach is sort of endorsed here JBoss AS classloading although it uses the jboss-deployment-structure or MANIFEST.MF to achieve pretty much the same thing.

Upgrade Hibernate version in JBOSS

I am having a hard time when trying to ship inside my EAR my own version of Hibernate (and not the one that JBoss brings by default).
Then I made my deployment "scoped" by including in the EAR a jboss-app.xml file containing the following:
<jboss-app>
<loader-repository>
com.example:archive=unique-archive-name
<loader-repository-config>
java2ParentDelegation=false
</loader-repository-config>
</loader-repository>
</jboss-app>
And, as usual, I declare my persistence provider in the persistence unit to be Hibernate, as follows:
<persistence>
<persistence-unit name="myapp">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
...
But then, the worst happens. On deployment, the server throws a ClassCastException when it tries to cast from org.hibernate.ejb.HibernatePersistence to the JPA interface javax.persistence.spi.PersistenceProvider (which IS implimented by HibernatePersistence).
This is kind of WEIRD, because I am shipping the JPA API also in my EAR, so, given that the classes of the EAR have priority to those of JBoss, it should have no problem when casting from HibernatePersistence to PersistenceProvider, since they "should be" on the same class loader.
If I don't ship my own JPA API, then the deployment fails with a ClassNotFoundException when JBoss tries to find some JPA class.
Any idea on why is this casting failing?
I am using JBoss 5.1.0, and trying to use Hibernate 3.5.6.Final. The JPA API version is the one imported transitively by the menctioned Hibernate version.
You could try turning on class scoping via the ear deployer. For JBoss 5.x edit:
jboss/server/[configuration]/deployers/ear-deployer-jboss-beans.xml
and change:
<bean name="EARClassLoaderDeployer" class="org.jboss.deployment.EarClassLoaderDeployer">
<property name="isolated">false</property>
</bean>
setting isolated to true.
Have you included the hibernate-entitymanager.jar too?
Otherwise you can try replacing the hibernate core jar in the common/lib with the 3.5.6 version.
To solve the class loading issues with hibernate in jboss server you need to add the jboss-classloading.xml inside the WEB-INF folder of your web application. Read more about these configuration settings here.
<classloading xmlns="urn:jboss:classloading:1.0"
domain="pentaho.ear"
export-all="NON_EMPTY"
import-all="true"
parent-first="false">
</classloading>

Struts <bean:cookie> tag breaks on WebLogic 11gR1

I'm trying to deploy a very simple Struts app on WebLogic 11gR1. The app has one JSP called Welcome.jsp and this JSP contains the following tag :
<bean:cookie name="" id=""/>
The associated taglib is imported at the top of the JSP using the following line :
<%# taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
When this tag is inside the JSP, I've the following error :
Welcome.jsp:11:24: javax.servlet.http.Cookie cannot be resolved
<body bgcolor="white"><bean:cookie name="" id=""/>
But when I remove this tag, the Welcome.jsp works just fine.
The JSP includes other tags like :
<bean:message key="welcome.heading"/>
Those tags are working just fine.
And to finish, the ActionServlet of Struts is also working and starting with the app.
I'm guessing that there must be a classloading problem but I don't understand why the Struts ActionServlet is working : javax.servlet.http.Cookie and javax.servlet.http.HttpServlet are declared in the same package.
Maybe, there is a problem with the Oracle implementation of the Cookie class in WebLogic but it is very unlikely.
Thanks.
javax.servlet.http.Cookie is an interface showing the structure that those who are implementing the Servlet API need to implement.
The issue might be with your WebLogic 11gR1 configuration/libary: I'll explain using Tomcat 7.0.
In Tomcat 7.0, under TOMCAT_HOME/lib folder, there's a servlet-api.jar. That jar allows Tomcat to support the Java Servlet API specification (and has Cookie.class included in the directory, under javax/servlet/Cookie).
Your WebLogic 11gR1 must have a Servlet Container library that conforms to the Servlet API (like Tomcat's servlet-api.jar). I never used WebLogic, but if you have a lib folder somewhere (apparently WL_HOME/server/lib), make sure there's a servlet api somewhere (I think weblogic.jar contains servlet api implementations).
Also, please check that you don't have a servlet like library (e.g. servlet-api.jar, eclipse servlet jars, etc.) inside your WAR file as it can conflict with WebLogic's servlet library.

Categories