One of the problems you come across when using Weblogic are Weblogic classloader issues. These can regularly happen because Weblogic itself uses a lot of frameworks, some of which you’re also using in your application EAR/WAR file. Sometimes you want to use a newer version of the library then the one in Weblogic and that’s when the problems start because your library comes later on the classpath.
WLS CAT (Class Loader Analysis Tool)
Fortunately there is a Web app wls-cat available by default in Weblogic (you don’t see it deployed in the Weblogic console though).
Below you can find a screenshot of wls-cat in action. When you analyze conflicts, the tool will spit-out all classes which are in conflict – eg. more then one version is on the classpath (EAR/WAR classpath + Weblogic classpath), but only one can be loaded in the JVM.
Once you have a list of the packages/classes in conflict, you have two options: either you can remove the duplicate jar from your EAR application, or you can instruct Weblogic to choose your version over the one bundled in Weblogic.
The latter option is configured via the META-INF/weblogic-application.xml file in your EAR file:
Configuring the options happens on package level. Now the nice thing about wls-cat is, that it also generates a ready-to-use prefer-application-packages xml element so you don’t need to create this list fully by hand by inspecting all the packages inside a conflicting library jar
The WebLogic Scripting Tool or in short WLST, is a command-line tool that you can use to automate Weblogic server installs and configuration of domains. This post will explain how to setup your Eclipse WLST development environment so you can write the scripts with code completion.
WLST scripting environment
The WLST scripting environment is based on the Java scripting interpreter, Jython. To get access to the WebLogic scripting functions from your Eclipse IDE you’ll have to install the plugins Oracle has made available.
What Does WLST Do?
WLST lets you perform the following tasks:
- Retrieve and edit domain configuration and runtime information.
- Automate domain configuration tasks and application deployment.
- Control and manage the server life cycle.
- Access the Node Manager and start, stop, and suspend server instances remotely or locally
Eclipse WLST configuration
- Install Eclipse Kepler release with the Oracle Enterprise Pack for Eclipse (WTP) from http://download.oracle.com/otn_software/oepe/kepler/wtp/
- Create a Weblogic Server runtime via Window -> Show View -> Servers
- Click this link to create a new Server
- Choose Oracle WebLogic Server 12c (12.1.2)
- Enter the following parameters:
- Weblogic Home: <BEA_HOME>\wlserver
- Java Home: <JAVA_HOME>
- Domain: <WEBLOGIC_DOMAIN_DIR>
Verifying Eclipse WLST installation
- Create a new Facet Project in Eclipse
- Add the Facet Weblogic Scripting Tools (WLST)
- Click on Further configuration required, click OK
- If you go to Window -> Preferences -> PyDev -> Interpreter Jython, you should now see something similar as below:
When trying to @Inject an EJB inside a bean, it is possible that you’ll get an exception about ambiguous dependencies for type on Weblogic:
Substituted for the exception org.jboss.weld.exceptions.DeploymentException which lacks a String contructor, original message - Exception List with 2 exceptions: Exception 0 : org.jboss.weld.exceptions.DeploymentException: WELD-001409 Ambiguous dependencies for type [ABC] with qualifiers [@Default] at injection point [[field] @Inject private ABCField]. Possible dependencies [[Session bean [class ABCImpl with qualifiers [@Any @Default]; local interfaces are [ABC], Managed Bean [class ABCImpl_7pbnr4_Impl] with qualifiers [@Any @Default]]]\
Solving the Ambiguous dependencies for type problem
The problem is that there are two possible implementations to inject and the CDI container doesn’t know which one to choose. You can also see that there seems to be a proxied/generated class to be listed (in our example ABCImpl_7pbnr4_Impl).
In our case this generated class was created by the Weblogic appc tool which was run on our EAR file. This ear file includes a JAR with EJB 2.x beans and another one with EJB 3.x beans<.
We solved this problem by not letting Weblogic appc being run on our EJB3.x jar. You can do this by running the Weblogic appc on individual jar files instead of the ear file. As you probably know EJB3 style beans don’t need an ejb compiler anymore to generate the remote and local interfaces as everything can be done with annotations.
PS: Weblogic uses Weld, the reference implementation of Contexts and Dependency Injection in JavaEE.