0

EJB 3.1 Injection using annotation

asked 2011-07-19 08:26:39 +0800

marcelodecampos gravatar image marcelodecampos
183

updated 2011-07-19 08:29:45 +0800

I really do not like to bother, but I need a help: I am currently now testing a new application using EJB 3.1 and can not use dependency injection in the controller. But work on a regular servlet. It seems obvious that this should be no problem with zk. If someone went through something similar and can help me thank you.
If I use jndi lookup works perfectly, of course.
Let the code:


This is a simple zul file:

<?page title="Auto Generated index.zul"?>
<window title="Hello World!!" border="normal" width="100%" apply="TestController">
	<div align="Center">
		<vlayout>
			<label value="You are using: ${desktop.webApp.version}"/>
			<button label="Load List" id="btnLoad"  />
			<listbox id="listObjects" vflex="true" mold="paging" autopaging="true" >
				<listhead>
					<listheader label="This is my list" sort="auto" >
					</listheader>
				</listhead>
			</listbox>
		</vlayout>
	</div>
</window>


And this is the zul controller:

import java.util.Collections;
import java.util.List;

import javax.ejb.EJB;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;

import br.com.mcampos.ejb.system.entity.Menu;
import br.com.mcampos.ejb.system.menu.session.MenuServiceRemote;


public class TestController extends GenericForwardComposer
{
	private static final long serialVersionUID = -5998869122000174965L;
	private Listbox listObjects;

	@EJB
	private MenuServiceRemote service; // THE problem!!!!!!

	@Override
	public void doAfterCompose( Component comp ) throws Exception
	{
		super.doAfterCompose( comp );
		List<Menu> list = Collections.emptyList( );

		if ( service != null ) // THIS IS ALWAYS NULL????
			list = service.getAll( );
		listObjects.setModel( new ListModelList ( list ) ); //we don't have a render,but doesn't matter now
	}
}


Just in case, I've made a simple servlet just in case and it works!!!! Annoying!

/**
 * Servlet implementation class TestServlet
 */
@WebServlet("/test")
public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    public TestServlet() {
    }

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGetPost(request, response);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGetPost(request, response);
	}

	@EJB
	private MenuServiceRemote service;  // THIS IS THE SAME OF MY CONTROLLER

	private void doGetPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		response.setContentType( "text/html;charset=UTF-8" );
		PrintWriter out = response.getWriter( );
		out.println ( "<html><body></body></html>");
		if ( service != null ) {                               // ######NOT NULL######, it works :(
			List<Menu> list = service.getAll( );
			for ( Menu item : list ) {
				out.println ( "<br /> " + item.getMnuDescriptionCh( ) );
			}
		}
		out.println ( "</body></html>");
		out.close ();
	}
}


The code's boring part - Entity + SessionBean + Interface:

@Entity
@Table(name="menu")
public class Menu implements Serializable {
	private static final long serialVersionUID = 1L;
	private Integer mnuIdIn;
	private Boolean mnuAutocheckBt;
	private Boolean mnuCheckedBt;
	private Boolean mnuCheckmarkBt;
	private String mnuDescriptionCh;
	private Boolean mnuDisabledBt;
	private Boolean mnuSeparatorBeforeBt;
	private Integer mnuSequenceIn;
	private String mnuUrlCh;
	private Menu menu;
	private List<Menu> menus;
	private Media media;

    public Menu() {
    }


	@Id
	@Column(name="mnu_id_in", unique=true, nullable=false)
	public Integer getMnuIdIn() {
		return this.mnuIdIn;
	}

	public void setMnuIdIn(Integer mnuIdIn) {
		this.mnuIdIn = mnuIdIn;
	}


	@Column(name="mnu_autocheck_bt")
	public Boolean getMnuAutocheckBt() {
		return this.mnuAutocheckBt;
	}

	public void setMnuAutocheckBt(Boolean mnuAutocheckBt) {
		this.mnuAutocheckBt = mnuAutocheckBt;
	}


	@Column(name="mnu_checked_bt")
	public Boolean getMnuCheckedBt() {
		return this.mnuCheckedBt;
	}

	public void setMnuCheckedBt(Boolean mnuCheckedBt) {
		this.mnuCheckedBt = mnuCheckedBt;
	}


	@Column(name="mnu_checkmark_bt")
	public Boolean getMnuCheckmarkBt() {
		return this.mnuCheckmarkBt;
	}

	public void setMnuCheckmarkBt(Boolean mnuCheckmarkBt) {
		this.mnuCheckmarkBt = mnuCheckmarkBt;
	}


	@Column(name="mnu_description_ch", nullable=false, length=64)
	public String getMnuDescriptionCh() {
		return this.mnuDescriptionCh;
	}

	public void setMnuDescriptionCh(String mnuDescriptionCh) {
		this.mnuDescriptionCh = mnuDescriptionCh;
	}


	@Column(name="mnu_disabled_bt")
	public Boolean getMnuDisabledBt() {
		return this.mnuDisabledBt;
	}

	public void setMnuDisabledBt(Boolean mnuDisabledBt) {
		this.mnuDisabledBt = mnuDisabledBt;
	}


	@Column(name="mnu_separator_before_bt")
	public Boolean getMnuSeparatorBeforeBt() {
		return this.mnuSeparatorBeforeBt;
	}

	public void setMnuSeparatorBeforeBt(Boolean mnuSeparatorBeforeBt) {
		this.mnuSeparatorBeforeBt = mnuSeparatorBeforeBt;
	}


	@Column(name="mnu_sequence_in", nullable=false)
	public Integer getMnuSequenceIn() {
		return this.mnuSequenceIn;
	}

	public void setMnuSequenceIn(Integer mnuSequenceIn) {
		this.mnuSequenceIn = mnuSequenceIn;
	}


	@Column(name="mnu_url_ch", length=1024)
	public String getMnuUrlCh() {
		return this.mnuUrlCh;
	}

	public void setMnuUrlCh(String mnuUrlCh) {
		this.mnuUrlCh = mnuUrlCh;
	}


	//bi-directional many-to-one association to Menu
    @ManyToOne
	@JoinColumn(name="mnu_parent_id")
	public Menu getMenu() {
		return this.menu;
	}

	public void setMenu(Menu menu) {
		this.menu = menu;
	}


	//bi-directional many-to-one association to Menu
	@OneToMany(mappedBy="menu")
	public List<Menu> getMenus() {
		return this.menus;
	}

	public void setMenus(List<Menu> menus) {
		this.menus = menus;
	}


	//bi-directional many-to-one association to Media
    @ManyToOne (optional = true)
	@JoinColumn(name="med_id_in")
	public Media getMedia() {
		return this.media;
	}

	public void setMedia(Media media) {
		this.media = media;
	}

}

This is a simple SessionBean, using a remote interface

@Stateless
public class MenuService implements MenuServiceRemote
{

    @PersistenceContext
    private transient EntityManager em;

	@Override
	@SuppressWarnings( "unchecked" )
	public List<Menu> getAll( )
	{
		Query query = getEntityManager( ).createQuery( "SELECT m FROM Menu m ORDER BY m.mnuDescriptionCh" );

		return query.getResultList( );
	}


	private EntityManager getEntityManager ()
	{
		return em;
	}

}

The Remote Interface:


@Remote
public interface MenuServiceRemote {
	List<Menu> getAll ();
}

delete flag offensive retag edit

5 Replies

Sort by » oldest newest

answered 2011-07-19 08:39:05 +0800

cvarona gravatar image cvarona
554 1 6

To the best of my knowledge you cannot inject EJBs into non-managed classes (servlets, filters and the like). As far as I know zk composers cannot be considered managed objects. It means you cannot resort to injection and should rely upon classical jndi lookup instead.

With kind regards

César Varona

link publish delete flag offensive edit

answered 2011-07-19 08:44:16 +0800

marcelodecampos gravatar image marcelodecampos
183

You are completely correct, Mr. Varona. I was wondering if there is any solution other than to use jndi lookup, it is not portable and neither takes advantage of new features injection specification 3.1!
But I appreciate your comment a lot!!!!

link publish delete flag offensive edit

answered 2011-07-19 08:56:41 +0800

cvarona gravatar image cvarona
554 1 6

Jndi lookup is indeed portable, as long as you correctly set up ejb-refs in your web.xml descriptor (taken for granted, as it would be logical, that your composers belong to the same war exhibiting the descriptor and pointing to the zk libraries). If you're completely sure your target jee server is 3.1 compliant you could even use global jndi names.

There are some other options as well
1) define a filter which gets the ejb injected (either at class or method level ) and sets it up into the request attributes
2) the same trick but with a session listener and the user's http session

Of course, depending on the type of bean and how costful it is to instantiate you should exert extra caution. You might as well find neither solution makes sense.

With kind regards

César Varona

link publish delete flag offensive edit

answered 2011-07-19 09:01:47 +0800

marcelodecampos gravatar image marcelodecampos
183

Oh! My Friend! That's hot!!!! Could you show some examples, please?

link publish delete flag offensive edit

answered 2018-02-19 23:54:44 +0800

latzo gravatar image latzo
1

I have an entity named Unites and i have two interfaces, a Remote one for accessing the EJB from a different JVM and a local one. As already said, you cant use the annotation @EJB in your controller because it is not a managed class. What you can do is accessing to it from the jndi.

The Example is done with a Jboss server. The name of the EJB may differ in another container.

package controllers.unites;

import javax.naming.Context; import javax.naming.InitialContext;

import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.select.SelectorComposer; import org.zkoss.zk.ui.select.annotation.Wire; import org.zkoss.zul.ListModel; import org.zkoss.zul.ListModelList; import org.zkoss.zul.Listbox;

import gmao.ejbs.interfaces.UniteEJBRemote; import gmao.entities.Unite;

public class UnitesController extends SelectorComposer<component> {

/**
 * 
 */

private static final long serialVersionUID = 1L;

@Wire
private Listbox unitesListBox;

private Context context;

private ListModel<Unite> unites;

public UniteEJBRemote uniteService ; 


@Override
public void doAfterCompose(Component comp) throws Exception {
    super.doAfterCompose(comp);
    context = new InitialContext();
    try {
        uniteService = (UniteEJBRemote) context.lookup("java:global/GmaoWEB/UniteEJB!gmao.ejbs.interfaces.UniteEJBRemote");
        unites = new ListModelList<>( uniteService.findAll());
        this.setUnites(unites);
        unitesListBox.setModel(unites);
    }
    catch(Exception e) {
        System.out.println(e.getMessage());
    }
}


public ListModel<Unite> getUnites() {
    return unites;
}


public void setUnites(ListModel<Unite> unites) {
    this.unites = unites;
}

}

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2011-07-19 08:26:39 +0800

Seen: 507 times

Last updated: Feb 19 '18

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More