Composite component backing bean location - jsf-2

I'm trying to split my JSF2 pages into composite components. So I decided to put the composite components in a logical file tree. For example:
WebContent/resources/components/page1/component1.xhtml
The associated bean is in
Java resources/src/components/page1/component1.java
Its package is this components.page1.
In this example, component1.xhtml is found and rendered, but the bean is not found by the server.
If I don't use a subpackage:
WebContent/resources/page1/component1.xhtml
Java resources/src/page1/component1.java
So when the class is in the package page1, it works!
Is there a problem with composite component beans and subpackages?
I am using MyFaces 2.0, Tomcat 6 and Eclipse.

You need the componentType attribute of <cc:interface> to explicitly specify the backing component.
<cc:interface componentType="component1">
with
package components.page1;
#FacesComponent("component1")
public class Component1 extends UINamingContainer {
// ...
}

Related

Ejb jndi binding in java code

The method is loading a bean
Context ctx = new InitialContext();
Object lookupResult = ctx.lookup("abilitecConsumerClient/local");
And another class
#Stateless
#LocalBinding(jndiBinding="abilitecConsumerClient/local" )
#Local()
What exactly does represent abilitecConsumerClient/local? Is that the path in my local machine that I need to look for this property file or the file I need it loads for this EJB JNDI binding name?
If you can also give info how to specify a custom EJB JNDI binding name in JBoss EAP 6?
This app is going to run on JBOSS EAP 6.
According to the old JBoss documentation:
...when the application is deployed in a .jar, session beans will bind to JNDI in the form (...) ejbName/local in the case of local interfaces. When the EJBs are deployed in an .ear file, the default JNDI binding will be prepended by the name of the .ear file.
So, if we have an EAR file which name is foo.ear the default JNDI name would be foo/EJB-NAME/local.
This behavior can be overriden by defining our own #LocalBinding annotation on our bean.
By definition, the #LocalBinding annotation specifies the local JNDI binding for an EJB local interface.
Which means that the value of the element jndiBinding, passed on #LocalBinding, represents the name associated (binded) to the bean, where the annotation was placed, on the Java Naming and Directory Interface (JNDI).
This then allows us to retrieve an instance of the bean, as you mentioned, by looking it up on the JNDI, using the jndiBinding defined on the #LocalBinding annotation:
MyBean bean = ctx.lookup("abilitecConsumerClient/local");
NOW, regarding your last question, notice that in beginning of my answer I said ...old JBoss documentation.... Why? Because since JBoss EAP 6 (or JBoss AS 7), the binding of EJBs to custom JNDI names isn't allowed anymore either by annotations or XML configuration.
One may assume that it was due to the efforts of Java EE 6 to standardize EJB Namespaces.
You can take a closer look at the JNDI changes present on JBoss EAP 6, where EJB 3.1 introduced a standardized global JNDI namespace and a series of related namespaces that map to the various scopes of a Java EE application.
Making a parallel between prior EAP 6 and after, we have:
Prior to EAP 6
// Bean definition
#Stateless
#LocalBinding(jndiBinding="custom/MyBean")
public class MyBeanImpl implements MyBean {
(...)
}
// look-up
ctx = new InitialContext();
MyBean myBean = (MyBean) ctx.lookup("custom/MyBean");
After EAP 6
// Bean definition
#Stateless
#Local(MyBean.class)
public class MyBeanImpl implements MyBean {
(...)
}
// look-up
MyBean myBean = (MyBean)
InitialContext.lookup("java:module/MyBean");
// or through injection
#EJB
MyBean myBean;
Finally, you can find more examples on how to do the EJB look-up on the JBoss AS 7 examples and take a careful look at the following:
Portable JNDI sintax
Application-specified Portable JNDI Names
Section "Examples of JNDI mappings in previous releases and how they might look now" of How do I migrate my application from AS5 or AS6 to AS7

ManagedBean Params not accepted and Bean seemingly not in scope

This uses the same code that comes from
primefaces tree control
#ManagedBean( name = "theName", eager = true)
The first question is why "name" and "eager" are not recognised. Eclipse suggests I change either parameter to "value" - so not sure whats going on there.
Then, where I have been careful to capitalise where necessary and create my bean
public class TreeBean implements Serializable {
and reference it in my xhtml
<h:form id="mainForm">
<p:tree id="treeSingle" value="#{treeBean.root}" var="node"
selectionMode="single"
selection="#{treeBean.selectedNode}">
(paying attention to the capitalisation of the classname).
The output shows only a narrow bar. System.out.println("Constructor called") suggests the bean is not known. To support this, if I press the button as coded in the example (link provided at the top) I get the error
Jan 13, 2014 12:19:26 AM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
SEVERE: javax.el.PropertyNotFoundException: /HelloWorld.xhtml #23,50 selection="#{treeBean.selectedNode}": Target Unreachable, identifier 'treeBean' resolved to null
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:133)
I've run out of ideas now as to what could be the problem. Is there any way of further debugging this or anyone got any ideas about the eager/name thing and what is causing the Bean class to be (I assume) not to be seen.
Thanks in advance.
Kevin
beans should be defined this way:
#ManagedBean(name="treeBean")
#SessionScoped // or whatever scope you would like to use
public class TreeBean implements Serializable {
....
Usage in XHTML: ...="#{treeBean.root}"
Or
#ManagedBean(name="xyz")
#SessionScoped // or whatever scope you would like to use
public class TreeBean implements Serializable {
....
Usage in XHTML: ...="#{xyz.root}"
bean name is just a key for the map, you can name it whatever you want
the scope of the bean should be from the package javax.faces.bean
i.e. for sessionscoped beans you have to import
import javax.faces.bean.SessionScoped;
and for the managedBean Annotation
import javax.faces.bean.ManagedBean;
Here you can find different ways to define a JSF managed bean and also here you can find a really good discuss about managed beans.

NotSerializableException on ViewScoped ManagedBean with CDI Injected properties

I'm trying to create a scalable JSF application.
I would like to save view states on client side but I have troubles with ViewScoped ManagedBean with CDI Injected attributes.
SomeService.java :
#Singleton
public class SomeService {
// ...
}
SomeBean.java
#ManagedBean
#ViewScoped
public class SomeBean implements Serializable {
#Inject
private SomeService someService;
}
Unfortunately glassfish fails to serialize someService which I don't want to be serializabled but re-injected.
I tried to make it transient which ends up to a NullPointerException when accessing someService after de-serialization.
What shall I do?
I'm aware that I could use CDI ViewScoped with Seam Faces or CODI but I want to minimize at most dependencies.
I could also wait for JEE7 which will provide #ViewScoped for CDI but we won't be using JEE7 before months.
UPDATE :
I just wanted to add that I was using embedded EJB bundled in a jar which is itself linked to my war.
NotSerializableException's stack trace has the following message :
com.company.core.service.__EJB31_Generated__SomeService__Intf____Bean__
I don't like to self respond to my own questions but after some more research I found that it was a bug in Mojarra 2.1.6 (I'm using Glassfish 3.1.2.2) which is now solved in Mojarra 2.1.20.
To update Mojarra you just need to download a fresher version (eg: https://maven.java.net/content/repositories/releases/org/glassfish/javax.faces/2.1.20/javax.faces-2.1.20.jar) and place it in the $GLASSFISH/modules directory as javax.faces.jar.

How to access a local interfaces from one project into another within the same ear project

I have a web project that has FacesValidator, this validator needs to access an EJB service to verify if a record exists. Unfortunately, I cannot inject my enterprise beans since the validator is not a managed-bean, so I'm trying to access it via InitialContext. I've tried different combination from http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html but failed.
What works is this format:
java:global/myProject-ear-1.0.0/myProject/MyService!com.czetsuya.myProject.service.membership.MyService,
My question is can it be simplify? Seems too long.
Thanks,
czetsuya
Look at the server logs. A bit decent EJB container (at least, Glassfish 3 and JBoss 6/7 do), logs all available JNDI names of the EJB during EJB deployment step. Provided that the validator is properly been put in the WAR and the EJB has a #Local interface, then the shortest JNDI name would be the java:app one which should in your case have been java:app/myProject/MyService.
A completely different alternative is to just make the validator a JSF or CDI managed bean instead, so that you can just use the #EJB annotation.
#ManagedBean // Or #Named.
#ApplicationScoped // Provided that the instance doesn't have any state.
public class MyValidator implements Validator {
#EJB
private MyService myService;
// ...
}
and reference it by binding instead of validatorId:
<f:validator binding="#{myValidator}" />
Note that from JSF 2.2 on, you should be able to inject #EJB in a #FacesValidator (and #FacesConverter).
See also:
How to inject in #FacesValidator with #EJB, #PersistenceContext, #Inject, #Autowired

Inject singleton bean into session bean via remote interface, object always "null"

I need to inject a singleton bean into the session bean. Below are the corresponding classes. The problem is that the injected object is always null. I tried all of the JNDI lookup strings which my JBoss 7.0.1 server showed me during startup (i.e. JNDI bindings for session bean named GlobalBean in deployment unit subdeployment .. of deployment .. are as follows: ..). I also tried commenting out the #EJB annotation in GlobalBean.java and also tried to use the "ejb/GlobalBean" during injection. However, no luck. What could be the reason? Thx.
GlobalBean.java:
#Startup
#Singleton
#Remote(GlobalBeanRemote.class)
#EJB(name="ejb/GlobalBean", beanName="GlobalBean", beanInterface=GlobalBeanRemote.class)
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class GlobalBean implements GlobalBeanRemote
{
// CODE
}
SessionBean.java:
#Stateful
public class SessionBean extends ParentBean
{
#EJB(name="java:module/GlobalBean!project.framework.interfaces.GlobalBeanRemote")
private GlobalBeanRemote globalBeanAPI3;
// CODE
}
In your SessionBean class try changing name attribute of #EJB to mappedName.
#EJB(mappedName="java:module/GlobalBean!project.framework.interfaces.GlobalBeanRemote")
This will, of course, only work if your two beans are in the same module.
Update
Given that your beans are in separate modules, try using the java:app namespace:
#EJB(mappedName="java:app ...")
The java:app namespace is used to look up local enterprise beans packaged within the same application. That is, the enterprise bean is packaged within an EAR file containing multiple Java EE modules. JNDI addresses using the java:app namespace are of the following form:
java:app[/module name]/enterprise bean name[/interface name]
Also try removing GlobalBean's #EJB annotation. #EJB is used to define a dependency.

Resources