Tag: jboss-deployment-structure

How to create custom modules in JBossAS7 to load different slots of the jars ?

Hi,

AS 7 does classloading right. It uses JBoss Modules to provide true application isolation, hiding server implementation classes from the application and only loading the classes your application needs. Modules, packaged as collections of classes, are peers that remain isolated unless explicitly defined as a dependency of another module. Visibility rules have sensible defaults, yet can be customized.

Modular classloading is one of the greatest and amazing feature of JBossAS7, but some application server admins are not much aware of this new feature. So here we are going to see a practicle demo of creating a module on JBoss AS7.1.1.Final.

Few Points Which we are going to discuss here:

Point-1). How to create our own custom modules?

Point-2). What is the need of “module.xml” and where to place it?

Point-3). What is “slot” and Why and When to define “slot” in our “module.xml” file?

Point-4). How to reference a module inside our webapplication for classloading purpose?

Point-5). How and why to use the “META-INF/jboss-deployment-structure.xml” or “WEB-INF/jboss-deployment-structure.xml” file?

***NOTE*** This demo is also available in Github:
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/JBossAS7_module_slot_Demo

Developing a Custom Module:

Step-1). Create a directory somewhere in your file system where we will develop our own custom Module with some different versions of class files. Suppose the directory is “/home/userone/CustomModuleTest”

Step-2). Now create a directories structure as “aaa/bbb/1.0” and “aa/bbb/main” inside the directory “/home/userone/CustomModuleTest”.

Step-3). Now write a class with name “Test.java” inside “/home/userone/CustomModuleTest/aaa/bbb/1.0” as following:

package aaa.bbb;
public class Test
  {
     static {
          System.out.println("nntaaa.bbb.Test class Loaded  [VERSION-1.0]");
      }
     public String sayHello(String name)
      {
          System.out.println("nntaaa.bbb.Test sayHello() called");
          return "Mr. " +name;
      }
  }

Step-4). Similarly write a “Test.java” program as following inside the directory “/home/userone/CustomModuleTest/aaa/bbb/main” :

package aaa.bbb;
public class Test
  {
     static {
          System.out.println("nnt[1.2] aaa.bbb.Test class Loaded  [VERSION-1.2]");
      }
     public String sayHello(String name)
      {
          System.out.println("nnt[1.2] aaa.bbb.Test sayHello() called");
          return "Mr. [1.2] " +name;
      }
  }

***NOTE***: The class “aaa.bbb.Test” is same as mentioned in Step3 and Step4 but there is a slight different in the implementation of these classes like the Version of the class is 1.0 and 1.2 as you can see in the static block of the code. This is just to demonstrate that how we can load any version of the same class inside our application with the help of “slot” concept of JBoss Modules.

Step-5). Now we will need to write a file with name “module.xml” inside the directory “/home/userone/CustomModuleTest/aaa/bbb/1.0” as following:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="aaa.bbb" slot="1.0">
    <resources>
        <resource-root path="Test1.0.jar"/>
    </resources>
</module>

Step-6). Now we will need to write another file with name “module.xml” inside the directory “/home/userone/CustomModuleTest/aaa/bbb/main” as following:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="aaa.bbb">
    <resources>
        <resource-root path="Test1.2.jar"/>
    </resources>
</module>

***NOTE*** If we have the same Jars of different versions defined as part of a module then the Jar which is present inside the “main” directory of the module will be utilized by default until the application uses “META-INF/jboss-deployment-structure.xml” or “WEB-INF/jboss-deployment-structure.xml” to mention which “slot” (version) it want to use.

Step-7). Now it’s turn to compile the Test.java class. So open a shell prompt and then make sure that your PATH variable is set properly to point to the JDK bin directory as following:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;%PATH%

Step-8). In the abobe shell prompt now move inside the directory “/home/userone/CustomModuleTest/aaa/bbb/main” to compile the Test.java program and to create a Test1.2.jar file as following:

[userone@localhost 1.0]$ cd /home/userone/CustomModuleTest/aaa/bbb/main

[userone@localhost main]$  javac -d . Test.java 

[userone@localhost main]$  jar cvf Test1.2.jar Test.java aaa/
added manifest
adding: Test.java(in = 321) (out= 174)(deflated 45%)
adding: aaa/(in = 0) (out= 0)(stored 0%)
adding: aaa/bbb/(in = 0) (out= 0)(stored 0%)
adding: aaa/bbb/Test.class(in = 766) (out= 455)(deflated 40%)

Step-9). Similarly we wiill compile the Test.java present inside the “/home/userone/CustomModuleTest/aaa/bbb/1.0”. So in the abobe shell prompt now move inside the directory “/home/userone/CustomModuleTest/aaa/bbb/1.0” to compile the Test.java program and to create a Test1.0.jar file as following:

[userone@localhost 1.0]$ cd /home/userone/CustomModuleTest/aaa/bbb/1.0

[userone@localhost 1.0]$ javac -d . Test.java 

[userone@localhost 1.0]$ jar cvf Test1.0.jar Test.java aaa/
added manifest
adding: Test.java(in = 303) (out= 168)(deflated 44%)
adding: aaa/(in = 0) (out= 0)(stored 0%)
adding: aaa/bbb/(in = 0) (out= 0)(stored 0%)
adding: aaa/bbb/Test.class(in = 748) (out= 448)(deflated 40%)

Step-10). Now just copy and paste your custom module directory “aaa” directory placed inside the “/home/userone/CustomModuleTest” to destination directory “/home/userone/jboss-as-7.1.1.Final/modules”

Step-11). Now restart your JBossAS7 server as following:

     ./standalone.sh  -c standalone-full.xml

Testing the Custom Module and it’s slot:

Now we are going to develop a simple web application which will demonstrate how we can load the module, which has name “aaa.bbb” inside our application. And how to load various versions of the same class “aaa.bbb.Test” with the help of “slot” using “WEB-INF/jboss-deployment-structure.xml”

Step-12). Just create a WebApplication directory “TestCustomModule.war” somewhere in your file system like inside “/home/userone/CustomModuleTest”

Step-14). Write the following kind of simple “index.jsp” page inside our Web Application directory “/home/userone/CustomModuleTest/TestCustomModule.war”

<html>
  <head><title>JBoss Module Testing </title></head>
  <body>

    <%
       aaa.bbb.Test test=new aaa.bbb.Test();
       System.out.println("test.sayHello(JBossAS7) = "+test.sayHello("JBossAS7"));   
       out.println("test.sayHello(JBossAS7) = "+test.sayHello("JBossAS7"));      
    %>
       Hi Check the Console/Log  of your JBoss
  </body>
</html>

Step-15). Create another directory “WEB-INF” as “/home/userone/CustomModuleTest/TestCustomModule.war/WEB-INF” and then palce the following kind of “web.xml” file inside it :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Module Demo JBposs AS7 </display-name>
 
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

</web-app>

Step-16). Create another file with name “jboss-deployment-structure.xml” inside “/home/userone/CustomModuleTest/TestCustomModule.war/WEB-INF”, Now with the help of this file we will specify which version of the “aaa.bbb.Test ” class we want to use in our application.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
  <deployment>
    <dependencies>
      <module name="aaa.bbb" slot="1.0" />
    </dependencies>
  </deployment>
</jboss-deployment-structure>

Step-17). Copy and paste the “TestCustomModule.war” directory inside your JBossAS7 standalone deployment directory “/home/userone/jboss-as-7.1.1.Final/standalone/deployments”

Step-18). Now write a file with name “TestCustomModule.war.dodeploy” inside the JBoss deployment directory “/home/userone/jboss-as-7.1.1.Final/standalone/deployments” to tell JBoss AS7 to deploy our application. (NOTE: as our application is Exploaded directory so we need to create this file otherwise war/jar/ear “FILES” are automatically deployed without creating *.dodeploy file.)

Step-19). Access the application as “http://localhost:8080/TestCustomModule/index.jsp” to see if your JSP file is able to access the “aaa.bbb.Test” class or not? In the JBoss Console (command prompt output/STDOUT) you will see following kind of output.

12:19:37,036 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "TestCustomModule.war"
12:22:54,946 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:22:54,947 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:22:54,947 INFO  [stdout] (http--127.0.0.1-8080-2) 	aaa.bbb.Test class Loaded  [VERSION-1.0]
12:22:54,947 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:22:54,948 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:22:54,949 INFO  [stdout] (http--127.0.0.1-8080-2) 	aaa.bbb.Test sayHello() called
12:22:54,950 INFO  [stdout] (http--127.0.0.1-8080-2) test.sayHello(JBossAS7) = Mr. JBossAS7
12:22:54,950 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:22:54,951 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:22:54,951 INFO  [stdout] (http--127.0.0.1-8080-2) 	aaa.bbb.Test sayHello() called

Further Testing & Verification :

Step-20). At the time of application deployment based on the version of module which you mentioned in your “jboss-deployment-structure.xml”, If your module is loaded and deployed successfully then you will see a file with name “Test1.0.jar.index” or “Test1.2.jar.index” name inside the “/home/userone/jboss-as-7.1.1.Final/modules/aaa/bbb/1.0” or “/home/userone/jboss-as-7.1.1.Final/modules/aaa/bbb/main”

Step-21). Remove the “slot=1.0” attribute in your “” file as following then redeploy your WebApplication then see access the same index.jsp page ….. you will notice that now JBoss AS7 will load the 1.2 version of aaa.bbb.Text class as this is the default version.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
  <deployment>
    <dependencies>
      <module name="aaa.bbb"/>
    </dependencies>
  </deployment>
</jboss-deployment-structure>

Folllowing kind of output your will see now after redeployment of your application :

12:24:52,293 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-4) JBAS015877: Stopped deployment TestCustomModule.war in 165ms
12:24:52,295 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-4) JBAS015876: Starting deployment of "TestCustomModule.war"
12:24:52,365 INFO  [org.jboss.web] (MSC service thread 1-5) JBAS018210: Registering web context: /TestCustomModule
12:24:52,482 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) JBAS018562: Redeployed "TestCustomModule.war"
12:25:00,697 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:25:00,698 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:25:00,698 INFO  [stdout] (http--127.0.0.1-8080-2) 	[1.2] aaa.bbb.Test class Loaded  [VERSION-1.2]
12:25:00,698 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:25:00,699 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:25:00,700 INFO  [stdout] (http--127.0.0.1-8080-2) 	[1.2] aaa.bbb.Test sayHello() called
12:25:00,700 INFO  [stdout] (http--127.0.0.1-8080-2) test.sayHello(JBossAS7) = Mr. [1.2] JBossAS7
12:25:00,701 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:25:00,701 INFO  [stdout] (http--127.0.0.1-8080-2) 
12:25:00,701 INFO  [stdout] (http--127.0.0.1-8080-2) 	[1.2] aaa.bbb.Test sayHello() called

Notice that this time a 1.2 version of aaa.bbb.Test class is loaded by JBoss.

.
.
Thanks 🙂
Middleware Magic Team


Using JAR file placed inside a SAR in JBoss AS7

Hi,

This Demonstration is based on “jboss-as-7.1.0.Beta1” it might require some additional work to be deployed without any issue in other version of JBossAS7, as JBoss will be stable after JBossAS7.1.0Final

Based on the query posted by “http://middlewaremagic.com/jboss/?p=366#comment-40 (kc7bfi)” we are writing this article.
In the previous article “http://middlewaremagic.com/jboss/?p=366” we saw how to create a SAR archive to publish our MBeans inside the JBoss AS7, But many times people face an issue while placing a “Jar” file inside their SAR file on JBoss AS7. As by default the JAR files present inside a SAR file is not loaded automatically in JBoss AS7 so we see many NoClassDeffoundErrors and missing dependencies errors.

In previous article we saw the SAR inside JBoss AS 7 is little different as the class “org.jboss.system.ServiceMBean” and “org.jboss.system.ServiceMBeanSupport” are not present in JBoss AS7. Also the JBoss AS 7 service descriptor (jboss-service.xml) file requires XSD declaration, And without the XSD declaration inside jboss-service.xml file you will see the following kind of Exception while deploying your SAR file.

Point-1). In this article we will see what is the use of “jboss-deployment-structure.xml” file.
Point-2). How to place/use a JAR file inside a SAR file.
Point-3). Why “jboss-deployment-structure.xml” file is needed.

More information on file usages “jboss-deployment-structure.xml” can be found in the following link: https://docs.jboss.org/author/display/AS7/Class+Loading+in+AS7

Developing SAR file with JARs

Step1). Create a directory somewhere in your file system like “/home/userone/ServerMonitorService.sar”.

Step2). Create an MBean interface “MyServerMonitorMBean.java” inside the “/home/userone/ServerMonitorService.sar” directory.

package custom.mbean;
public interface MyServerMonitorMBean
  {
      public void setFrequency(String frequency);
      public String getFrequency();
  }

Step3). Now provide an implementation class of the above MBean interface as “MyServerMonitor.java” inside the directory “/home/userone/ServerMonitorService.sar”. And implement the start() and stop() service if we want to perform some specific operations while jboss starts and stops the service.

package custom.mbean;
import javax.management.*;
import java.io.*;
import java.util.*;
import java.rmi.*;
import javax.naming.*;
public class MyServerMonitor implements MyServerMonitorMBean
  {
      boolean flag=true;
      public String Frequency;

      public MyServerMonitor()
      {
         System.out.println("nnt ServiceMonitorMBean is activated...inside ServiceMonitor() constructor--setting default Frequency=10000 Miliseconds");;
      }

      public void setFrequency(String Frequency)
      {
          System.out.println("nt Server Watch Frequency is set to : "+Frequency+"-Milliseconds");
          this.Frequency=Frequency;
      }

      public String getFrequency()
      {
          System.out.println("nt Server Watch Frequency is set to : "+Frequency+"-Milliseconds");
          return this.Frequency;
      }

     public void start() throws Exception
      {
            System.out.println("nntStarting start() MyServerMonitor invoked");
            Frequency="3000";
      }

     public void stop() throws Exception
      {
            System.out.println("nntStopping stop() MyServerMonitor  invoked");
      }
  }

Step4). Now the most important part, here we need to declare the MBean inside the “/home/userone/ServerMonitorService.sar/META-INF/jboss-service.xml” file as following:

<?xml version="1.0" encoding="UTF-8"?>
<server xmlns="urn:jboss:service:7.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="urn:jboss:service:7.0 jboss-service_7_0.xsd">

    <mbean code="custom.mbean.MyServerMonitor" name="service.server.monitor:service=MyMonitor">
         <attribute name="Frequency">5000</attribute>
    </mbean>

</server>

NOTE: The XSD declaration is required without that you will see parsing error while deploying your service.

Step5). Now compile the “MyServerMonitor.java” and “MyServerMonitorMBean.java” programs and then make a JAR containing these class files. Suppose the Jar file name is “Test.jar”. So place this “Test.jar” file inside the SAR file inside as following “/home/userone/ServerMonitorService.sar/Test.jar”

Step6). Now create a file “jboss-deployment-structure.xml” inside “/home/userone/ServerMonitorService.sar/META-INF/jboss-deployment-structure.xml” as following:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
  <deployment>  
    <dependencies>
      <module name="deployment.ServerMonitorServiceWorking.sar.Test.jar" />
    </dependencies>
    <resources>
      <resource-root path="Test.jar" />
    </resources>
  </deployment>
</jboss-deployment-structure>

Step7).
Deploy the “ServerMonitorService.sar” inside the “jboss-as-7.1.0.Beta1/standalone/deployments” directory of your JBoss. After deploying the service archive you may see the following Message in server’s Console Stdout….Because the “ServerMonitorService.sar” which we are trying to deploy is in Exploded format:

23:19:17,410 INFO  [org.jboss.as.deployment] (DeploymentScanner-threads - 1) Found ServerMonitorService.sar in deployment directory. To trigger deployment create a file called ServerMonitorService.sar.dodeploy

Step8). So create an empty file with name “ServerMonitorService.sar.dodeploy” inside “jboss-as-7.1.0.Beta1/standalone/deployments” to tell jboss to deploy this Service Archive.

NOTE: If you don’t want to see the message which is displayed in Step7) and don’t want to follow Step8).. then deploy your SAR file as an archive file. (similar to how we create jar/war/ear files using jar utility)

JIRA related to current demonstration: https://issues.jboss.org/browse/AS7-887

Related Issues: http://community.jboss.org/thread/173071

TestCase for JBoss AS7.1.1.Final can be downloaded from Github

https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/ServerMonitorServiceWorking.sar

(***NOTE***) In JBoss AS7.1.1.Final i used the following “jboss.deployment-strcture.xml” file Which WORKED for Me…

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
  <deployment>  
     <resources>
         <resource-root path="Test.jar">
         </resource-root>
      </resources>
  </deployment>
</jboss-deployment-structure>

.
.
.
Thanks
Middleware Magic Team


Copyright © 2010-2012 Middleware Magic. All rights reserved. |