Wednesday, June 19, 2013

Production Redeployment with ADF Shared WebLogic Libraries


Based on my previous post I wanted to know if we can achieve to redeploy parts of an ADF application by using shared WebLogic Libraries. In conjuction with the production redeployment WLS feature the overall goal is to prove that we can update modular ADF applications without downtime.

Introduction

The sample application consists of an employees taskflow that is bundled as ADF Library and deployed as shared library on WebLogic server. The sample is based on ADF 11.1.1.7 / WLS 10.3.5 / HR Schema.

First step: Create ADF Library as Shared WAR deployment

Goto JDev application with the containing Taskflow:

Create a MANIFEST.MF file under ViewController/src/META-INF/ with the following contents
The important parts are

Extension-Name: enpit.sample.empFlow
Specification-Version: 1.0
Implementation-Version: 1.0

Create ADF Library Deployment Profile for the empFlow on ViewController project with dependency on your Model project.
Make sure only connection name is Included in the Library

Having an ADF Library Deployment Profile in the employee taskflow application we create an additional Deployment profile (of type WAR) in the ViewController project. 

Under  WAR Options include the MANIFEST.MF file

Make sure to remove everything from Web Files contributors since we only want to wrap the ADF Library inside this WAR file.

Same to WEB-INF/classes. Exclude everything.

Under Profile Dependencies add the dependency to the ADF Library Profile

Goto WEB-INF/lib Filters and uncheck everything except the desired ADF Library JAR file.

With that WAR deployment configuration we are able to deploy -  the ADF Taskflow -  as shared library to the WebLogic server. (Select ViewController, right click, Choose Deploy > SharedADFLib ...to Application Server)

As a result the library shows up under Deployments in the WebLogic Admin Console

Deploy master application

In the master application that consumes the taskflow from the ADF Library we need to make sure
  • versioning is configured for application deployment
  • ADF Library is not bundled with the EAR
  • Library reference is added to the ADF Shared Library in weblogic.xml (not weblogic-application.xml)
To enable the versioning for the app deployment we add /src/META-INF/MANIFEST.MF file with the contents
Manifest-Version: 1.0
Weblogic-Application-Version: 1.0

Now goto the EAR deployment profile and add the MANIFEST.MF file under the EAR Options

Goto application descriptors Filters and exclude MANIFEST.MF. (Otherwise the EAR won't be created as JDeveloper will try to include 2 MANIFEST.MF files in the EAR. You will see this exception in the deployment log window).

Now exclude the ADF Library from the application deployment. Goto ViewController project properties of the master application and make sure the library is not deployed by default.

In the WAR deployment profile check that the ADF Library JAR is not included


Next create WEB-INF/weblogic.xml and add library reference to the ADF Shared Library.

Important note: In my first try I added that library reference in the weblogic-application.xml. That won't work. At deployment time there will be the following exception
[08:23:54 AM] [Deployer:149034]An exception occurred for task [Deployer:149026]deploy application enpit_application1 [Version=1.0] on DefaultServer.: javax.faces.context.ExternalContext.
[08:23:54 AM] Weblogic Server Exception: weblogic.application.WrappedDeploymentException: javax.faces.context.ExternalContext
[08:23:54 AM]   See server logs or server console for more details.
[08:23:54 AM] weblogic.application.WrappedDeploymentException: javax.faces.context.ExternalContext
[08:23:54 AM] ####  Deployment incomplete.  ####
[08:23:54 AM] Remote deployment failed (oracle.jdevimpl.deploy.common.Jsr88RemoteDeployer)

So don't try this.

Doing it right you should see the following in Admin Console:

Test the application. It loads the taskflow and displays version 1

Next Step: Test production redeployment based on new version of ADF Shared Library
We are going to 
  • Make changes in employees taskflow
  • Change Library Implementation-Version to 1.1
  • Deploy ADF Library as Shared WLS Library
  • Increase application version to 1.1
  • Redeploy master application
So first we increase the library version
and make some simple changes to the JSFF

Next: Deploy ADF Library to JAR
Next: Deploy sharedADFLib Deployment to IntegratedWebLogic

Check deployment in the Admin Console

Goto the master application and change Weblogic-Application-Version to 1.1

and deploy the master application to Verify deployment in the Admin Console once again. You should notice that previous application (1.0) is in stop running state. Actually it is meant to be RETIRED Mode. Existing web sessions will be served by that version 1.0.

Open a NEW BROWSER WINDOW (a different browser window to be dead sure) and point to the master application URL. You should see new version of the integrated Taskflow.

Conclusion

This mechanism is really powerful. It lets you redeploy application parts - maybe of a huge application - without downtime.

Download Sample Application


Related Posts

Thursday, June 6, 2013

WebLogic Application redeployment using shared libraries - without downtime


Environment
Oracle WebLogic 10.3.6

Use Case
An application that depends on custom shared libraries needs to be redeployed without downtime. That means without interrupting the availability of the application to existing and new clients. Since production redeployment is not available for libraries we need to think about a different approach.

Precondition

A shared library (as war) is deployed (state: active) and targeted to - for simplicity say - AdminServer with the following version settings:

Extension-Name: enpit-common-war-lib
Specification-Version: 1.0
Implementation-Version: 1.0.4

An application references that library in its weblogic.xml in the following way:
<?xml version='1.0' encoding='UTF-8'?>
  <library-ref>
       <library-name>enpit-common-war-lib</library-name>
  </library-ref>
</weblogic-web-app>

The library is referenced without any version information. That means it will reference the highest available deployed library version. That application is successfully deployed and also targeted to AdminServer. Its state is active. It is working correctly, accesses Java classes in the shared library.

Problem

Trying to deploy the existing library (not changing the version information) once again 

java weblogic.Deployer -adminurl t3://eden.local:7001 -username weblogic -password welcome1 -upload -library -targets AdminServer -deploy -source enpit-shared-lib-war.war
results in the following error:

Cannot undeploy library Extension-Name: enpit-common-war-lib, Specification-Version: 1, Implementation-Version: 1.0.4 from server AdminServer, because the following deployed applications reference it: enpittestcommons-reflib.war

=> Makes sense!

Solution Trial 1
We change the MANIFEST.MF of the Shared Library that has to be redeployed to
Implementation-Version: 1.0.5   (the deployed one has 1.0.4)

Lets see what happens

Task 17 completed: [Deployer:149117]deploy library enpit-common-war-lib [LibSpecVersion=1.0,LibImplVersion=1.0.5] on AdminServer.
Target state: deploy completed on Server AdminServer

=> We succeeded. Have a new version deployed!

Question 1
Which version is our running application now using?

Well, the application still uses version 1.0,1.0.4 although it is specified that the highest version should be used. To conclude: The application does not dynamically adopt to the new library version. I think that is good. Otherwise it would be much magic happening in the background.

Question 2
We stop the running application. Now the application shows up in the admin console in state "prepared".
Lets start it again. ... It moves again to state "active".

Which version is our running application now using?

Well, In my simple use case I changed the returned string in the library class to "1.0,1.0.5" according to the new library version. And indeed, my sample app shows the right information.
Library-Version: 1.0,1.0.5

Conclusion: That's a powerful way to update dependencies for an application. All you have to do is just restarting the application. At the time of restart the new version of the library is picked up! Further: we are able to undeploy the unreferenced "old" library (in my case 1.0,1.0.4). Everything works as expected except the use feedback at the admin console looks inconsistent. Selecting the Library no referenced applications are shown in the corresponding section


Question 1
How about production redeployment for the application in that scenario? It would mean that the application would have NO DOWNTIME. So lets give it a try. I have undeployed the sample app and deployed it as follows:

java weblogic.Deployer -adminurl t3://eden.local:7001 -username weblogic -password welcome1 -upload -targets AdminServer -deploy -source enpittestcommons-reflib.war -appversion 1.0
Note: That the web application shows up with a version information.

Next: We are going to update the library to impl. version 1.0.6

Task 24 completed: [Deployer:149117]deploy library enpit-common-war-lib [LibSpecVersion=1.0,LibImplVersion=1.0.6] on AdminServer.
Deployment succeeded!

Next: Instead of restarting the web application we Redeployit with "-appversion 1.1"

Log: weblogic.Deployer invoked with options:  -adminurl t3://eden.local:7001 -username weblogic -upload -targets AdminServer -deploy -source enpittestcommons-reflib.war -appversion 1.1
<05.06.2013 19:14 Uhr MESZ> <Info> <J2EE Deployment SPI> <BEA-260121> <Initiating deploy operation for application, enpittestcommons-reflib.war#1.1 [archive: /Users/ak/Dropbox/community/doag/doag-2013-imc/use-shared-lib-app/enpittestcommons-reflib.war], to AdminServer .>
Task 25 initiated: [Deployer:149026]deploy application enpittestcommons-reflib.war [Version=1.1] on AdminServer.
Task 25 completed: [Deployer:149026]deploy application enpittestcommons-reflib.war [Version=1.1] on AdminServer.
Target state: deploy completed on Server AdminServer

Now we test the existing connection. It still shows
Library-Version: 1.0,1.0.5

Further open a new Browser and target to the same web app URL gives me :

Library-Version: 1.0,1.0.6

After sessions timed out, we get the following picture

Conclusion

Shared Libraries on WebLogic Server in conjunction with "production redeployment" is a really powerful feature. Applications can upgrade to a library version without downtime!

Next I would like to check if same is possible with shared ADF Libraries. That way it would be possible to update separate application parts (deployed as ADF Libraries) without downtime. Would be really cool!