how to implement EJBTimer (persistant) in Open Liberty

460 views Asked by At

Product name: Open Liberty Product version: 20.0.0.7 Product edition: Open

is it possible to implement persistent ejbtimers on filesystem based default derby DB, using embedded.derby.DB

I installed derby in /tmp/derby, configured server.xml with the following, i don't see any file being created under /tmp when I start the OpenLiberty JVM, what am I missing in this approach?

        <feature>ejbPersistentTimer-3.2</feature>

       <library id="DerbyLib">
            <fileset dir="/tmp/derby/lib" includes="derby.jar"/>
        </library>
        <dataSource id="DefaultDerbyDatasource" jndiName="jdbc/defaultDatasource" statementCacheSize="10" transactional="false">
           <jdbcDriver libraryRef="DerbyLib"/>
           <properties.derby.embedded createDatabase="create" databaseName="/tmp/sample.ejbtimer.db" shutdownDatabase="false"/>
           <containerAuthData user="user1" password="derbyuser" />
        </dataSource>

2

There are 2 answers

4
Gas On

Check this book - http://www.redbooks.ibm.com/abstracts/sg248076.html?Open In chapter "5.2.4 Developing applications using timers" you should find all stuff needed.

UPDATE based on comment:

If you look to the book and to the log it shows:

[INFO ] CNTR4000I: The ITSOTimerApp.war EJB module in the ITSOTimerApp
application is starting.
[INFO ] CNTR0167I: The server is binding the com.ibm.itso.timers.TimerBean
interface of the TimerBean enterprise bean in the ITSOTimerApp.war module of
the ITSOTimerApp application. The binding location is:
java:global/ITSOTimerApp/TimerBean!com.ibm.itso.timers.TimerBean
[INFO ] DSRA8203I: Database product name : Apache Derby
[INFO ] DSRA8204I: Database product version : 10.8.2.3 - (1212722)
[INFO ] DSRA8205I: JDBC driver name : Apache Derby Embedded JDBC Driver
[INFO ] DSRA8206I: JDBC driver version : 10.8.2.3 - (1212722)
[INFO ] CNTR0219I: The server created 1 persistent automatic timer or timers
and 0 non-persistent automatic timer or timers for the ITSOTimerApp.war module.
TimerBean initialized

It creates db 'as needed' so if you dont have any persistent timers beans, the service will not be started nor db created.

Liberty in general follows lazy model and doesn't start unneeded services.

So create sample application and then your DB will be created. There is no need to create database nor connection to database when no one is requesting for it.

0
njr On

In general, it is not advisable to use Derby Embedded database for persistent EJB timers due to limitations of Derby Embedded that all connections use the same class loader (implying the same JVM as well). This means you cannot leverage the failover capability (missedTaskThreshold setting) or even have multiple servers connected to the database at all. If you decide to use a Derby Embedded database, it means that you are limiting yourself to a single server. You can decide for yourself if that is acceptable based on what your needs are.

In the case of the example configuration you gave, it doesn't work because the EJB persistent timers feature in Liberty has no way of knowing that you dataSource, "DefaultDerbyDatasource" with jndiName "jdbc/defaultDatasource" is the data source that it ought to use. Also, it is incorrect to specify transactional="false" on the data source that you want EJB persistent timers to use because EJB persistent timers are transactional in nature.

I assume that what you are intending to do is configure the Java EE default data source and expecting EJB persistent timers to use it. That approach will work, except that you'll need to configure the Java EE default data source, you need to specify the id as "DefaultDataSource".

Here is an example that switches your configured data source to the Java EE default data source and removes the transactional="false" config,

  <library id="DerbyLib">
    <fileset dir="/tmp/derby/lib" includes="derby.jar"/>
  </library>
  <dataSource id="DefaultDataSource" jndiName="jdbc/defaultDatasource" statementCacheSize="10">
    <jdbcDriver libraryRef="DerbyLib"/>
    <properties.derby.embedded createDatabase="create" databaseName="/tmp/sample.ejbtimer.db" shutdownDatabase="false"/>
    <containerAuthData user="user1" password="derbyuser" />
  </dataSource>

By default, the EJB persistent timers feature should create database tables once the application runs and the EJB module is used. However, you may be able to verify the configuration prior to that point by running the ddlgen utility (after correcting the configuration as above)

https://www.ibm.com/docs/en/was-liberty/base?topic=line-running-ddlgen-utility

which gives you the opportunity to see the DDL that it will use and optionally to run it manually (which is useful if you turned off automatic table creation via <databaseStore id="defaultDatabaseStore" createTables="false"/> )