eclipsedependency-injectionglassfishejbapplication-client

Using @EJB injection in an Application Client, both in same EAR


I've searched now for days to find some solution for my, in my opinion not too hard but obviously unsolvable problem.

I have an EAR project containing Some EJB, a web client (works fine) and now I added an Application Client Module.

As everything is in the same project, I thought a simple @EJB injection in the main class of the application client would do. I also tried a JNDI lookup. I use eclipse and glassfish as a server and tried to run the application 1. in eclipse (there my injected bean is just null) and 2. downloaded the client-stub from the glassfish administration and tried to start it with sh appclient -client (or -jar) OmazanClient.jar (and also the other two jars hidden in the client-stub folder). There I get mostly a "ClassNotFoundExeption:Main" like

java.lang.ClassNotFoundException: Main
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at org.glassfish.appclient.client.acc.ACCClassLoader.findClass(ACCClassLoader.java:212)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.glassfish.appclient.client.acc.FacadeLaunchable.getMainClass(FacadeLaunchable.java:262)
at org.glassfish.appclient.client.acc.AppClientContainer.setClient(AppClientContainer.java:324)
at org.glassfish.appclient.client.acc.AppClientContainerBuilder.createContainer(AppClientContainerBuilder.java:185)
at org.glassfish.appclient.client.acc.AppClientContainerBuilder.newContainer(AppClientContainerBuilder.java:172)
at org.glassfish.appclient.client.AppClientFacade.createContainerForAppClientArchiveOrDir(AppClientFacade.java:492)
at org.glassfish.appclient.client.AppClientFacade.createContainer(AppClientFacade.java:454)
at org.glassfish.appclient.client.AppClientFacade.prepareACC(AppClientFacade.java:269)
at org.glassfish.appclient.client.acc.agent.AppClientContainerAgent.premain(AppClientContainerAgent.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:338)

So for the injection, my code looks like:

public class Main {
@EJB (mappedName="ejb/customerBean")
public static CustomerInterface customerBean;
@EJB (mappedName="ejb/productBean")
public static ProductInterface productBean;

public static void main(String[] args) {
    try{
        Main m = new Main();
        m.runDialog();
    }
    catch (Exception e){
        e.printStackTrace();
    }

}

/* (non-Java-doc)
 * @see java.lang.Object#Object()
 */
public Main() {
    super();

}
private void runDialog() throws Exception{
    System.out.println("Test");
    List<ProductDTO> productList = productBean.getAllProducts();

...

My remote interface looks like this:

@Remote
public interface ProductInterface {

public int addProduct(String productName);
public void deleteProduct(int prodid);
public void updateProduct(int prodid, String newName);
List<ProductDTO> getAllProducts();

...

My implementation is this:

/**
 * Session Bean implementation productInterface
 *  */
@Stateless(mappedName="ejb/productBean")
@LocalBean
@WebService
public class ProductBean implements ProductInterface {

@EJB ProductEAO eao;
@EJB Conversion conv;

/**
 * Default constructor. 
 */
public ProductBean() {
    // TODO Auto-generated constructor stub
}

@Override
public int addProduct(String prodName) {
    return eao.addProduct(prodName);
}

@Override
public List<ProductDTO> getAllProducts() {

         List<ProductDTO> result = new ArrayList<ProductDTO>();
         List<Product> allProducts = eao.allProducts();
            for (Product pr : allProducts) {
               ProductDTO ci = conv.fromProduct(pr);
                result.add(ci);
            }
            return result;

}

... and so on (all methods required by the interface are implemented, just try to keep it shorter here)

and the MANIFEST.MF is just

Manifest-Version: 1.0
Main-Class: Main

I've tried a lot like JNDI lookup, giving the bean names (see example) etc. But either the interface is not found (lookup) or the bean simply null.

How ever I am also not quite sure how to run the application client. I thought glassfishs appclient is the right starting point? It shall be a console-interaction so no swing components or anything similar.

Now I'd be thankful for any suggestions what I might have missed.

Cheers :)


Found a solution. Somehow, JNDI works now. Another problem was that my db query returned an Object and not primitive value or string - this caused a buffer error.

However, I am still confused on how to export an run an application client correctly. Maybe someone has an idea?!


Solution

  • There is a good example here: Create and Run a JEE6 Client Application with Netbeans 6.8 and Glassfish V3 - Part 2: Enhancing and Deploying the Application. It is a few years old, but it does give a pretty good overview.