Monday, January 31, 2011

Create JPA Entities from Tables with JDeveloper

This article will show you how to create Java Persistence Architecture (JPA) entities from relational tables with JDeveloper.

Java Persistence

The Java Persistence provides an object relational mapping facility to Java developers for managing relational data in Java applications. Java persistence consists of three areas:
  1. Java Persistence API
  2. Object-relational mapping (ORM) metadata
  3. Query language

Java Persistence API

The Java Persistence API (JPA) is the Java specification that provides a standard to ORM in Java. JPA is part of the EJB specification and JEE platform, but can also be used in JSE.

The key object involved in the mapping is Entity. A JPA entity is a lightweight Java class whose state is typically persisted to a table in a relational database. Instances of such an entity correspond to individual rows in the table.

Entities typically have relationships with other entities, and these relationships are expressed through object/relational metadata. Object/relational metadata can be specified directly in the entity class file by using annotations, or in a separate XML descriptor file distributed with the application.

A JPA entity is a Java class meets the following rules:
  • It is a plain old Java object (POJO) that does not have to implement any particular interface (except java.io.Serializable; see explanation below) or extend a special class.
  • The class must not be declared final, and no methods or persistent instance variables must be declared final.
  • The entity class must have a no-argument constructor that is public or protected. The entity class can have other constructors as well.
  • The class must either be annotated with the @Entity annotation or specified in the orm.xml JPA mapping file.
  • The class must define an attribute that is used to identify in an unambiguous way an instance of that class (it corresponds to the primary key in the mapped relational table).
  • Both abstract and concrete classes can be entities, and entities can extend non-entity classes (this is a significant limitation with EJB 2.x).

Using JDeveloper, you can create JPA entities bottom-up from relational tables. JPA entities that implement the java.io.Serializable interface can also be transferred on the wire (for example, they can be serialized over RMI-IIOP).

An Example of JPA Entity

package oracle.apps;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;

@Entity
@NamedQueries({
@NamedQuery(name = "Dept.findAll", query = "select o from Dept o")
})
public class Dept
implements Serializable
{
@Column(nullable = false)
@Id
private Long deptno;
@Column(length = 14)
private String dname;
@Column(length = 13)
private String loc;

public Dept()
{
}
public Dept(Long deptno, String dname, String loc)
{
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
public Long getDeptno()
{
return deptno;
}
public void setDeptno(Long deptno)
{
this.deptno = deptno;
}
public String getDname()
{
return dname;
}
public void setDname(String dname)
{
this.dname = dname;
}
public String getLoc()
{
return loc;
}
public void setLoc(String loc)
{
this.loc = loc;
}
}
The Dept class above is conforming to the JavaBean specification and is mapped through the package javax.persistence annotations. For example,
  • @Entity —identifies a Java class as an entity
  • @Table —provides information related to which table and schema the entity corresponds to
  • @Id —is used to identify the property that corresponds to the primary key in the mapped table
  • @Column —provides information related to which column is mapped by an entity property. By default, properties are mapped to columns with the same name, and the @Column annotation is used when the property and column names differ.
Entities support two types of persistence mechanisms:
  1. Field-based persistence—The entity properties must be declared as public or protected and instruct the JPA provider to ignore getter/setters.
  2. Property-based persistence—You must provide getter/setter methods. We recommend to use this approach, because it is more adherent to the Java programming guidelines.

Object-Relational Mapping Metadata

JPA permits the developer to work directly with Java objects rather then with SQL statements. The mapping between Java objects and database tables is defined via persistence metadata.

The object relational mapping of an entity can be done through the use of annotations. As an alternative, you can specify the same information in an external file (called orm.xml ) that must be packaged in the META-INF directory of the persistence module, or in a separate file packaged as a resource and defined in persistence.xml with the mapping-file element.

persistence.xml

persistence.xml, located in META-INF directory, is used to configure your JPA application. Using JDeveloper, this file can be automatically generated when you create Entities from Tables. Within this XML file, persistence units are defined.

Persistence Units

A persistence unit defines a set of entity classes that are managed by one entity manager (described hereafter) instance in an application. This set of entity classes represents the data contained within a single data store.

Entity Manager

Entities cannot persist themselves on the relational database; annotations are used only to declare a POJO as an entity or to define its mapping and relationships with the corresponding tables on the relational database. JPA has defined the EntityManager interface for this purpose to let applications manage and search for entities in the relational database.

Using EntityManager, you can perform:
  • persist—Insert a new entity instance
  • find—Find an instance by key
  • remove—Delete an instance
  • merge—Merge changes of an entity
  • flush—Synchronize with database
  • refresh—Reload from database
  • createNamedQuery—Create an instance of a predefined query
Each EntityManager instance is associated with a persistence context. A persistence context defines the scope under which particular entity instances are created, persisted, and removed through the APIs made available by an EntityManager.

The entity manager tracks all entity objects within a persistence context for changes and updates made, and flushes these changes to the database. After a persistence context is closed, all managed entity object instances become detached from the persistence context and its associated entity manager, and are no longer managed.

JPA Query Language

The Java persistence query language (JPQL) is used to define searches against persistent entities independent of the mechanism used to store those entities. As such, JPQL is portable, and not constrained to any particular data store.

The Java persistence query language is an extension of the Enterprise JavaBeans query language, EJB QL, and is designed to combine the syntax and simple query semantics of SQL with the expressiveness of an object-oriented expression language.

JPA Persistence Provider

Persistence providers are implementations of the Java Persistence API (JPA) specification and can be deployed in the Java EE compliant application server that supports JPA persistence. In this article, we will work with one of the provider named EclipseLink.

EclipseLink is based on the TopLink product, which Oracle contributed the source code from to create the EclipseLink project[1].

In this article, we will focus on one of the multiple EclipseLink persistence services[2]EclipseLink JPA. The EclipseLink JPA provides developers with a standards based Object-Relational persistence solution. In this article, we'll use JPA in a standalone application (i.e., J2SE).

Generating the JPA Entities

In this section, you will generate the JPA entities from the SCOTT database tables (i.e., EMP and DEPT) using JDeveloper. First, let's create a JpaExample application:

  1. Select File > New > Generic Application to bring up the Create Generic Application wizard.
  2. Specify JpaExample in the Name field
  3. Click Next
  4. Select TopLink from the Available list and shuttle it to the right
  5. Click Next
  6. Click Finish

Now that we have a JPA project (i.e., Project1) created. Let's add a JDBC library to the project:
  1. Right select Project1 and select Project Properties to bring up Project Properties Wizard
  2. Select Libraries and Classpath
  3. Click Add Library
  4. On the Add Library Wizard, highlight Oracle JDBC and click OK
  5. Click OK again to close Project Properties Wizard
  6. Click Save All

With Oracle JDBC library added, now we can generate our JPA entities:
  1. Right-click the new JPA project that you created, Project1, and select New > Business Tier > TopLink/JPA > Entities from Tables.
  2. Check EJB 3.0 -- JPA Entities as our JPA/EJB Version
  3. Click Next
  4. On the Persistence Unit step, click New to bring up the New Persistence Unit Wizard
  5. On the Name field, specify empmanager
  6. Click OK
  7. Click Next
  8. Use the default Online Database Connection. Click Next
  9. Need to create a new connection. Click "+" icon
  10. On the Create Database Connection, provide your connection information using scott/tiger credentials
  11. Click Test Connection and then OK
  12. Click Next
  13. Click Query and select both EMP and DEPT tables and shuttle them to the right
  14. Click Next
  15. Click Next
  16. Click Next
  17. Click Finish
As shown in the figure, you will see two Entities (i.e., Dept.java and Emp.java) , persistence.xml, and Offline database files generated:

Adjusting the JPA Objects

The JPA objects generated are only a starting point. They require adjustment and enhancement before elaborating on them with further business logic. Adjustments are required to exploit language conveniences available and to ensure that the entities reflect the business and application domain more accurately.

We will make these adjustments on generated JPA entities:
  • Open Dept.java and add the new annotations to the deptno property as shown below:
    • @Column(nullable = false)
      @Id
      private Long deptno;
  • Open Emp.java and add the new annotations to the empno property as shown below:
    • @Column(nullable = false)
      @Id
      private Long empno;
We also need to make changes to persistence.xml. Open persistence.xml and select Source view. Copy and paste the following contents to it:
<?xml version="1.0" encoding="Cp1252" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="empmanager" type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>oracle.apps.Dept</class>
<class>oracle.apps.Emp</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver">
<property name="javax.persistence.jdbc.user" value="scott">
<property name="javax.persistence.jdbc.password" value="tiger">
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@xxxxx.us.oracle.com:1512:yyyyy">
<property name="eclipselink.target-server" value="WebLogic_10">
</properties>
</persistence-unit>
</persistence>
name
  • (attribute) Every entity manager must have a name.

transaction-type
  • (attribute) Transaction type used. Either JTA or RESOURCE_LOCAL (default to JTA in a JavaEE environment and to RESOURCE_LOCAL in a JavaSE environment). When a jta-datasource is used, the default is JTA, if non-jta-datasource is used, RESOURCE_LOCAL is used.

provider
  • The provider is a fully-qualified class name of the EJB Persistence provider. You do not have to define it if you don't work with several EJB3 implementations. This is needed when you are using multiple vendor implementations of EJB Persistence.

class
  • The class element specifies a fully qualified class name that you will map. By default all properly annotated classes found inside the archive are added to the persistence unit configuration.

properties
  • The properties element is used to specify vendor specific properties. This is where you will define your vendor specific configurations. This is also where you will have to specify JDBC connection information as well.


The following properties can only be used in a SE environment where no datasource/JNDI is available:
  • javax.persistence.jdbc.driver—the fully qualified class name of the driver class
  • javax.persistence.jdbc.url—the driver specific URL
  • javax.persistence.jdbc.user—the user name used for the database connection
  • javax.persistence.jdbc.password—the password used for the database connection

Bootstrapping

The JPA specification defines a bootstrap procedure to access the EntityManagerFactory and the EntityManager. The bootstrap class is javax.persistence.Persistence, e.g.
//properties provide a set of overrides that will take precedence over
//any properties defined in your persistence.xml files
//
//An entity manager factory is typically create at application initialization
//time and closed at application end. It's creation is an expensive process.
//
emf = Persistence.createEntityManagerFactory("empmanager", properties);
EntityManager entityManager = emf.createEntityManager();

Testing JpaExample Application


The final step is to create Entity Manager and execute queries. To achieve that, create a new java file named JpaExample.java in the oracle.apps package with the following contents:
package oracle.apps;

import java.io.Serializable;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


import javax.persistence.*;

import org.eclipse.persistence.config.CacheType;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.jpa.*;
import org.eclipse.persistence.sessions.server.*;

public class JpaExample
{
private static EntityManagerFactory ms_emf;
private static volatile boolean ms_initialized = false;

public JpaExample()
{
super();
}
public static void init(){
if (null != ms_emf){
return;
}
Map properties = new HashMap();
properties.put(PersistenceUnitProperties.CACHE_TYPE_DEFAULT,CacheType.NONE);
properties.put(PersistenceUnitProperties.WEAVING,"false");
//The following commented-out line is how we would use the standard
//JPA technique for discovering an EntityManagerFactory.
//ms_emf = Persistence.createEntityManagerFactory("activitygraph",properties);
//But we don't want to discover one. We want to always use the one from
//Eclipselink
PersistenceProvider persistenceProvider = new PersistenceProvider();
// "socialmedia" -- name of persistence unit
// ms_emf = persistenceProvider.createEntityManagerFactory("manager1", properties);
ms_emf = Persistence.createEntityManagerFactory("empmanager", properties);
}

public static EntityManagerFactory getEMF() {
if (!ms_initialized){
synchronized(JpaExample.class){
if(!ms_initialized){
init();
ms_initialized=true;
}
}
}
return ms_emf;
}
public static EntityManager createEntityManager(){
EntityManagerFactory emf = getEMF();
if (null == emf){
throw new RuntimeException("Unable to get an instance of EntityManagerFactory. This usually means that persistence.xml is not in the classpath.");
}
EntityManager entityManager = emf.createEntityManager();
return entityManager;
}

public static void main(String args[])
{
EntityManager entityManager = null;
String jpql = "select o from Dept o";

try{
entityManager = createEntityManager();
Query query = entityManager.createQuery(jpql);
// Batching is only allowed on queries that have a single object in their
// select clausejjj
// See http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Query_Hints#Batch
// "a.relationId" a single-valued relationship path expression.
query.setHint("eclipselink.jdbc.fetch-size", 256);

List resultList;
resultList = query.getResultList();
System.out.println("size = " + resultList.size());
}
finally{
//By closing the Entity Manager we will put all of the objects
//in the "detached" state.
close(entityManager);
}
}
private  static void close(EntityManager entityManager){
if (null == entityManager){
return;
}
if (!entityManager.isOpen()){
return;
}
try{
entityManager.close();
}
catch(Throwable e){
System.out.println("An exception occurred while closing an entity manager");
}
}
}

To test the application, right-click JpaExample.java and select Run.

References

  1. EclipseLink on Wikipedia
  2. EclipseLink
  3. Oracle JDeveloper Downloads

Sunday, January 30, 2011

Which Style of WSDL Does Your Web Service Use?

A WSDL document describes a Web service. A WSDL binding describes how the service is bound to a messaging protocol, particularly the SOAP messaging protocol. A WSDL SOAP binding can be either a Remote Procedure Call (RPC) style binding or a document style binding. A SOAP binding can also have an encoded use or a literal use. This gives you four style/use patterns:

1. RPC/encoded
2. RPC/literal
3. Document/encoded
4. Document/literal

Adding to this collection, there is another pattern which is known as the document/literal wrapped pattern and used by Microsoft's Web Services. Totally you can have five binding styles to choose from when creating a WSDL file. To learn about the strengths and weaknesses of each pattern, read "Which style of WSDL should I use?".

Which Style of WSDL Does Performance Notes Web Service Use?

Using operation "createXtmPerformanceNotesView1" as example, we can see our sample Performance Notes Web Service uses Document/literal style (see style and use attributes). Or rather, I should say, it uses document/literal wrapped pattern.

<wsdl:binding name="XtmPerfNotesAMServiceSoapHttp" type="tns:XtmPerfNotesAMService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="createXtmPerformanceNotesView1">
<soap:operation soapAction="/model/common/createXtmPerformanceNotesView1" />
<wsdl:input>

<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>

<wsdl:fault name="ServiceException">
<soap:fault name="ServiceException" use="literal" encodingStyle="" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>

For a document/literal wrapped style WSDL, your portType definition should end up with something like this:

<schema elementFormDefault="qualified" xmlns:ns0="/model/common/"
targetNamespace="/model/common/types/">
<element name="createXtmPerformanceNotesView1">
<complexType>
<sequence>
<element name="xtmPerformanceNotesView1" type="ns0:XtmPerformanceNotesViewSDO" />
</sequence>

</complexType>
</element>

<complexType name="XtmPerformanceNotesViewSDO">
<sequence>
<element minOccurs="0" name="AuthorId" type="long" />
<element minOccurs="0" name="NoteCreationDate" type="ns0:dateTime-Timestamp" />

<element minOccurs="0" name="NoteId" type="long" />
<element minOccurs="0" name="NoteText" type="string" />
<element minOccurs="0" name="TargetId" type="long" />
</sequence>
</complexType>
<element name="xtmPerformanceNotesViewSDO" type="XtmPerformanceNotesViewSDO" />

</schema>

<wsdl:message name="XtmPerfNotesAMService_createXtmPerformanceNotesView1">
<wsdl:part name="parameters" element="types:createXtmPerformanceNotesView1" />
</wsdl:message>


<wsdl:portType name="XtmPerfNotesAMService">
<wsdl:operation name="createXtmPerformanceNotesView1">

<wsdl:input message="tns:XtmPerfNotesAMService_createXtmPerformanceNotesView1" />
<wsdl:output message="tns:XtmPerfNotesAMService_createXtmPerformanceNotesView1Response" />
<wsdl:fault name="ServiceException" message="errors:ServiceException" />
</wsdl:operation>
</wsdl:portType>

If you invoke createXtmPerformanceNotesView1 method with appropriate message parts, a SOAP message which looks something below should be sent:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:createXtmPerformanceNotesView1
xmlns:ns1="/model/common/types/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ns1:xtmPerformanceNotesView1 xmlns:ns2="/model/common/">
<ns2:AuthorId>40009 </ns2:AuthorId>

<ns2:NoteCreationDate>2009-04-14T11:22:00.000</ns2:NoteCreationDate>
<ns2:NoteId> 10001 </ns2:NoteId>
<ns2:NoteText>Tim has delivered the gadget on time!</ns2:NoteText>
<ns2:TargetId>45353</ns2:TargetId>

</ns1:xtmPerformanceNotesView1>
</ns1:createXtmPerformanceNotesView1>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

In summary, the characteristics of document/literal wrapped style include:

  • There is no type encoding info in the parameters (i.e., not like this: <ns2:AuthorId type="xsd:long">40009 </ns2:AuthorId> ).
  • You can validate this message easily with any XML validator because everything within the soap:body is defined in a schema.
  • Document/literal is WS-I compliant, and the wrapped pattern meets the WS-I restriction that the SOAP message's soap:body has only one child.
  • The WSDL is more complicated than other styles.
  • The operation name appears in the message, so the receiver has an easy time dispatching this message to the implementation of the operation. This is also why not setting soapAction as below is ok.
var soapAction = document.getElementById("soapAction");
soapAction.value = "/model/common/createXtmPerformanceNotesView1";
...
xmlHttpReq.setRequestHeader("SOAPAction", "\"" + soapAction + "\"");

Saturday, January 15, 2011

WebLogic's Classloading Framework


Updated (09/12/2014):

The FilteringClassLoader provides a mechanism for you to configure deployment descriptors to explicitly specify that certain packages should always be loaded from the application, rather than being loaded by the system classloader. To understand the default class loader structure in WLS 12.1.3, read here.

System (D)
  |
  FilteringClassLoader (filterList := x.y.*) (C)
   |
  App (B)
   |
  Web (A)

Running any application on a JVM or an application server (e.g., WebLogic Server), the main question a designer faces is:
  • Which class is getting loaded from which source
A classloader is used by the JVM to locate and load Java classes into memory at runtime. Java classloaders define a hierarchy, a tree-like collection of parent and child classloaders.

In this article, we will look at two classloader hierarchies:
  • Java Classloader Hierarchy
    • Applied to regular Java applications running from command line
  • Application Classloader Hierarchy
    • We will look at one such hierarchy implemented by WebLogic's Classloading Framework

Three Principles of Java Classloader Operation

Classloader hierarchy plays an important role when locating and loading classes into memory.  There are only three basic principles to understand:
  1. Delegation Principle
    • If a class is not loaded already, the classloaders delegate the request to load that class to their parent classloaders (see also [11]).
      • In other words, a child classloader loads a class only if its parent fails to load it
      • See customization section for an exception that is supported by WebLogic Server to override this default behavior by setting the prefer-web-inf-classes element to true in the weblogic.xml descriptor file.
  2. Visibility Principle
    • Classes loaded by parent classloaders are visible to child classloaders but not vice versa
    • A classloader cannot access any classes loaded by a sibling classloader.
  3. Uniqueness Principle
    • When a classloader loads a class, the child classloaders in the hierarchy will never reload that class.
The application that triggered the request to load a class receives a ClassNotFoundException or NoClassDefFoundError [7]if neither the classloader nor any of its ancestors can locate the class.

Java Classloader Hierarchy


Regular Java applications running from command line involve three classloaders:
  1. Bootstrap classloader (root)
    • Created by the JVM for loading its internal classes and the java.* packages (i.e., core Java libraries under /lib directory) included within the JVM
    • Written in native code
    • Endorsed-standards override mechanism allows a jar file containing a newer implementation of an endorsed standard or standalone API be installed into a run-time image by placing it in one of the directories named by the system property (i.e., java.endorsed.dirs), or by placing it in the default lib/endorsed directory if the system property is not defined. 
      • Such jar files are prepended to the JVM's bootstrap class path at run time, thereby overriding any definitions stored in the run-time system itself.
  2. Extensions classloader (child of bootstrap classloader)
    • Loads any JARs placed in the extensions directory (/lib/ext or any other directory specified by the java.ext.dirs system property) of the JDK
    • Implemented by the sun.misc.Launcher$ExtClassLoader class
    • Extension classes cannot override the JDK classes loaded by the bootstrap loader but they are loaded in preference to classes defined by the system loader and its descendants.
  3. System classloader (child of extensions classloader)
    • Loads code found on java.class.path, which maps to the system CLASSPATH variable.
    • Implemented by the sun.misc.Launcher$AppClassLoader class
    • Any custom classloader created by an application, including WebLogic's classloaders, are all descendants of this system classpath classloader
    • Can be programmatically accessible as ClassLoader.getSystemClassLoader()
    • Is also known as application class loader
In J2EE, each application is packaged as an Enterprise ARchive (EAR) and each EAR gets its own classloader. The J2EE classloader hierarchy supported by a specific framework could include the above-mentioned classloaders and more[6]. J2EE application servers utilize sophisticated classloader hierarchies for features like Java Naming and Directory Interface (JNDI), thread pooling, component hot redeployment, and so on.  In this article, we will introduce one such Application Classloader Hierarchy implemented by WebLogic's classloading framework.

WebLogic's Classloading Framework

WebLogic's standard classloading framework needs to achieve two main goals:
  1. Maintain application independence
    • Classes used by application A must never come in conflict with any classes used by application B
    • Redeploying application A must have no effect on classes used by application B
  2. Hot-deploy or hot-redeploy
    • Within an application, it must allow you to redeploy web applications without having to redeploy the EJBs
    • It is more common to change JSP files and servlets than to change the EJB tier. With proper design, a separate classloader can be created for each servlet and JSP page. This allows you to reload individual servlets and JSPs easily, without the need for redeploying the web application or affecting any of the EJBs.
WebLogic achieves the first goals by creating a separate classloader hierarchy for each application deployed to the server. The parent of this hierarchy is the system classpath classloader. By creating a separate classloader hierarchy for each application, classloaders associated with one application cannot see the classloaders or classes of another application, and because sibling classloaders are isolated from each other, this also isolates the applications.

Java classloaders do not have any standard mechanism to undeploy or unload a set of classes, nor can they load new versions of classes. To achieve the second goal, each application in WebLogic Server has a hierarchy of classloaders (see the Figure below) that are offspring of the system classloader. These hierarchies allow applications or parts of applications to be individually reloaded without affecting the rest of the system. To find out more details on this, read WebLogic Server Application Classloading.


Customization

Even with good support from either Java classloading framework or WebLogic's application classloading framework, it often comes times that you need to have better control over which modules are reloadable, which classes are visible between modules, etc.

There are multiple solutions to your customization needs:
  1. You can configure a web application classloader so that it doesn't use the default parent delegation scheme by setting the prefer-web-inf-classes element to true in the weblogic.xml descriptor file. See details here.
  2. The FilteringClassLoader provides a mechanism for you to configure deployment descriptors to explicitly specify that certain packages should always be loaded from the application, rather than being loaded by the system classloader. See details here.
  3. You can create custom classloader hierarchies for an application allowing for better control over class visibility and reloadability. You achieve this by defining a classloader-structure element in the weblogic-application.xml deployment descriptor file. See details here.

Wrap-up

More often than not, you want class definitions (which are stable) shared across applications. To facilitate sharing, you would place them at higher level of the classloading hierarchy (for example, getting loaded at system classloader instead of at application classloader).

If it is common to change some modules, a separate classloader can be created for them and place them at the tip of the classloading tree. This allows you to reload individual modules easily, without the need for redeploying their parent applications.

When loading a resource dynamically, you can choose from at least three classloaders: the system classloader, the current classloader, and the current thread context classloader. Which classloader is the right one?  You can read [8] to find the answer.

References

  1. Classloader
  2. JRebel
  3. Understanding WebLogic Server Application Classloading
  4. WebLogic: The Definitive Guide
  5. WebLogic Server 11g for ADF/Forms Developers
  6. Classloaders and J2EE (good) 
  7. 3 ways to resolve NoClassDefFoundError in Java
  8. Find a way out of the ClassLoader maze 
  9. Professional Oracle WebLogic Server by Robert Patrick, Gregory Nyberg, and Philip Aston
  10. VM Class Loading
  11. Using 3rd party JDBC Jar Files
    • The general precedence of jar files in the classpath is the following:
    • Note that the above doesn't consider library-ref or prefer-application-packages (see article for details).
  12. WebLogic class loader - analysis and configuration options  (good)
  13. JEP 220: Modular Run-Time Images