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!

2 comments:

  1. Hello Andreas,

    good post. Thx. In fact you are using "side by side deployement" which have many limitations that make it not very usefull in "real" life. The recommended approach for this situation is to build a second parralel environment.
    Emmanuel

    ReplyDelete
  2. It's possible show this information in some jspx from my page:

    And indeed, my sample app shows the right information.
    Library-Version: 1.0,1.0.5


    I would like to print the version that my application is in same page.

    ReplyDelete