22 Dec 2013

Hot Redeployment of ADF Libraries with JRebel

One of the most powerful features of JDeveloper 11gR2 and 12c is the ability of hot redeployment of classes and resources to the integrated WebLogic server. And sometimes it really works, saving a lot of developers' time. You just need to make your changes, rebuild the project, refresh the browser and you are happy.  There is no full redeployment of the entire application.
But it doesn't work with ADF libraries. Any modern large ADF application is split into an number of ADF libraries and developers work mostly with code of those libraries. And in order to get their changes applied, developers need to redeploy a library and restart an application. There is pretty powerful tool JRebel, which can make working with ADF libraries much faster and easier. It can be installed as JDeveloper's plugin and it allows hot redeployment of library's classes and resources likewise classes and resources of the target running project. Even better. With JRebel we don't have to rebuild the entire project in case of making changes to class files, we can just rebuild corresponding classes and that's it.  
The installation process is pretty easy and well described in this manual. Once the plugin has been installed, we have to generate JRebel configuration files (rebel.xml) for the main target project which we actually run and for each project which is going to be deployed as an ADF library:
 

For example, for the ViewController project it will generate something like this:
<?xml version = '1.0' encoding = 'UTF-8'?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd"
     xmlns="http://www.zeroturnaround.com">  
 <classpath>   
  <dir name="/Users/Fedor/jdeveloper/mywork/HotDeployApp/ViewController/adfmsrc"/>
  <dir name="/Users/Fedor/jdeveloper/mywork/HotDeployApp/ViewController/classes">
     <include name="**/*.class"/>
     <exclude name=".wlsjsps/**"/>
  </dir>
  <dir name="/Users/Fedor/jdeveloper/mywork/HotDeployApp/ViewController/src">
    <exclude name="**/*.java"/>
  </dir>
 </classpath>
     
 <web>
   <link target="/">
     <dir name="/Users/Fedor/jdeveloper/mywork/HotDeployApp/ViewController/public_html"/>                  
   </link>
 </web>
</application> 

Note, that absolute paths are used, which is not feng shui. We have to manually edit generated rebel.xml and use a special placeholder ${workspace.path}:

<?xml version = '1.0' encoding = 'UTF-8'?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd"
     xmlns="http://www.zeroturnaround.com">  
 <classpath>   
  <dir name="${workspace.path}/ViewController/adfmsrc"/>
  <dir name="${workspace.path}/ViewController/classes">
     <include name="**/*.class"/>
     <exclude name=".wlsjsps/**"/>
  </dir>
  <dir name="${workspace.path}/ViewController/src">
    <exclude name="**/*.java"/>
  </dir>
 </classpath>
     
 <web>
   <link target="/">
     <dir name="${workspace.path}/ViewController/public_html"/>                  
   </link>
 </web>
</application>


Since the ViewController project is a web project, there is a <web> tag in the file. Actually the same tag is going to be generated for ADF library projects as well, if those projects are web projects containing some task flows. The important thing is that we don't need the <web> tag in the rebel.xml file for ADF library projects. It doesn't work. We have to manually move the public_html dir tag to the <classpath> section:

<?xml version = '1.0' encoding = 'UTF-8'?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd"
    xmlns="http://www.zeroturnaround.com">
   <classpath>
      <dir name="${workspace.path}/TaskFlow/classes">
         <exclude name=".wlsjsps/**"/>
      </dir>
      <dir name="${workspace.path}/TaskFlow/src">
         <exclude name="**/*.java"/>
      </dir>
      <dir name="${workspace.path}/TaskFlow/public_html"/>      
   </classpath>
   <!--
   <web>
      <link target="/">
         <dir name="${workspace.path}/TaskFlow/public_html"/>
      </link>
   </web>-->
</application>   

And in order to get it all working, we need to enable JRebel in JDeveloper before starting the integrated WebLogic server:
And add the following string to Java options:

-noverify -Drebel.adf_core_plugin=true -Drebel.adf_faces_plugin=true -Dworkspace.path=/Users/Fedor/jdeveloper/mywork/HotDeployApp


That's it!

4 comments:

  1. That is elegant Eugene but there are a lot of problems according my experience with JRebel you should try to make all of the artifacts (eg pageDef,adfc-config ...) to be hot deployed by JRebel otherwise if you want to normal deploy and undeploy by JRebel setting in Jdeveloper. You would go into very Slow weblogic response problem!
    Mehdi Mohammadi

    ReplyDelete
  2. Hi Mehdi!
    Yes, WebLogic is getting slower, but not too much. The response time is pretty acceptable. It is recommended to use Make instead of complete Rebuild of the project.
    Anyway, this is much better than wasting time redeploying ADF library and restarting an application each time you need to make a change.

    ReplyDelete
  3. i really like your post.thanks for this post.

    ReplyDelete

Post Comment