5 Replies Latest reply on Dec 7, 2010 5:44 PM by obrienmi8

    WebLogic 11g EAR EJB Classpath and class loaders


      I have been having issues migrating Spring based EJB applications from OC4J to WebLogic 11g (10.3.1). I have been in communication with Oracle who has suggested a work around however I am keen to see if anyone else can suggest a solution.

      The application is dependant on stateless session EJB beans that communicate with a Spring managed service tier to perform the business logic and database access. PitchFork is used to inject the Spring managers into the EJB’s using the spring-ejb-jar.xml configuration file. Note originally I was using the SpringBeanAutowiringInterceptor however I could not get this to work. See WebLogic 11g and Spring beens injected into EJB for details.

      When the application is deployed packaging all the dependant jars within the APP-INF\lib folder I get a verity of errors from the following InvalidClassException, NoSuchMethodError, AbstractMethodError and IllegalArgumentException. I am using Spring 2.5.3 to match the supported WebLogic version. Note within the EAR application.xml the library-directory is set to APP-INF/lib. The issue appears to be Spring, PitchFork, commons-logging and aspectj libraries are being loaded form WebLogic and do not have visibility on jars within the application or have been modified when bundled for WebLogic. An example of this is the PitchFork jar within WebLogic has been changed excluding the spi package resulting in java.lang.ClassNotFoundException: org.springframework.jee.spi.PitchforkUtilsImpl errors.

      Moving the jars to the domain library path does not resolve any of the issues. I have been unable to successfully deploy the application picking up the application jars using the prefer-application-packages configuration.

      Oracle has advised me to deploy the libraries into the WebLogic system classpath by modifying the startWebLogic command to load the libraries into the classpath. I am concerned that modifying the system classpath will result in an unstable WebLogic server as I will be replacing modified jar files packages with WebLogic (such as PitchFork). This will also limit the applications that can be deployed within the server as each application must use the same libraries and versions (as the application ibraries are leing ignored).

      Has anyone else hit this issue and corrected it? Can anyone think of an alternative solution?

        • 1. Re: WebLogic 11g EAR EJB Classpath and class loaders
          René van Wijk
          We had the same kind of issue, involving ANTLR (i.e. the version which comes with Hibernate). We also resorted to the FilterClassLoader (prefer-application-packages). But due to a packing error in the system classpath of WebLogic, the classes in the application are not picked up. I think the same is happening in your case. Our solution was the same as what you are doing - to put the classes in the system classpath (in front).

          By putting your libaries before the libraries of WebLogic, the FilterClassLoader should probably do it's work when you deploy different applicaties, as long as the libraries you put in the system classpath are packaged correctly - with versioning.

          As a last resort you could put up an architecture, in which you use different domains for different technologies (classes are loaded per domain).
          • 2. Re: WebLogic 11g EAR EJB Classpath and class loaders
            Sorry to hear about your classpath issues. Here at a division that deploys libraries to Oracle WebLogic Server we happen to have a similar issue to yours where we require a procedure for end users who wish to run the new JPA 2.0 API on versions of WebLogic up to that support JPA 1.0. The option to hack the startup script on the domain as you mentioned or even the commEnv.cmd script on the server itself - works - but makesthis library override global for all apps.

            Use of the domain library places the jars at the end of the server classpath - see the readme - this will not work for us.

            You are right to use the *<wls:prefer-application-packages>* element - however I have found that it also requires placement of the jars and references in all packaged WARs (I have not tested ejb-jar projects yet).

            There is a procedure that requires no changes to the server where we can place any library jar higher in the server classpath (modules directory) that may be of interest to you. This particular case is for an EAR containing only an application managed EM in a WAR, the other use cases involving other forms of application managed and container managed EM's that may involve a separate shared-library EAR on the server are in progress for our particular case.

            It involves all of the following...
            - .MANIFEST reference to the jars
            - <wls:prefer-application-packages> package overrides in weblogic-application.xml
            - no web.xml persistence-context-ref
            - no weblogic-application.xml wls:library-ref
            - jars placed in the EAR project under APP-INF/lib

            thank you

            TopLink discussion forum
            • 3. Re: WebLogic 11g EAR EJB Classpath and class loaders
              I am trying to deploy application with JPA 2.0 to weblogic 10.3.2 server. I am not using any EJB's. I am using eclipselink as provider. When I use the above procedure it gives me class cast exception

              Caused By: weblogic.deployment.EnvironmentException: Error processing persistence unit PT of module pt: Error instantiating the Persistence Provider class org.eclipse.persistence.jpa.PersistenceProvider of the PersistenceUnit PT: java.lang.ClassCastException: org.eclipse.persistence.jpa.PersistenceProvider cannot be cast to javax.persistence.spi.PersistenceProvider

              Any help is really appreciated.
              • 4. Re: WebLogic 11g EAR EJB Classpath and class loaders
                I am using eclipselink jpa 1.0, and getting classcast exception while casting object (retrieved from database ) to normal java bean.
                both are getting loaded by different class loaders and its very simple application i am using only one table and one java bean.

                please do let me know the steps to do while deploying war file into weblogic to make those two classes (java bean and database tables)

                private static final String PERSISTENCE_UNIT_NAME = "flavors";
                private static EntityManagerFactory factory;
                factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
                EntityManager em = factory.createEntityManager();
                Query q = em.createQuery("select fc from Flav_Choice fc"); // Flav_Choice is the table name
                List<Flav_Choice> f = q.getResultList();
                for(int i=0; i< f.size(); i++){
                System.out.println(f.size()); // printing size properly
                Flav_Choice fc = f.get(i); // getting class cast exception here
                String value = fc.getName();
                SelectItem sm = new SelectItem(value);

                class containing above piece of code and Flav_Choice class both r in same package.

                ]] Root cause of ServletException.
                javax.el.ELException: java.lang.ClassCastException: view.Flav_Choice
                     at javax.el.BeanELResolver.getValue(BeanELResolver.java:266)
                     at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:143)
                     at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
                     at com.sun.el.parser.AstValue.getValue(AstValue.java:118)
                     at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:192)
                     Truncated. see log file for complete stacktrace

                Caused By: java.lang.ClassCastException: view.Flav_Choice
                     at view.ViewBeanClass.getSelectItems(ViewBeanClass.java:51) // Flav_Choice fc = f.get(i);
                     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                     at java.lang.reflect.Method.invoke(Method.java:597)
                • 5. Re: WebLogic 11g EAR EJB Classpath and class loaders
                  I am in the process of updating the tracking bug# 331569 with copies of the eclipse EAR/WAR projects and the EAR for these scenarios. Here are some details on how I got past the 2nd CCE on the org.eclipse.persistence.jpa.PersistenceProvider class (not the javax one)

                  Essentially an SE persistence unit running both JPA 2.0 api and the 2.0 XSD schema work fine. I will next retest the EE case with variations of the 3 types of injection on the SSB or Servlet.
                  Update: There are 3 (possibly 4) issues here (all of these may become obsolete when the next WLS version ships)
                  Initially I got the same 2.0 schema error and the ClassCastException on org.eclipse.persistence.jpa.PersistenceProvider
                  It turns out that my import of the 2 eclipse projects from my bug # 296271 for WebLogic lost their facets(specifically the dynamic web facet) because I associated them with a different WebLogic - this caused the CCE I was experiencing like Sri.
                  Anyways, after creating an EAR/Web project combination from scratch in eclipse associated with the instance - I predeployed/deployed/ran fine - even with the 2.0 schema - in SE bootstrap mode (no EE yet).
                  Reproduction Procedure:
                  redoing project from scratch as I noticed that the war was not at the root of the ear - it was a jar in the app-inf/lib dir - my imported eclipse project was not referenced correctly as a web module facet
                  - create empty EAR and WAR project with references
                  - download and open my EAR and WAR project code from bug # 296271
                  - do essentially all the steps in the page below (I paraphrase for re-verification)
                  - copy applicationService, entity and FrontController servlet code into new projects
                  - create persistence.xml and MANIFEST.MF manifest in src\META-INF
                  - update manifest
                  Class-Path: APP-INF/lib/eclipselink.jar

                  - copy both javax.persistence 2.0 and eclipselink 2.x jars to APP-INF/lib
                  - change ordering of WebLogic library modules classpath reference (javax.persistence 1.0) to ear reference (2.0 version)
                  - update web.xml with servlet tags
                  - update weblogic.xml with new context root
                  - make the persistence unit name the same in persistence.xml and ApplicationManagedService
                  - update weblogic-application.xml with prefer-application-packages overrides
                  - enable server redirect logging
                  <!-- new for http://wiki.eclipse.org/EclipseLink/Examples/JPA/Logging#Server_Logging -->
                  <property name="eclipselink.logging.logger" value="DefaultLogger"/>
                  - start WebLogic
                  - deploy (run on) server from eclipse or export ear to auto deploy directory

                  1) JPA 2.0 XSD usage on
                  - I reproduced this issue with a bad EAR
                  - was able to use the 2.0 schema within the WAR-only application managed EAR
                  <persistence version="2.0" 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_2_0.xsd">
                  <!-- persistence version="1.0" 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"-->
                  <persistence-unit name="example2" transaction-type="JTA">
                  <property name="eclipselink.target-server" value="WebLogic_10"/>
                  <property name="eclipselink.logging.level" value="FINEST"/>
                  <property name="eclipselink.target-database" value="Derby"/>
                  <!-- new for http://wiki.eclipse.org/EclipseLink/Examples/JPA/Logging#Server_Logging -->
                  <property name="eclipselink.logging.logger" value="DefaultLogger"/>
                  <!-- property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
                  <property name="javax.persistence.jdbc.url" value="jdbc:derby://;create=true"/>
                  <property name="javax.persistence.jdbc.user" value="APP"/>
                  <property name="javax.persistence.jdbc.password" value="APP"/-->
                  <!-- turn off DDL generation after the model is stable -->
                  <!-- property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
                  <property name="eclipselink.ddl-generation.output-mode" value="both"/-->

                  2) CCE on JPA provider implementation class
                  Error instantiating the Persistence Provider class org.eclipse.persistence.jpa.PersistenceProvider of the PersistenceUnit example2: java.lang.ClassCastException: org.eclipse.persistence.jpa.PersistenceProvider
                  - I reproduced and fixed this one (was Eclipse project facet issue) - EAR was wrong
                  - was able to run JPA 2.0 code fine on an SE PU (predeploy/deploy together)
                  - EE injection should not work but I will post an example EAR anyway
                  [EL Example]: enterprise: JPA 2.0 Metamodel: MetamodelImpl@56287508 [ 3 Types: , 1 ManagedTypes: , 1 EntityTypes: , 0 MappedSuperclassTypes: , 0 EmbeddableTypes: ]

                  3) CCE on JPA spec interface class
                  - I could not reproduce this one
                  Re: WebLogic 11g EAR EJB Classpath and class loaders
                  Error processing persistence unit PT of module pt: Error instantiating the Persistence Provider class org.eclipse.persistence.jpa.PersistenceProvider of the PersistenceUnit PT: java.lang.ClassCastException: org.eclipse.persistence.jpa.PersistenceProvider cannot be cast to javax.persistence.spi.PersistenceProvider

                  4) CCE on fallback Kodo JPA provider (if an invalid say 2.1 JPA XSD schema is referenced)
                  java.lang.ClassCastException: kodo.persistence.PersistenceProviderImpl
                  at javax.persistence.Persistence.findAllProviders(Persistence.java:186)

                  java.lang.NoSuchMethodError: javax/persistence/EntityManager.getMetamodel()Ljavax/persistence/metamodel/Metamodel;

                  - reproduced by using the 1.0 javax.persistence jar (but named as the 2.0 one in APP-INF/lib)
                  - fixed by using either the 1.0 or 2.0 JPA XSD schema and using the correct 2.0 spec jar

                  thank you