JSF custom component with #FacesComponent is not found in Spring Boot - spring

I want to create a custom JSF 2.0 component but can't get it to work.
My component is defined like this:
#FacesComponent(value = "myCustomComponent")
public class CommaSeperatedOutput extends UIComponentBase { ... }
The taglib looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd" version="2.0">
<namespace>http://www.company.com/tags</namespace>
<tag>
<tag-name>custom</tag-name>
<component>
<component-type>myCustomComponent</component-type>
</component>
</tag>
</facelet-taglib>
My faces-config looks like this:
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
</faces-config>
I get the following error:
SEVERE: JSF1068: Component with componenttype myCustomComponent could not be instantiated.
javax.faces.FacesException: Expression Error: Named Object: myCustomComponent not found.
Not sure if it is important, but I'm using Spring 3.1 together with JSF 2.1 here. So dependencies are managed by Spring.
Any idea what is happening here?

[moving author's solution here]
Seems like Spring is the bad guy here.
I've removed the annotation #FacesComponent(value = "myCustomComponent") from the component and defined it instead in my faces-config like this:
<component>
<component-type>myCustomComponent</component-type>
<component-class>com.company.jsf.component.CommaSeperatedOutput</component-class>
</component>
Now it works.

Alternatively, and since you've configured your faces-config.xml file to use the Spring Container, you could use the Spring annotation #Component("myCustomComponent")

Related

How to specify which application-{env}.yml to use in application.yml while using maven package? Is it specified in runtime or compile time?

Have tried all methods.. passing a variable from maven pom.xml to application.yml file. using #environmentVariable#, -Dspring.profiles.active etc.
To specify the yml file used by spring boot packaged as a war file, you should configure the spring.config.additional-location context parameter in your WEB-INF/web.xml file, similar to this...
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>spring.config.additional-location</param-name>
<param-value>file:./my-application.yml</param-value>
</context-param>
</web-app>

Start Jetty application but "java.lang.IllegalStateException: Duplicate fragment name"

Sorry if duplicated.
I am using gradle to build my .war file and start my application using Jetty. But I see this error message
java.lang.IllegalStateException: Duplicate fragment name: spring_web for jar:file:/private/var/folders/r7/z7yqbhx10wl9kyw738crggdd0zwztx/T/jetty-0.0.0.0-8080-application-1.0.war-_pplication-1.0-any-/webapp/WEB-INF/lib/spring-web-4.1.9.RELEASE.jar!/META-INF/web-fragment.xml and jar:file:/private/var/folders/r7/z7yqbhx10wl9kyw738crggdd0zwztx/T/jetty-0.0.0.0-8080-cpplication-1.0.war-_pplication-1.0-any-/webapp/WEB-INF/lib/spring-web-4.1.9.RELEASE.jar!/META-INF/web-fragment.xml
I already did some research on internet, but all are talking about jetty-maven-plugin and the solution is to add "<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>" to webAppConfig. But in my application I don't have webAppConfig. Is this only for Maven? How to solve this if I am using Gradle?
Thanks!
you can put jetty.xml under WEB-INF
jetty.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC
"-//Mort Bay Consulting//DTD Configure//EN"
"http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="allowDuplicateFragmentNames">true</Set>
</Configure>
In your WEB-INF/web.xml, look for the tag (should be at the top), and modify atributes to match these values:
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/j2ee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
metadata-complete="true"
..
>

No Spring Bean found in EJB with SpringBeanAutowiringInterceptor

I need some help: I have one EAR-File, containing one WAR-File, one EJB-Jar-File and some "shared" libs:
aopalliance-1.0.jar commons-logging-1.1.1.jar log4j-1.2.16.jar spring-aop-4.0.5.RELEASE.jar spring-beans-4.0.5.RELEASE.jar spring-context-4.0.5.RELEASE.jar spring-context-support-4.0.5.RELEASE.jar spring-core-4.0.5.RELEASE.jar spring-expression-4.0.5.RELEASE.jar
The War File has a Context initializer which find the spring config and loads everything well.
I now want to use another Spring Context for the EJB Jar.
My EJB is defined as
#Stateless(mappedName = "ejb/SpringRocks")
#RemoteHome(com.ibm.websphere.ola.ExecuteHome.class)
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class WolaUseCaseOne {
#Autowired
private DummyService dummyService;
/* ...More stuff here */
Inside the EJB-JAR, there is also a beanRefContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myEjb" name="myEjb" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg value="classpath*:META-INF/spring/simpleEjb.xml" />
</bean>
</beans>
The simpleEjb.xml is is also inside the EJB-Jar and is defining a very simple Bean:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myDummyService" class="com.provinzial.beispielanwendung.batch.wola.DummyServiceImpl" />
</beans>
As described, the WEB Part works perfect, but when the EJB is called, the SpringBeanAutowiringInterceptor is called, but seems to do nothing. What do I have to do, to get a Spring Context created?! My hope was that it is initialized when the EJB is created. I created a Subclass of SpringBeanAutowiringInterceptor with some loggers, but the class is only created, no method is called !
What else do I have to do? Or does anybody have a valid EAR File example?
I think the Problem is that inside the EJB Module no context is initialized...
Greets
Timo
I was facing similar issue with my EJB (no WAR). This is what fixed mine,
I was missing the spring-aop jar on my classpath. I see you have it so good there.
In my ejb-jar.xml file, I set the meta-data flag to true so I did not get prompted on deployment to complete.
I set to "false" for one deployment to see what IBM generated for me. In the ejb-jar.xml it added the following (my MDB is named TaskMDB),
<assembly-descriptor>
<interceptor-binding>
<ejb-name>TaskMDB</ejb-name>
<interceptor-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
<interceptors>
<interceptor>
<interceptor-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</interceptor-class>
<post-activate>
<lifecycle-callback-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</lifecycle-callback-class>
<lifecycle-callback-method>autowireBean</lifecycle-callback-method>
</post-activate>
<pre-passivate>
<lifecycle-callback-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</lifecycle-callback-class>
<lifecycle-callback-method>releaseBean</lifecycle-callback-method>
</pre-passivate>
<post-construct>
<lifecycle-callback-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</lifecycle-callback-class>
<lifecycle-callback-method>autowireBean</lifecycle-callback-method>
</post-construct>
<pre-destroy>
<lifecycle-callback-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</lifecycle-callback-class>
<lifecycle-callback-method>releaseBean</lifecycle-callback-method>
</pre-destroy>
</interceptor>
</interceptors>
Then I added what IBM generated (the assembly-descriptor and interceptors stanzas) back to my ejb-jar.xml and set the metadata-complete back to true.
Then it worked. Hope this helps.
Here is the full ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
<display-name>ares-api-uow-ejb</display-name>
<enterprise-beans>
<message-driven id="TaskMDB">
<ejb-name>TaskMDB</ejb-name>
<ejb-class>something.api.uow.ejb.mdb.TaskMDB</ejb-class>
<messaging-type>javax.jms.MessageListener</messaging-type>
<transaction-type>Bean</transaction-type>
</message-driven>
</enterprise-beans>
</ejb-jar>

Spring Boot <absolute-ordering/> and metadata-complete="true" done with java config

I have a Spring Boot app. In that app, all my config is done with java config and currently i needed to add to my configuration two new security related entries, i.e.
metadata-complete="true"
<absolute-ordering/>
Till now i did not had web.xml file in my project. My question is how to configure those two features with java config i.e. no XML.
Here is an example of my current web.xml (located in "src/main/resources/WEB-INF/web.xml") file that i need to convert to java config
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true"
>
<absolute-ordering/>
</web-app>
In an embedded container I don't think those properties in web.xml have any meaning, so you should be good to go. Spring Boot does not process WebApplicationInitializers (for example).

What DTD should I use in JSF 1.2/2.0/2.1 to validate my configuration XML?

currently, I have following DTD:
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
And it does not validate the 1.2 tags, like:
managed-bean => managed-property
And I cannot find a newer version form sun:
http://java.sun.com/dtd/
from some tutorials, I see people simply not using DTD for JSF 2 at all, should I try to find a DTD or is DTD deprecated for JSF 1.2+?
Many thanks for your suggestions.
JSF 2.0 doesn't have a DTD. It's a XSD.
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0"
>
<!-- Config here -->
</faces-config>
The same story applies to JSF 1.2.
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2"
>
<!-- Config here -->
</faces-config>
If you were using a JSF 1.1 DTD on JSF 1.2/2.0, then those applications will run in JSF 1.1 mode. You really don't want to have that.

Resources