EJBUtil classes, februari 2007

Download, Java docs

My homepage and mapping software for your phone

This document contains a short introduction to the EJBUtil class library.

The class library contains classes for:

It has been tested with JBoss 3.2.x and 4.0.x and SAP-WAS 6.40.


Transfer files over a JMS based ESB bus like ActiveMQ

JMSStream allows sending large streams (files) over a JMS provider based ESB bus, e.g. based on ActiveMQ.

The JMSStream can be used as a library in Java programs, but also as a command line tool to send and retrieve files from a JMS provider.

The program offers the following features:

To use the program you'll have to create a script file first, e.g. jmsstream or jmsstream.bat. I'll give the unix script jmsstream as an example:
#! /bin/sh
CP=$HOME/JmsStream/ejbutil.jar
CP=$CP:$HOME/JmsStream/apache-activemq-4.1.0-incubator.jar
CP=$CP:$HOME/JmsStream
exec java -cp $CP eu.v7f.jms.JMSStream "$@"
and Windows jmsstream.bat:
@echo off
set HOME=c:\JmsStream
set CP=%HOME%/JmsStream/ejbutil.jar
set CP=%CP%;%HOME%/JmsStream/apache-activemq-4.1.0-incubator.jar
set CP=%CP%;%HOME%/JmsStream
java -cp %CP% eu.v7f.jms.JMSStream %1 %2 %3 %4 %5 %6 %7 %8 %9
Note that you'll have to place a jndi.properties file in the $HOME/JmsStream directory so that the program can find your JMS provider. My file looks like this:
# JBoss properties
#java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
#java.naming.provider.url=jnp://localhost:1099
#java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

# ActiveMQ Properties
java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory
brokerURL=tcp://localhost:61616&jms.prefetchPolicy.all=1
java.naming.provider.url=tcp://localhost:61616
topic.topic/BigDurable=BigDurable
topic.topic/BigFiles=BigFiles
That's it. You can now send files over ActiveMQ. Type the following command in a window:
jmsstream --topic topic/BigFiles --dest demo --prefix ./
This will start the file receiver. Any received files are prefixed so that they will be placed in the current directory.

Now send a file by typing in another window:

jmsstream --topic topic/BigFiles --dest demo /vmlinuz
The file vmlinuz will emerge in the directory where the jmsstream receiver is running. As long as the file is not fully received it has the extension .part. Also note that you can run multiple receivers and each will receive a copy of the file!

Now stop the receiver with CTRL-C and rerun the send commando. After 10 seconds (settable with --timeout 5 to 5 seconds) you'll see:

java.lang.Exception: JMSStream transport timed out
        at eu.v7f.jms.JMSStream.send(JMSStream.java:165)
        at eu.v7f.jms.JMSStream.main(JMSStream.java:331)
The standard mode of transport requires that a receiver is running. When you want really reliable transport you can use a durable topic for transport.

Now start the receiver with the --ident option and --verbose:

jmsstream --topic topic/BigDurable --ident MyName --dest demo --prefix ./ --verbose
and terminate it with CTRL-C. This creates a subscription with the name MyName. Than send the file again:
jmsstream --topic topic/BigFiles --dest demo --timeout 0 /vmlinuz
The --timeout 0 parameters signals that JmsStream should not wait for a reply from a receiver. The file is now stored in ActimeMQ.

Now run the receive command again:

jmsstream --topic topic/BigDurable --ident MyName --dest demo --prefix ./ --verbose
and you'll see that the file is retrieved in 7 chunks (each 256000 bytes) from ActiveMQ.
New dest: .//vmlinuz
Request: 1
Request: 2
Request: 3
Request: 4
Request: 5
Request: 6
Request: 7
Done: .//vmlinuz
Note that JMSStream will also recover from partially received files when using durable topics. You can interrupt the receiver halfway and the transfer will resume the next time the receiver is started. The file transfers are really atomic.

You can monitor the transfers for all destinations by starting jmsstream with the --monitor option:

jmsstream --topic topic/BigDurable --monitor

INFO: Start: test_stream: vmlinuz
13-feb-2007 6:48:30 eu.v7f.jms.JMSStream monitor
INFO: End:   test_stream: vmlinuz Size: 1636700
13-feb-2007 6:48:33 eu.v7f.jms.JMSStream monitor


Efficiently using XDoclet generated SessionBean Home interfaces

Example:

YourSBLocal pers;
pers = (YourSBLocal) EjbUtil.create(YourSBLocalHome.class);

Notes:

The Home interface must be Xdoclet generated. You can use remote and local interfaces.

Home interfaces are cached (by default for 60 seconds). See the Javadoc for details.

Caching can be disabled by specifying a timeout of 0 milliseconds.
Note that caching should not be used when using JBoss failover and/or load-balancing features.

The efficiency gain of caching Home-interfaces depends on the J2EE server used.


Using Hibernate in SessionBean facades/proxies

Example:

public class PersonSBBean implements SessionBean {

	public PersonSBBean() {
		super();
	}

	public void ejbActivate() throws EJBException, RemoteException {
	}

	public void ejbPassivate() throws EJBException, RemoteException {
	}

	public void ejbRemove() throws EJBException, RemoteException {
	}

	private SessionContext context;

	public void setSessionContext(SessionContext ctx) throws EJBException,
			RemoteException {
		context = ctx;
	}

	public void ejbCreate() throws CreateException {
	}


	// singleton
	static EjbHibernateUtil ehu= new EjbHibernateUtil("person.cfg.xml");
	

	/**
	 * Example of business method which is a Hibernate proxy
	 * 
	 * @ejb.interface-method view-type = "both"
	 */
	public Person new(Person p) throws
			CreateException {
		Session session = ehu.getSession(context);
		try {
			// calls the business logic:
			p = Person.new(session, p);
		} catch (RuntimeException e) {
			ehu.rollback();
			throw e;
		} finally {
			ehu.closeSession();
		}
		return p;
	}
}

Calling J2EE SessionBeans from C++ programs

FromC2J implements calling SessionBean methods from C++.

You can call methods with a String or a String[] signature.

Examples:

	/**
	 * Business method for testing FromC2J
	 * 
	 * @ejb.interface-method view-type = "remote"
	 */
	public String echo(String in) {
		return "echo: " + in;
	}

	/**
	 * Business method for testing FromC2J
	 * 
	 * @ejb.interface-method view-type = "remote"
	 */
	public String concat(String[] in) {
		System.err.println(in[0]);
		return "concat: " + in[0] + "+" + in[1];
	}

You should wrap existing methods with String wrappers. Passing XML in/out is a good option.

In the c-src directory you'll find an example main.cc program and a Makefile. The best approach is to adapt the example program and to test your environment by calling echo() or concat() methods in your own SessionBeans.

See the Makefile in the c-src directory for compile/link options and the fromc2j.h file for details.