Friday, April 13, 2012

ADF 11g: Using Application Module outside ADF Application context

Earlier this week, I had to refactor an existing project, and extract some functionality. The goal was that this code could run outside of our Weblogic server, in a crontab job. So I created a new project, containing a class with a main method. The original code was based on Business Components, so I wanted to use this Oracle ADF specific technology as well.

After all the extraction was done, I created a JAR file of my new project and tried to run my main class. The fist problem I encountered was not having all the necessary JARs on my classpath. Therefor, I created a batch-script (could be Unix as well, but I was working in a Windows environment), setting all necessary JARs on my classpath and launching my main method

set JAVA_HOME=C:\Oracle\Middleware\jdk160_18\jre

set PATH=%JAVA_HOME%\bin;%PATH%
set CLASSPATH= YOUR_CLASSPATH

java -classpath %CLASSPATH% my.MainClass


Where YOUR_CLASSPATH is a semicolon-seperated list of all JARs you need. Now the code would compile! But then I ran into the next issue: creating an application module.

I used the default way of creating an Application Module, ie. Configuration.createRootApplicationModule(). While this works inside an ADF application, running a JAR standalone does not provide you with enough context. So I tried a new approach, and manually initialized a context:

String jdbcURL = "jdbc:oracle:thin:@HOST:PORT:SID";

Hashtable env = new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY, JboContext.JBO_CONTEXT_FACTORY);
env.put(JboContext.DEPLOY_PLATFORM, JboContext.PLATFORM_LOCAL);

Context ic = new InitialContext(env);


But of course, creating a Context isn't enough to use the Application Module. We need to create that as well, and I did that in the following manner:

// 'defName' is the JNDI name for the application module
// definition from which the root application module is to
// be created
String defName = "my.AppModule";

ApplicationModuleHome home = (ApplicationModuleHome)ic.lookup(defName);
ApplicationModule = (ApplicationModule)home.create();
mbApplicationModule.getTransaction().connect(jdbcURL, dbUser, dbPassword);


DefName is the JNDI name of your application module. This can be found in bc4j.xcfg. Now we can use the ApplicationModule just like we would in an ADF Application context!