May 5, 2012 - EJB is null inside RESTful web service

Comments

While developing my enterprise application and learning Java EE at the same time, I came to a situation where injecting an EJB inside a RESTful web service class would be the same as nothing. The EJB variable was always null.

So, what did I change to fix this?
This was my source code before:
@Path("/mypath")
public class MyREST {

@EJB
private MyFacadeLocal myFacade;

public MyREST() {
}

@GET
@Produces("text/plain")
public String respond() {
return "DONE";
}
}
I forgot to tell the scope of the service. I managed to make it work by turning it request scoped (although from what I read it should be, by default, request scoped):
@RequestScoped
@Path("/mypath")
public class MyREST {

@EJB
private MyFacadeLocal myFacade;

public MyREST() {
}

@GET
@Produces("text/plain")
public String respond() {
return "DONE";
}
}

If I make it session scoped, I end up with the issue: Error creating managed object for class.

If I make it @Stateless, it also works properly and seems to be the recommended way:
@Stateless
@Path("/mypath")
public class MyREST {

@EJB
private MyFacadeLocal myFacade;

public MyREST() {
}

@GET
@Produces("text/plain")
public String respond() {
return "DONE";
}
}

Notice that MyFacadeLocal is actually an interface for the session bean (which doesn't have the @LocalBean annotation itself). If I want to directly inject the session bean (called MyFacade) I need to have the @LocalBean annotation in it. If not, the EJB inside the RESTful web service may not be properly deployed and the following error may appear:

java.lang.IllegalStateException: Exception attempting to inject Remote ejb-ref name=rest.MyREST/myFacade,Remote 3.x interface =ejb.MyFacade,ejb-link=null,lookup=,mappedName=,jndi-name=ejb.MyFacade,refType=Session into class rest.MyREST: Lookup failed for 'java:comp/env/rest.MyREST/myFacade' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}

Here's MyFacade without requiring an interface (assuming you'll be using it locally anyway):
@LocalBean
@Stateless
public class MyFacade extends AbstractFacade {
@PersistenceContext(unitName = "myjpaunit")
private EntityManager em;

@Override
protected EntityManager getEntityManager() {
return em;
}

public MyFacade() {
super(My.class);
}

@Override
public int count() {
return super.count();
}

@Override
public void create(My entity) {
super.create(entity);
}

@Override
public void edit(My entity) {
super.edit(entity);
}

@Override
public My find(Object id) {
return super.find(id);
}

@Override
public List findAll() {
return super.findAll();
}

@Override
public List findRange(int[] range) {
return super.findRange(range);
}

@Override
public void remove(My entity) {
super.remove(entity);
}
}

Another cause for having a null EJB is if, for any reason, an exception is thrown inside of it. Java EE will not inject it if running the EJB methods that are supposed to be called through the dependent object leads to exceptions. So, if you comment every call in your dependent object and then just check if the EJB is null, you'll see it isn't. But if you make use of a malfunctioning method, the EJB will just become null.
Useful links:
Glassfish embedded with JUnit for EJB testing

May 5, 2012 - Error creating managed object for class

Comments

Well, while developing my enterprise application in NetBeans 7.1.2 with GlassFish 3.1.2 as the application server, the following most notable error appeared and made the project unable to deploy:

Error creating managed object for class: class org.jboss.weld.servlet.WeldListener

and a bunch of other errors and exceptions.


I tried to revert my changes since the last revision from the revision control and found myself in the same situation.

Manual clean followed by build also did nothing.

Solution:
My gut told me I just needed to clean the NetBeans trash and so I did:

  • I deleted all of my project locally;
  • Restarted NetBeans;
  • Checked out my project from the revision control again;
  • Run it, and it worked!
I don't know the cause of this, but if you can't find another way then just try to clean your NetBeans generated junk.

I was having this in the context of a RESTful web service (Jersey) plus EJBs which was working properly. A little investigation told me that it might be a bug in Jersey, check the links below for more information.

I also invite you to comment on a better solution for this and I'll update this post with it.

Update: I can now reproduce this issue, if I set my RESTful web service to be session scoped (@SessionScoped) it breaks but sometimes I can make it work by changing to request scoped (@RequestScoped) again. My source code is simply the following:

@SessionScoped
@Path("/mypath")
public class MyREST {

@EJB
private MyFacadeLocal myFacade;

public MyREST() {
}

@GET
@Produces("text/plain")
public String respond() {
return "DONE";
}
}

Useful links:

Apr 17, 2012 - Generated Facelets templates not applying / can't find CSS stylesheets

Comments

Using NetBeans, I have created a Facelets template and a Facelets template client through the wizards provided. No changes were made to the source code.

However, when navigating in the generated template client with my browser, I noticed that the sections "inserted" (e.g, header, footer, content) were not being stylized in any way.

After a great deal of head banging onto the wall, I finally found a solution for this.
I checked the generated HTML source code in my browser (from /faces/index.xhtml, my template client)  to see where the CSS files were being pointed at:
http://localhost:8080/MyContextRoot/faces/resources/css/default.css
http://localhost:8080/MyContextRoot/faces/resources/css/cssLayout.css

These files were not publicly available, so the browser couldn't load them to process the styles. This was all generated by NetBeans. My /faces/index.xhtml was generated dynamically with sucess, so it wasn't a problem with the mapping of the Faces servlet.

After comparing my project files, specifically the WEB-INF/web.xml, with an empty project I came to the conclusion that the cause of the problem was a conflict in servlet URL patterns. This is how my web.xml looked like:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.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-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>10</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
</web-app>

The /* URL pattern from the Jersey servlet will basically hide the stylesheets location, so they will not be accessible through the generated template code.


Fixing it


1. The best fix is the right one. Go to your WEB-INF/web.xml and fix any superposition of URL patterns. In my case I changed the Jersey URL pattern from:
    <servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
to:
    <servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>

2. If you don't want to do the above method, open your template file (in my case it was template.xhtml) and replace the following lines:

<link href="./resources/css/default.css" rel="stylesheet" type="text/css" />
<link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" />
with:
<h:outputStylesheet name="css/default.css"/>
<h:outputStylesheet name="css/cssLayout.css"/>

The difference is that now the actual HTML CSS include code will be generated in the server with the correct link for the CSS files. I checked the code that was generated in my case, which was:
<link type="text/css" rel="stylesheet" href="/MyProject/faces/javax.faces.resource/css/default.css" />
<link type="text/css" rel="stylesheet" href="/MyProject/faces/javax.faces.resource/css/cssLayout.css" />

And it also works. You can use it but it is less portable and depends on the configuration and future releases.

I hope that in the future Oracle adds a way to auto-detect these conflicts in NetBeans to ease development for beginner Java EE developers.

Useful links:
JSF template not applied
Styles not getting applied for the Facelets template client
Applying a Facelets Template

Update (2015-Oct-11) with a recommended introduction to JSF:
JSF Tutorial: An Introduction to JSF