Archive

Posts Tagged ‘ejb3’

Extending EJB3 Objects

December 2, 2009 Leave a comment

Small and fast tip.

In order to be able to extend an EJB Entity object (be it a main object or a primary key embbedable) you need to write the MappedSuperclass anotation in the super class.

The following is taken from hibernate documentation :

@MappedSuperclass
public class BaseEntity {
    @Basic
    @Temporal(TemporalType.TIMESTAMP)
    public Date getLastUpdate() { ... }
    public String getLastUpdater() { ... }
    ...
}

@Entity class Order extends BaseEntity {
    @Id public Integer getId() { ... }
    ...
}

Some other notes taken from the documentation :

  • Properties from superclasses not mapped as @MappedSuperclass are ignored;
  • The access type (field or methods), is inherited from the root entity, unless you use the Hibernate annotation @AccessType;
  • Any class in the hierarchy non annotated with @MappedSuperclass nor @Entity will be ignored.

Read the documentation to understand it fully : http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html chapter 2.2.4.4

Please note that even though i’ve used the Hibernate documentation as a reference this anotation also exists in javax.persistence so it can be used with JPA

Advertisements
Categories: ejb3, java Tags: , ,

NullPointerException calling RemoteBusinessInterface

June 25, 2009 1 comment

I recently ran into the following issue while trying to JUnit myself into an EJB3 service running inside my Weblogic 10.3 :

java.lang.NullPointerException
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.getTargetMethod(RemoteBusinessIntfProxy.java:162)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:53)
at $Proxy0.myServiceCall(Unknown Source)
at com.siemens.enginedevelopment.MyTest.testMyTest(MyTest.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

There was no apparent reason for this to happen, the service was running well when called from inside the weblogic instance, and JUnit calls made on other workstations, with older workspaces, still worked without a hitch.
I did some digging on the interwebz, and managed to find the solution to my problems. Seems there is a bug in Weblogic 10R3. All you need to make this work is force your IDE to run wlappc on your EJB Service classes, this will generate appropriate stubs and the problem will go away.

The solution can be found here. I’m transcribing it for posterity:

All right, after having spent two days on this issue, I finally found out that in order to be able to use generics in EJB with WebLogic, one needs to have appc generated stubs on the client side. Doing that is not trivial in Eclipse (OEPE) but adding an ant script like the following

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”no”?>
<project basedir=”.” default=”build-project” name=”ww204-ejb”>
<property name=”jpa.project” value=”../ww204-jpa”/>
<target name=”build-project”>
<echo message=”${ant.project.name}: ${ant.file}” />
<taskdef name=”wlappc” classname=”weblogic.ant.taskdefs.j2ee.Appc”/>
<wlappc source=”build/classes” forceGeneration=”true” verbose=”true” deprecation=”true”>
<classpath>
<pathelement location=”${jpa.project}/build/classes”/>
</classpath>
</wlappc>
</target>
</project>

which generates the appc stubs in the EJB Project’s binary output directory and using this directory in the remote client CLASSPATH solves the problem. This is probably not regular as there is no any other application server having such a requirement but, if you want to use EJB with WebLogic and if, as myself, you think it would be too stupide not to use generics, you need to do that. You may continue using the WTP build facilities of Eclipse (OEPE) but you need to add to your EJB Project an ant builder which runs the script above. That’s a pain, I know, but it seems to be the only way to decently do EJB/JPA with WebLogic. That’s crazy that I needed to spend two days to come to something which is probably already known since longtime. So, I hope that, as oposed to myself, other people will be luckyer and beneficiate of this post.

Kind regards,

Nicolas

Categories: ejb3, java Tags: , ,

EJB3 JNDI

March 24, 2009 Leave a comment

EJB3 follow a strange naming convention by default. I have yet to find a way to define how this can be set using annotations.

Lets say you define the following bean:

package test.mybeans.service;

@Stateless(name=”TestServiceBean”, mappedName=”TestService”)

@Remote(TestService.class)

public class TestServiceBean implements TestService

This creates a stateless bean implementation of the interface TestService, this is the remote interface you will use to call the services.

When you deploy this bean, if you check your containers jndi tree, it will have the following name

TestService#test.mybeans.service.TestService

In order to acess the remote interface you will need to get the bean from your context: you can use something like this:

ctx.lookup(“TestService#test.mybeans.service.TestService”);

This will return a proxy object of TestService which will allow you to access your service calls. Note: ctx will be your initial context(the context where you have your service running)

I use the following methods to make this access easier:

public static synchronized Object getSessionInterface(Class interfaceClass){
    try{
        InitialContext ctx = new InitialContext();
        return ctx.lookup(getSessionJndiName(interfaceClass));
} catch (NamingException e) { log.error("Error Obtaining sessionbean for " +interfaceClass, e); return null; } }
public static synchronized String getSessionJndiName(Class interfaceClass){ return interfaceClass.getSimpleName() + "#" + interfaceClass.getName();
}
Note: Mind that the creation of your InitialContext will be diferent if for instance you are running your services in a diferent server.
Categories: ejb3 Tags: , , ,