Hot questions for Using Enterprise JavaBeans in websphere liberty

Question:

I need to create a EJB timer (using @Schedule), but have read that this is not supported in a Websphere Liberty profile? According to a previously posted question on StackOverflow, it wasn't supported as of 08/2013:

Java EE-Timer / @Schedule in Websphere Liberty Profile

Currently when I try to use the @Schedule annotation I get the following exception:

[ERROR   ] CWWKZ0004E: An exception occurred while starting the application 
<EAR>. The exception message was: com.ibm.ws.container.service.state.StateChangeException: com.ibm.ws.exception.RuntimeError: java.lang.IllegalStateException: The ejbPersistentTimer feature is enabled, but the defaultEJBPersistentTimerExecutor persistent executor cannot be resolved. The most likely cause is that the DefaultDataSource datasource has not been configured. Persistent EJB timers require a datasource configuration for persistence.

The problem is I DO have a default data source defined. Here is the EJB code - it is very simple because I was just trying to test out timer functionality:

import javax.ejb.Schedule;
import javax.ejb.Stateless;

@Stateless
public class TimerBean {

    @Schedule(second="*/10", persistent=false)
    public void doSomething() {
        System.out.println("Hello World!");
    }

}

Update:

I changed my dataSource id to "DefaultDataSource", and now I am getting a different exceptions in my console when starting the server:

[ERROR   ] WTRN0078E: An attempt by the transaction manager to call start on a transactional resource has resulted in an error. The error code was XAER_RMERR. The exception stack trace follows: javax.transaction.xa.XAException: com.microsoft.sqlserver.jdbc.SQLServerException: Could not find stored procedure 'master..xp_sqljdbc_xa_start'.
at com.microsoft.sqlserver.jdbc.SQLServerXAResource.DTC_XA_Interface(SQLServerXAResource.java:647)
at com.microsoft.sqlserver.jdbc.SQLServerXAResource.start(SQLServerXAResource.java:679)
at com.ibm.ws.rsadapter.spi.WSRdbXaResourceImpl.start(WSRdbXaResourceImpl.java:1189)
at [internal classes]

[ERROR   ] J2CA0030E: Method enlist caught javax.transaction.SystemException: XAResource start association error:XAER_RMERR
at com.ibm.tx.jta.impl.RegisteredResources.startRes(RegisteredResources.java:1048)
at [internal classes]
Caused by: javax.transaction.xa.XAException: com.microsoft.sqlserver.jdbc.SQLServerException: Could not find stored procedure 'master..xp_sqljdbc_xa_start'.
at com.microsoft.sqlserver.jdbc.SQLServerXAResource.DTC_XA_Interface(SQLServerXAResource.java:647)
at com.microsoft.sqlserver.jdbc.SQLServerXAResource.start(SQLServerXAResource.java:679)

Is this the result of the timer attempting to write to my SQL DB, and if so, is there a way to avoid this?


Answer:

It looks like you have the ejbPersistentTimer-3.2 feature turned on, since you are getting exceptions for having a DataSource configured.

If you are going to use ejbPersistentTimer-3.2 (or ejb-3.2 which includes it) you need to configure a datasource to be used for persistent timers.

Since you don't need persistent EJB timers (because you have persistent=false in your @Schedule annotation) you can remove the ejbPersistentTimer-3.2 feature and just use the ejbLite-3.2 feature (which doesn't include the persistent timer feature).

The ejbLite-3.2 feature includes support for non-persistent timers, and you won't need to worry about configuring a DataSource.

Question:

I have to migrate a software project from Websphere Application Server v8 (WAS8) to Webphere Liberty Base v17 (WL17) and ran into troubles with the EJB's. E.g. there is the following EJB:

@Stateless
@Local(MyUserServiceLocal.class)
public class MyUserServiceBean implements MyUserServiceLocal {

    @EJB
    private OtherServiceLocal otherServiceLocal;

    @Resource
    private SessionContext context;

    public MyUserServiceBean() {
    }

    public String getUserEmail() {...}

    public String getUserDataId() throws ServiceException {...}
    ...
}

With the corresponding local interface:

@Local
public interface MyUserServiceLocal {

    public String getUserEmail();

    public String getUserDataId() throws ServiceException;
    ...
}

There are a lot more EJB's following a similar implementation scheme.

The project builds fine, all facets in all Eclipse projects are set correctly and maven creates a fresh and deployble EAR file. But when I visit the applications default page the following nested exception is thrown: The MyUserServiceBean bean class for the MyApplication#MyUserServiceEjb.jar#MyUserServiceBean bean does not have a public constructor that does not take parameters.

I currently can not imagine why this exception is thrown by WL17. The feature configuration of my WL looks like this:

<featureManager>
    <feature>appSecurity-2.0</feature>
    <feature>cdi-1.2</feature>
    <feature>distributedMap-1.0</feature>
    <feature>ejbLite-3.2</feature>
    <feature>ejb-3.2</feature>
    <feature>jacc-1.5</feature>
    <feature>jaxrs-2.0</feature>
    <feature>jaxws-2.2</feature>
    <feature>jca-1.7</feature>
    <feature>jdbc-4.1</feature>
    <feature>jndi-1.0</feature>
    <feature>jpa-2.1</feature>
    <feature>jsf-2.2</feature>
    <feature>jsp-2.3</feature>
    <feature>ldapRegistry-3.0</feature>
    <feature>mdb-3.2</feature>
    <feature>servlet-3.1</feature>
    <feature>ssl-1.0</feature>
    <feature>webCache-1.0</feature>
    <feature>wmqJmsClient-2.0</feature>
</featureManager>

I is the same when I do not load the mdb or the ejb feature. Is there any idea how to solve this problem? I have googled a lot and reade half of the internet but didn't get an answer or an idea how to solve this problem.


Answer:

I found the problem of the EJB. One of the interface methods was declared to throw a javax.xml.rpc.ServiceException. I do not understand why this should be a problem, but after removing the throws declaration in the interface and the implementation class WL 17 was able to initialize the bean correctly.

Question:

I have a EJB with a remote interface that I want to access from a client. I have difficulties to build the string for the JNDI lookup. Is there a command line tool which shows all register enterprise beans in the naming service? Or can I see this in a log file?

The JNDI name should look like this:

corbaname:localhost:2809#ejb/global/MyApp/MyModule/EJBName!full.package.remote.interface.Name

I’m also not really sure if my app and module name in the string is correct.


Answer:

As far as I know there is no way to dump the JNDI namespace on WebSphere Liberty (there is a way to do this in WebSphere traditional).

The easiest way to check what JNDI name your EJBs are registered at, is to check the messages.log file. In the messages.log file you should see some CNTR0167I messages which indicate where the server has bound your EJBs. The messages.log file can be found in ${server.config.dir}/logs/messages.log.

Example EJB binding message:

CNTR0167I: The server is binding the com.example.DatabaseBean interface of the DatabaseBean enterprise bean in the TestProject.war module of the TestProject application. The binding location is: java:global/TestProject/DatabaseBean!com.example.DatabaseBean

For more info, check out the IBM doc: Using enterprise JavaBeans with remote interfaces on Liberty