Developing applications with Oracle WLS

The WebLogic Server complete implementation of the Java EE 6.0 specification provides a standard set of APIs for creating distributed Java applications using a wide variety of services (such as databases, messaging services, and connections to external enterprise systems). It also supports the Spring Framework, a programming model for Java applications which provides an alternative to many aspects of the Java EE model.

Although the focus of this book is not on the development of applications, we will guide you through a set of topics which are important to know if you want to develop fully portable Java EE applications or simply if you want to kick-start your first Oracle WLS project.

  • The first part of this chapter covers the installation of a development environment which is an Eclipse on steroids, specifically designed for Oracle WLS.
  • In the second part we will learn some peculiar development features related to the JPA and JNDI API which are essentials when porting applications from other application servers to the WLS and vice versa.
  • In the last block, we will learn how to create shared libraries which can expand the default core server libraries.

Installing a development IDE for Oracle WLS

There are several alternatives for developing applications on Oracle WLS: in this recipe we will show how to download and install the Oracle Enterprise Pack for Eclipse (OEPE) which is an Eclipse based environment which contains all the required plugins for developing apps with Oracle WLS.

Oracle Enterprise Pack for Eclipse (OEPE) is installed out of the box in your distribution if you have installed it using the 32 bit Full Installer option.

In order to install the Oracle Enterprise Pack for Eclipse (OEPE),follow these simple steps:

  1. Move to the download page at:  http://www.oracle.com/technetwork/developer-tools/eclipse/downloads/index.html
  2. Download Oracle Enterprise Pack for Eclipse Standalone Installers suited for your OS.

The Oracle Enterprise Pack for Eclipse Standalone installers includes a preconfigured version of Eclipse and the OEPE plugins. Installing OEPE just requires unzipping it to a folder of your choice. Once done with it, start Eclipse by running the eclipse (eclipse.exe for Windows) command.

The first thing we will need to do is defining a new WebLogic Server. This can be achieved from the Eclipse File menu, by selecting New | Server:

Choose the latest stable release and, in the next screen, select your WebLogic home and Java home:

Click on Next. In the following screen, point to your Oracle WLS Domain directory:

Click Finish and verify that the Oracle WebLogic Server has been included in the Server Tab:


 

Developing JPA applications with Oracle WLS

Developing JPA applications with Oracle WLS is not different from other Java EE 6 compliant application servers. The only difference consists in the persistence provider, which is different from the other application server’s providers discussed in this book.

Oracle TopLink is the default persistence provider in WebLogic Server 12c. It is a comprehensive standards-based object-persistence and object-transformation framework that provides APIs, schemas and run-time services for the persistence layer of an application.

The core component of TopLink is the EclipseLink project's produced libraries and utilities. EclipseLink is the open source implementation of the development framework and the runtime provided in TopLink.

Here’s a sample persistence.xml which references a datasource named “jdbc/OracleDS”:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">

    <persistence-unit name="persistenceUnit">

        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

        <jta-data-source>jdbc/OracleDS</jta-data-source>

        <class>com.model.Property</class>

    </persistence-unit>

</persistence>

Configuring EclipseLink’s shared cache

By default, EclipseLink uses a shared object cache to cache objects read from the database, in order to avoid repeated database access. This is pretty like the Hibernate second level cache feature. One important difference with Hibernate JPA Provider (discussed in the JBoss EAP Part) is that support for second level cache in EclipseLink is turned on by default; thus entities which are read are L2 cached. When using Hibernate, on the other hand, just the first level cache is enabled by default.

 

One more difference is that EclipseLink caches actual entities in L2, while Hibernate caches just the entity id and the state in L2.

You can disable the L2 default behavior in several ways, for example by adding in your persistence.xml the following property:

<property name="eclipselink.cache.shared.default" value="false"/>

Or use the JPA 2.0 persistence unit element in your persistence.xml:

<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

This will require tagging your Entities with Cacheable = false in order to disable caching:

@Entity

@Cacheable(false)

public class Bean {   ...

}

Referencing resources in the JNDI tree

One of the key issues when porting Java EE applications between different application servers is the different JNDI naming policy used. This is a frequent issue when your applications reference Java EE resources (such as data sources, JMS objects, etc) by its JNDI name. For example, the following code introduces a portability issue, since it hardcodes the JNDI name of a resource in it:

public class TestEJB {

   @Resource(mappedName="jdbc/MyDataSource")

   private DataSource datasource;

}

One way to reduce the impact on portability, is introducing the resource name as an alias for the JNDI name which will be declared in XML deployment descriptors. In our case, here’s how to improve the above example EJB:

public class TestEJB {

   @Resource(name="MyDataSource")

   private DataSource datasource;

}

Then, in your ejb-jar.xml, you can declare the actual JNDI binding to your data source as follows:

<ejb-jar>

  <display-name>SampleJNDI</display-name>

     <enterprise-beans>

      <session>

         <ejb-name>TestEJB</ejb-name>

         <resource-ref>

            <res-ref-name>MyDataSource</res-ref-name>

            <lookup-name>jdbc/MyDataSource</lookup-name>

         </resource-ref> 

      </session>

   </enterprise-beans>

</ejb-jar>

This way, you can port your applications between different application servers by simply changing the ejb-jar.xml.

So far we did some improvements in portability; yet it remains the annoyance that you have to modify your deliverables when porting them to another application server. Luckily, it’s possible to use WLS custom XML descriptors (in our case weblogic-ejb-jar.xml) in order to “shade” the references contained in ejb-jar.xml. Here’s how we can do it:

<wls:weblogic-ejb-jar>

     <wls:weblogic-enterprise-bean>

        <wls:ejb-name>TestEJB</wls:ejb-name>

        <wls:stateless-session-descriptor></wls:stateless-session-descriptor>

         <wls:resource-description>

            <wls:res-ref-name>MyDataSource</wls:res-ref-name>

            <wls:jndi-name>jdbc/MyDataSource</wls:jndi-name>

        </wls:resource-description> 

    </wls:weblogic-enterprise-bean>  

</wls:weblogic-ejb-jar>

This way, you can pack your applications with a custom descriptor which will kick-in just in case you are deploying on WLS.

Can we improve even more our portability? For example, let’s say you don’t want to add at all a reference to your actual resource JNDI name in your application archive. This can be, for example, the case if you are moving your application from a development stage to a production stage, where it’s not granted that you have the same environment (just to mention one option: the database).

The answer is: use deployment plans which are a peculiar feature of WLS that let you override all or part of the application server deployment descriptors (in our case weblogic-ejb-jar.xml). Deployment plans are discussed in detail in Chapter 8, in the recipe “Creating Deployment plans” which includes a follow-up to our example.

Dumping the JNDI tree 

Getting to know the JNDI naming of your resources is essential when you are developing applications. A dump of the JNDI tree can be obtained through the Admin console. Login to console and select the server name you want to inspect from the left hand side.

Under the Configuration > General tab, click on View JNDI tree in order to dump the JNDI tree of the server:


 

Oracle Weblogic JNDI lookup of resources

Looking up a Java EE resource from an application which is running on WLS can be achieved using the standard Java EE API. For example, here’s how you can lookup the Oracle data source we have defined in the data source chapter:

Context context = new InitialContext();

dataSource = (javax.sql.DataSource) context.lookup("jdbc/OracleDS");

Things are a bit different if we need to look up a server resource (e.g. an EJB) from a remote endpoint:

Remote resource lookup

Looking up a remote resource from WLS requires using WLS Initial Context classes; therefore it’s a part of your application which will need some refactoring if you are moving from or to Oracle WLS. Here’s how you can look up the Oracle data source from a remote client:

Hashtable<String, String> h = new Hashtable<String, String>();

h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");

h.put(Context.PROVIDER_URL, "t3://localhost:7001");

h.put(Context.SECURITY_PRINCIPAL, “username”);

h.put(Context.SECURITY_CREDENTIALS, “password”);

 

InitialContext context = new InitialContext(h);

dataSource = (javax.sql.DataSource) context.lookup("jdbc/OracleDS");

Remote EJB lookup

Looking up a remote EJB requires using a special JNDI pattern:

EJB MappedName#package.RemoteBeanName

So, for example, supposing you were to deploy the following Stateless EJB:

package com.sample;

@Stateless(mappedName=”HelloWorld”)

public class HelloWorldBean implements HelloWorld {

. . .

}

Then, on the client side you could use the following lookup JNDI String:

Context ctx = new InitialContext(env);

System.out.println(“Initial Context created”);

helloWorld = (HelloWorld) ctx.lookup(“HelloWorld#com.sample.HelloWorld”);

 

 

How to create a shared library

The shared library feature in WebLogic Server provides an easy way to share one or more different types of JEE modules among multiple Enterprise Applications. You have two main options for sharing a library across your domain applications: you can either drop the library into the DOMAIN_HOME/lib or deploy the application itself as a library.

Deploy the library into the DOMAIN_HOME/lib

The domain library directory (lib) is one mechanism that can be used for adding application libraries to the server classpath. The jars located in this directory will be picked up and added dynamically to the end of the server classpath at server startup. The jars will be ordered lexically in the classpath.

 

It is possible to override the DOMAIN_HOME/lib directory by using the -Dweblogic.ext.dirs system property during startup. This property specifies a list of directories to pick up jars from and dynamically append to the end of the server classpath using java.io.File.pathSeparator as the delimiter between path entries.

Beware that, once you put your libraries in the DOMAIN_HOME/lib directory, you have to restart the server when the jar changes.

Deploying the application as a shared library

The deployment process is discussed in detail in Chapter 8 of this book. Anyway, deploying a new application as shared library requires following a very simple procedure:

  1. Open the Admin Console and click on Deployments. Once in the Deployment Summary screen, click on the Install button.
  2. Browse to your deployments and, once selected, you can opt to install it as an application or as library. Choose: “Install the deployment as a library

Once completed the deployment, you will have a deployment view of your library which resembles the following example:

Referencing the shared library in your applications

Applications can reference shared libraries by adding a library-ref element into the WebLogic custom deployment descriptors. For example, the following entry in the weblogic.xml references the above shared library named SharedLib:

<wls:library-ref>

   <wls:library-name>SharedLib</wls:library-name>

</wls:library-ref>

The main difference from barely adding files to the classpath is that a shared library can actually be a Java EE application. Working with a shared library gives you also more flexibility since you are able to deploy multiple versions of the library and use deployment descriptors to refer to the right version. You can include library specifications in the META-INF/MANIFEST.MF file:

Manifest-Version: 1.0

Specification-Version: 1.0

Implementation-Version: 1.1

Here’s the deployment outcome on the WLS console, when deploying the Shared Library application including the above library specifications:

And here’s how to reference an exact version in your weblogic.xml file:

<wls:library-ref>

   <wls:library-name>SharedLib</wls:library-name>

   <wls:specification-version>1.0</wls:specification-version>

   <wls:implementation-version>1.1</wls:implementation-version>

   <wls:exact-match>true</wls:exact-match>

</wls:library-ref>

Francesco Google+