EJB programming & troubleshooting: WebLogic won't marshal classes unreferenced from the bean API???

  1. I am trying to create an EJB that takes a single java.io.Serializable argument. Then I call this method with an instance of some UserData class from a client. The UserData class is in the deployment jar file; however, I get a ClassNotFound exception when WebLogic tries to unmarshal the argument from the input stream.

    Now, the weird part. If I add a dummy method in the bean that returns (or, after service pack 3, accepts) an explicit argument of the UserData type, then everything works!

    Why, you ask, do I declare the argument as Serializable, and not UserData. There are two reasons. First would be, if I wanted to pass one of several child classes to a method that is declared to accept a common parent. Second, which happens to be my real case, is that I really want to pass a Vector of objects, and since there is no reasonable way I can declare that the objects are of my UserData type, I have this problem. Maybe, we can solve this by adding C++ templates to Java - that would make Sun happy ;)

    The situation is made worse by the fact that if my UserData object happens to contain a NestedData field, I also have to declare NestedData in a dummy method, to make WebLogic pull that class in.

    Finally, the J2EE SDK app server (Sun's) eats this with no problems. I think that WebLogic folks either have a bug, or they came up with a very strange feature. Does everyone agree that a well-behaved app server should be able to marshal serializable classes loaded from the deployment jar, even if they are not statically referenced from the bean interface? It's in the jar, load it!

    - Gene Florintsev
    gene at florintsev dot com

  2. The UserData class is in the deployment jar file; however, >I get a ClassNotFound exception when WebLogic tries to >unmarshal the argument from the input stream.

       Take the case of code below:

    public void setContactProfileProxy(ContactProfileProxy contactprofile){

    contactid = contactprofile.contactid;
    interfacename = contactprofile.interfacename;
    busdescription = contactprofile.busdescription;


    Here ContactProfileProxy is simple class that implements Serializable. I am not facing any problem you mentioned.

  3. Hi,
    I must not have made myself clear.

    The bean method is declared like this:

    public void test (Serializable arg);

    The client calls it like this:

    bean.test (new UserData ());

    If I declare the method as:

    public void test (UserData arg);

    then everything works, because WebLogic's bean class loader recognizes UserData as an interface class and exports it to the parent class loader. But I think this behavior is inconsistent with the EJB spec.

    - Gene

  4. If you want to pass a list of User objects then you should be able to pass instance of the various container classes java provides like List and Vector. Your user objects should be element of this container classs.

    If you are expecting an argument serialazable just because you wantr to have a common parent. why not have a commom parent . for eg: an inteface with no method.
    public interface Tag
    public class A implements Tag
    public class B implements Tag
    In the bean you can have a method test(Tag)
  5. Hari,
    this is exactly what does not work! If I do what you propose, and no method in the bean's API explicitly returns or accepts A or B, then I get a ClassNotFoundException when an instance of A or B is being unmarshalled from the input stream - see for yourself.
    - Gene
  6. Actually what is happing is that Weblogic needs the classes loaded into its classpath and for some reason Weblogic doesn't really add your bean.jar to the weblogic classpath even when you set it in the property file. Try this, put the class in question into /myserver/server_classes. This is in the weblogic classpath. Then run the startweblogic script and I think you will find it works. If you have classloading problems in welogic it is almost always because you haven't put it in the weblogic classpath and the weblogic classloader doesn't find it.
  7. David,
    thank you for your advice. I know about this trick, and things do start to work if I use it. But I think that this contradicts to the spirit of the EJB spec, which is that I sholuld be able to package my app in a single deployment jar file. Would you agree with that?

    So far, the workaround I will use is adding dummy methods to the bean, pulling the classes into the interface class loader.

    - Gene