WebLogic Server Shared Libraries – Including Jars

In my last post about including static resources in shared libraries, I had a follow-up question about how to include multiple jar files in a library.  I alluded to it in my post, but here is a concrete example that should make it more clear.

Suppose I have 2 jars, that need to be deployed together, and I want to do that in a single shared library that my new web application will reference.

Foo.java – packaged in foo.jar

   1:  package com.oracle.otn.samples.wls;

   2:   

   3:  public class Foo 

   4:  {

   5:      public String toString()

   6:      {

   7:          return "Foo";

   8:      }

   9:  }


Bar.java – packaged in bar.jar – notice that Bar extends Foo, so unless both jars are available at runtime, we should expect to see an error.


   1:  package com.oracle.otn.samples.wls;

   2:   

   3:  public class Bar extends Foo {

   4:      

   5:      public String toString()

   6:      {

   7:          return super.toString() + "Bar";

   8:      }

   9:  }


To build a shared library for these, I simply construct a new packaging structure for this library that includes both foo.jar and bar.jar in the WEB-INF/lib of my shared library.  Of course I also need to configure a MANIFEST.MF.

Here is the file structure of my shared library I call manyjars.war.  The jars is in this library’s WEB-INF/lib directory will be added to the WEB-INF/lib of any application that references this library when the application is initialized.


   1:  d:\temp>jar -tf manyjars.war

   2:  META-INF/

   3:  META-INF/MANIFEST.MF

   4:  WEB-INF/

   5:  WEB-INF/lib/

   6:  WEB-INF/lib/bar.jar

   7:  WEB-INF/lib/foo.jar


Here is the MANIFEST.MF file:


   1:  Manifest-Version: 1.0

   2:  Specification-Title: ManyJars

   3:  Specification-Version: 1.0

   4:  Implementation-Title: ManyJars Implementation

   5:  Implementation-Version: 1.0

   6:  Implementation-Vendor: Oracle

   7:  Extension-Name: ManyJars


I can now deploy this shared library to WebLogic Server (or Oracle Enterprise Pack for Eclipse – OEPE - will do it for you if you configure the library there and refer to it in your application).  Here is how it looks in the console once it’s deployed.

ManyJars

In my new web application, I refer to the library in my weblogic.xml – again OEPE for insert this reference for you if you use the tooling:


   1:  <?xml version="1.0" encoding="UTF-8"?>

   2:  <wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd">

   3:      <wls:weblogic-version>10.3.2</wls:weblogic-version>

   4:      <wls:context-root>FooBarWeb</wls:context-root>

   5:      <wls:library-ref>

   6:          <wls:library-name>ManyJars</wls:library-name>

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

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

   9:      </wls:library-ref>

  10:  </wls:weblogic-web-app>


So now if I have a simple index.jsp that refers to the Bar class we showed earlier, it should all work:

FooBar

If I wanted to include these jars at the EAR level, the procedure would be similar, except that I would create an ear-based shared library packaging and instead of WEB-INF/lib, I would place the jars in APP-INF/lib.  Instead of referring to the shared library in weblogic.xml, I would use weblogic-application.xml.

You can download my files here if you want to try this.  Good luck.

Comments:

Thank you so much! You are a gem, James.. But, my application is bit more complicated it seems. The library as u told, have been deployed as a library and the jars are kept inside the WEB-INF/lib Next is deploying my EAR. let me tell its structure: 1.This EAR contains a META-INF folder (that has a application.xml and a manifest file inside) 2.EAR also contains many jars inside it in which one jar is considered to be the ejb module and is mentioned in the application.xml file. This module has inturn its own Manifest file and application file. 3.Now my question is whether i should put the weblogic-application.xml file in the parent location with main Meta-INF folder and those many jars or will out inside the meta-inf of that ejb module jar which is there present with otehr many jars I am not working with web module, so web-inf ?? shall i use app-inf/lib instead? please help

Posted by Subh on December 15, 2009 at 03:00 PM PST #

The deployment descriptor contents (such as web.xml, application.xml, etc) that are in Shared libraries get merged with the deployment descriptors of the applications that refer to them at deploy-time. To see how WebLogic does this, you can use the weblogic.appmerge ant task which will create one application out of a module and a set of libraries. http://download.oracle.com/docs/cd/E12839_01/web.1111/e13706/libraries.htm#i1073638 Check out some of the examples here: \wlserver_10.3\common\deployable-libraries You will see the contents of those shared library web.xml entries getting merged with the web applications that refer to them. Good luck, James

Posted by james.bayer on December 15, 2009 at 10:20 PM PST #

Hi Bayer I have a question. Say I have 100 libraries, and each application uses some set of these libraries. and these libraires are at differert locations. As i see in weblogic we have to package these libraries as an application and use them in applications But I want to directly reference libraries them in my application without packaging as applications. like in oc4j we can use the libraries directly by add-shared-library kind of tag. Could you please tell me how to acheive this in weblogic.

Posted by Murali on December 19, 2009 at 12:39 AM PST #

Murali, Read this: http://download.oracle.com/docs/cd/E12839_01/web.1111/e13702/understanding.htm#i1052660 Shared Libraries are either an application (EAR file) or a module (EJB jar, WAR). Their contents (static files, class files, jars, deployment descriptors) get merged with applications and modules that refer to them at runtime. If you don't want to package the stuff you need in an application or module, then you can use "Optional Packages" to simply put the classes you need as a jar file and refer to them that way. I'm not familiar with how OC4J did this. Thanks, James

Posted by james.bayer on December 19, 2009 at 01:10 AM PST #

Hi James, I have one question regarding weblogic application server having multiple web applications. Say I have 2 web application running in 1 weblogic application server. The web applications are webapp1.war webapp2.war These 2 web applications are developed using struts2 & spring frameworks so we need to keep framework .jar files in WEB-INF/lib folder, example we need to keep spring.jar file in both these application WEB-INF/lib folder Is their any way so that I can keep spring.jar file in one place rather then keeping this .jar file in individual .war file for sharing libraries. I know we can do this easily in Tomcat where they are having /common folder(sharing libraries). How to do this in weblogic? Thanks in advance. Regards, Sharath.

Posted by sharath on December 29, 2009 at 12:45 AM PST #

It depends on what you're trying to accomplish. The closest thing to the way Tomcat does it would be putting it in the domain\lib directory. http://download.oracle.com/docs/cd/E12839_01/web.1111/e13716/config_files.htm#i1101997 However, you could easily create a shared library that had a WEB-INF/lib/spring.jar and WEB-INF/lib/struts2.jar and an appropriate META-INF/MANIFEST.MF file. Then you could deploy this shared lib as an app and reference it in your weblogic.xml as a library and get the values at runtime. The blog comment system isn't the best for Q&A, I suggest using the WLS General OTN forum http://forums.oracle.com/forums/forum.jspa?forumID=570

Posted by james.bayer on December 29, 2009 at 11:37 AM PST #

Hi James, I created 'MyLibrary' which is having common .jar files used in different web application. Think that it is having all spring related .jar files. Where as 'MyWebApp' application is developed with struts2 and struts2.jar file is under '/WEB-INF/lib' folder. This web application also requires spring functionality so I added 'MyLibrary' to this web application. When I try to deploy 'MyWebApp' it is unable to fetch struts2.jar files placed under /WEB-INF/lib folder but it is resolving spring .jar files. As per my understanding it will give first preference files placed in 'MyLibrary' then it will load application specific .jar files(/WEB-INF/lib) folder. But this is not behaving like this.. I really don't understand why we need to use 'weblogic.appmerge'? we are using shared libraries so that we can place common files in one place to use this library where ever we requires common files rather than adding these common files in each web application. Can you please look into this and let me know how to resolve this issue. Thanks for your help. Regards, Sharath.

Posted by sharath on December 30, 2009 at 12:27 AM PST #

AppMerge is what WLS uses at deploy time when you're using shared libs. The reason I suggested it is that you'll get an opportunity to see what WLS does with your shared libraries. I don't recommend that you use it in your deploy process for real - simply to troubleshoot why you have a problem. Files in your application always take precedence over library files. I don't have time to troubleshoot what is happening in your config because I have many customer commitments right now, which is why I recommend you post in the OTN forum. Post all your deployment descriptors and the file structure of your shared lib using jar -tf sharedlib.war etc. Alternatively you can open a support case. Good luck, James

Posted by james.bayer on December 30, 2009 at 12:51 AM PST #

James, Great the way you are providing solutions to us.Thanks. Earlier I had a requirement with which I was able to work with your help (it was to put all the libraries into an ear and deploy that ear as shared lib and this Lib to be referred by an ear) We have a scenario now. I have an web.ear that has many jars inside it and also an web.war file. This web.war has many jars inside its web-inf/lib. Now I need to take out the jars just inside the main web.ear file and also 3rd party jars from the web-inf/lib and to put it in a single ear/war as a library How can I do it? if i create a library.ear, can the web.war inside the main web.ear can refer to that library ear? Please provide suggestion.

Posted by Subh on January 04, 2010 at 08:34 PM PST #

For using appmerge in Wl10.3 , do we need to so anything specific? I mean adding some jar to classpath or so? I was unable to run appmerge. And a query, I have an EAR that has many jars and a war file inside this EAR as well. I need to take a few 3rd party libraries from within the main ear and from the war (inside that ear) as well. These jars should be packaged as a Library EAR or WAR? So that we can reference them from the EAR application (that has again a war inside it?) Can you please help?

Posted by Subh on January 06, 2010 at 01:34 PM PST #

Did you set up your env by calling your domain's bin\setDomainEnv script when trying appmerge? As far as your question about shared libs - once you go to EAR packaging, you might find it easiest to simply put the jars in APP-INF/lib of your EAR or the shared library that your EAR will reference because then all the modules of that EAR including a WAR will have access to those classes. See http://download.oracle.com/docs/cd/E12839_01/web.1111/e13706/libraries.htm#sthref135 and http://download.oracle.com/docs/cd/E12839_01/web.1111/e13706/classloading.htm

Posted by james.bayer on January 06, 2010 at 01:55 PM PST #

The short answer is that it's probably easiest to create a new "Shared Library" that is based on an EAR layout and put all the jars you want to share among other applications in the APP-INF/lib directory of your shared library. Deploy it as a library. Then in your Application EAR projects that you want to have a reference to the jars you put in the shared library, simply add a library reference to your application-weblogic.xml which should cause any J2EE module in that EAR to get access the all the jars at deploy-time. The AppMerge tool will show you what WLS actual does if you want to get a preview to see if it's behaving as you expect. http://download.oracle.com/docs/cd/E12839_01/web.1111/e13706/libraries.htm#i1073638

Posted by james.bayer on January 06, 2010 at 01:56 PM PST #

Thanks James. Even I have set the setDomain it does not work.. it says "Only options were given, additional arguments are required." Output: [root@baufi2 Lib2]# ../bin/setDomainEnv.sh Logging WLS stdout to /bea/user_projects/domains/CteDomain/var/applications/MORT /logs/weblogic.out Logging WLS stderr to /bea/user_projects/domains/CteDomain/var/applications/MORT /logs/weblogic.err [root@baufi2kolmc8 Lib2]# java weblogic.appmerge -output CompleteSportsApp.ear - library ejb-api-3.0.jar,commons-io-1.4-1.4.jarclear Usage: java weblogic.appmerge [options] Only options were given, additional arguments are required. Actually I was trying to use java weblogic.appmerge -output A.ear =librarydir Lib where Lib is a dir that has the jars What can be the reason? Some thing silly I guess..

Posted by Subh on January 07, 2010 at 01:46 PM PST #

Below is an appmerge example using my files from this post. You'll see the libs being merged correctly. See how it compares to what you have done. James D:\Oracle\wls11g\user_projects\domains\sca_domain\tmp>..\bin\setDomainEnv.cmd D:\Oracle\wls11g\user_projects\domains\sca_domain>cd tmp D:\Oracle\wls11g\user_projects\domains\sca_domain\tmp>dir Volume in drive D has no label. Volume Serial Number is 646E-34E2 Directory of D:\Oracle\wls11g\user_projects\domains\sca_domain\tmp 01/13/2010 10:28 AM . 01/13/2010 10:28 AM .. 12/15/2009 11:17 AM 719 bar.jar 12/15/2009 10:42 AM 608 foo.jar 12/15/2009 12:00 PM 1,776 FooBarWeb.war 12/15/2009 11:20 AM 1,884 manyjars.war 4 File(s) 4,987 bytes 2 Dir(s) 64,802,357,248 bytes free D:\Oracle\wls11g\user_projects\domains\sca_domain\tmp>java weblogic.appmerge -output MergedApp.war -library manyjars.war FooBarWeb.war D:\Oracle\wls11g\user_projects\domains\sca_domain\tmp>jar -tf MergedApp.war META-INF/MANIFEST.MF .beamarker.dat index.jsp META-INF/ WEB-INF/ WEB-INF/classes/ WEB-INF/lib/ WEB-INF/lib/bar.jar WEB-INF/lib/foo.jar WEB-INF/web.xml WEB-INF/weblogic-webservices-policy.xml WEB-INF/weblogic.xml

Posted by james.bayer on January 13, 2010 at 12:38 AM PST #

Hi James, Thanks a lot for the answers provided. They really did help a lot as I am totally a fresher wrt to Weblogic Server. I have been working of IBM Websphere Application Server for the past 5 years. My question would be: How to include some configuration/property files in the server which the application references? In Websphere we used to create a shared library and specify the path for the location of the files. The server would pick them up from the specified location. I have used the Upload files option and the files were copied to the following location C:\oracle\Middleware\user_projects\domains\base_domain\servers\AdminServer\upload but the application when run on the server could not refernece those files and as a result --- NullPointerException. Could you please guide accordingly? Rohit

Posted by Rohit on June 28, 2010 at 09:09 PM PDT #

Yes, I wouldn't expect that the upload directory would help you. The easiest approach is to use a shared library, but one thing you have to remember is that if the application contains a file of the same name then the one inside the application will get precedence over the resource in the shared library. If you want to override resources that exist in your application archive/directory with a file that is outside your application, you can use a feature introduced in 10.3.2. http://download.oracle.com/docs/cd/E12840_01/wls/docs103/deployment/config.html#wp1066442 Hope this helps. If not give me a very simple example of what you want to do. Thanks, James

Posted by james.bayer on July 02, 2010 at 05:21 AM PDT #

Hi James, I am trying your sample application in Weblogic 9.2 MP2. And when I run the appmerge, I am getting the following error. java weblogic.appmerge -output MergedApp.war -library ManyJars.war FooBarWeb.war Exception in thread "main" weblogic.utils.compiler.ToolFailureException: Error: Unresolved WebApp library references defined in weblogic.xml, of module 'FooBarWeb.war' [Extension-Name: ManyJars, Specification-Version: 2, Implementation-Vers ion: 2, exact-match: false] at weblogic.servlet.utils.WebAppLibraryUtils.initWebAppLibraryManager(WebAppLibraryUtils.java:90) at weblogic.servlet.utils.WebAppLibraryUtils.getWebAppLibraryManager(WebAppLibraryUtils.java:67) at weblogic.application.compiler.AppcUtils.mergeWAR(AppcUtils.java:387) at weblogic.application.compiler.WARCompiler.merge(WARCompiler.java:95) at weblogic.application.compiler.flow.AppMergerFlow.mergeInput(AppMergerFlow.java:94) at weblogic.application.compiler.flow.AppMergerFlow.compile(AppMergerFlow.java:47) at weblogic.application.compiler.FlowDriver$FlowStateChange.next(FlowDriver.java:69) at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:26) at weblogic.application.compiler.FlowDriver.nextState(FlowDriver.java:36) at weblogic.application.compiler.FlowDriver$CompilerFlowDriver.compile(FlowDriver.java:96) at weblogic.application.compiler.AppMerge.runBody(AppMerge.java:133) at weblogic.utils.compiler.Tool.run(Tool.java:158) at weblogic.utils.compiler.Tool.run(Tool.java:115) at weblogic.application.compiler.AppMerge.main(AppMerge.java:166) at weblogic.appmerge.main(appmerge.java:13) Please advice.

Posted by Jangs on December 19, 2010 at 05:15 PM PST #

Jangs, This is telling you that there is a mismatch between the library reference in weblogic.xml and the shared library that is being used by appmerge (which is from the -library option in this case, ManyJars.war). Are you sure you don't have a typo, because the capitalization in my example is manyjars.war. I also created this example with WLS 10.3.2, so running it as-is on WLS 9.2.2 may not work without editing the deployment descriptors to be what the defaults are for 9.2. You can see FooBarWeb.war\WEB-INF\weblogic.xml file has a 10.3.2 version reference in it. I recommend you post followup questions in the OTN Forum - WLS General or with Oracle Support as I have a large work backlog and may not be very responsive. Good luck, James

Posted by james.bayer on December 22, 2010 at 04:03 AM PST #

Post a Comment:
Comments are closed for this entry.
About

James Bayer Image
I was formerly a Product Manager on the WebLogic Server team based out of Oracle HQ. You can find my new blog at http://iamjambay.com.
Follow Me on Twitter
Oracle WebLogic

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today