Datasource

Server Side Java Script Nashorn, WildFly10, Undertow with MySQL (part-3)

Hi,

This is the third part of in the series of JavaScript in which we are going to see how to implement the Server Side Java Script inside the WildFly 10 Container. As we know that WildFly provides the “undertow” container inside it. Undertow is a flexible performant web server written in java, providing both blocking and non-blocking API’s based on NIO. Undertow has a composition based architecture that allows users to build a web server by combining small single purpose handlers. In order to know more about undertow please refer to: http://undertow.io/

WildFly 10 allows users to use the JavaScript on the server side with the help of the Nashorn JavaScript engine offered by JDK8. So far as part of our previous part-1 and part-2 articles we have learned about Nashorn javascript, jjs command line tool and the JSR-292 APIs which allows us to execute and javascript. If you have not gone through those articles then it is better to have a look at them before we start this demo:

Why Nashorn Java Scripting in Java8, Is it Poisonous for Java? (part-1)

JDK8 Based Nashorn JavaScript & Java to interact with MySQL Database. (part-2)

What this demo is about?

As part of this demo we will learn about the following things:

1. How to create a MySQL DataSource inide the WildFly 10 using jboss-cli.

2. How to include the *.js (java script files) inside the application in WildFly and what is the use of “WEB-INF/undertow-scripts.conf” file.

3. How to execute simple JavaScript inside wildfly/undertow.

4. How to execute Plain JDBC based java script inside the wildfly/undertow.

5. How to lookup the DataSource from the Nashorn java script and fetch customer table data from database.

6. We will also see how to use the “wildfly-maven-plugin” to deploy the Application on Wildfly.

Setting up MySQL Database

Start the MySQL database and then do the following steps which will basically do the following things:
A. Creating a simple Database with name “TestJavaScriptDB”
B. Creating a table with name “CUSTOMER”.
C. Insert some dummy records inside the “CUSTOMER” table.

mysql -u root -p 
password:


mysql> create database TestJavaScriptDB;
Query OK, 1 row affected (0.00 sec)


mysql> use TestJavaScriptDB;
Database changed


mysql> CREATE TABLE CUSTOMER (custId INT(10) NOT NULL, custName CHAR(20) NOT NULL);
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO CUSTOMER VALUES (1000, "MiddlewareMagic");
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO CUSTOMER VALUES (2000, "Customer-2");
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO CUSTOMER VALUES (3000, "Customer-3");
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM CUSTOMER;
+--------+-----------------+
| custId | custName        |
+--------+-----------------+
|   1000 | MiddlewareMagic |
|   2000 | Customer-2      |
|   3000 | Customer-3      |
+--------+-----------------+
3 rows in set (0.01 sec)

Creating DataSource on WildFly10 side.

Now lets create a simple MySQL datasource using jboss-cli.sh script provided by WildFly.

[standalone@localhost:9990 /] module add --name=com.mysql  --dependencies=javax.api,javax.transaction.api --resources=/PATH/TO/mysql-connector-java-5.1.37-bin.jar 


[standalone@localhost:9990 /] /subsystem=datasources/jdbc-driver=mysql/:add(driver-module-name=com.mysql,driver-name=mysql,jdbc-compliant=false,driver-class-name=com.mysql.jdbc.Driver) 
{"outcome" => "success"}

[standalone@localhost:9990 /] /subsystem=datasources/data-source="MySqlDS":add(jndi-name="java:jboss/MySqlDS",driver-name="mysql",connection-url="jdbc:mysql://localhost:3306/TestJavaScriptDB",user-name="root",password="testpwd")
{"outcome" => "success"}

[standalone@localhost:9990 /] :reload
{
    "outcome" => "success",
    "result" => undefined
}

[standalone@localhost:9990 /] /subsystem=datasources/data-source="MySqlDS":test-connection-in-pool()
{
    "outcome" => "success",
    "result" => [true]
}

Once the above jboss-cli commands are executed we should be able to see the following kind of DataSource created inside our wildfly profile (i am using “standalone.xml”).

        <subsystem xmlns="urn:jboss:domain:datasources:4.0">
            <datasources>
                <datasource jndi-name="java:jboss/MySqlDS" pool-name="MySqlDS">
                    <connection-url>jdbc:mysql://localhost:3306/TestJavaScriptDB</connection-url>
                    <driver>mysql</driver>
                    <security>
                        <user-name>root</user-name>
                        <password>testpwd</password>
                    </security>
                </datasource>
                <drivers>
                    <driver name="mysql" module="com.mysql">
                        <driver-class>com.mysql.jdbc.Driver</driver-class>
                    </driver>
                </drivers>
            </datasources>
        </subsystem>

Developing WebApplication containing the Nashorn Script

Now lets start developing the WebApplication so in order to do that lets create some directory structure and to understand where we are going to place which file.

Step-1). Create a directory “Part-3_WildFly_ServerSide_JavaScript” some there in your filesystem.

mkdir Part-3_WildFly_ServerSide_JavaScript

mkdir -p Part-3_WildFly_ServerSide_JavaScript/src/main/webapp/WEB-INF

Step-2). Now lets write the “hello.js” simple script inside the “Part-3_WildFly_ServerSide_JavaScript/src/main/webapp/” directory as following, Where we will define the resource uri “/hello” and its actions.

$undertow.onGet("/hello",
                  { headers: {"content-type": "text/plain"}},
                      [function ($exchange) {
                         return "Hello, MiddlewareMagic!!!";
                   }])

Step-3). Similarly we will write another javascript inside the “Part-3_WildFly_ServerSide_JavaScript/src/main/webapp/” directory with name “testDB.js”. This is a simple javascript file which uses the plain JDBC approach to interact with the Database.

//  ## JDBC Based JavaScript  ##

$undertow
    .onGet("/getCustomerRecords",
        {headers: {"content-type": "text/plain"}},
        [function ($exchange) {
            var con1 = getConnection();
            var customerData = runQuery(con1, "select * from CUSTOMER");
            return "Got Customer Data: " + customerData;
        }])
        
     
     
//  Java Script Functions  //        
var getConnection = function() {
    var Properties = Java.type("java.util.Properties");
    var Driver = Java.type("com.mysql.jdbc.Driver");
    var driver = new Driver();
    var properties = new Properties();
    var conn = null;
    try {
        properties.setProperty("user", "root");
        properties.setProperty("password", "testpwd");
        conn = driver.connect("jdbc:mysql://localhost:3306/TestJavaScriptDB", properties);
        print("****** Got the JDBC Connection : " +conn);
        return conn;
    } finally {
    }
}

// Declaring runQuery function
var runQuery = function(conA, query) {
   var result = "";
   try {
       var stmt = conA.prepareStatement(query);
       var resultSet = stmt.executeQuery();
       print("      --------------------------- ");
       while (resultSet.next()) {
          result = result + " [";
          var rowData = resultSet.getString("custId") + " - " + resultSet.getString("custName");
          print("\t" + rowData);
          result = result + rowData + "], "; 
       }
       print("      --------------------------- ");
       return result;
    } finally {
      if (resultSet)
         try {
            resultSet.close();
            print("\nResultSet Closed.");
         }
         catch(e) {}
      if (stmt)
         try {
            stmt.close();
            print("Statement Closed.");            
         } catch (e) { print( e );  }
      if (conA)        
         try { 
            conA.close();
            print( "Connection Closed." );
         } catch (e) { print( e );  }          
      }  
 } 

//  Following Cals are commended else those wil be executed as soon as WildFly startes deploying this WebApplication.
//var con1 = getConnection();
//runQuery(con1, "select * from CUSTOMER");

Step-4). As above we have seen a plain JDBC interaction based javascript. However we want to use the DataSource concept as well in order to interact with the Database. So here we will be writing another simple Hava Script file “testDataSource.js” inside the directory “Part-3_WildFly_ServerSide_JavaScript/src/main/webapp/” directory with name “testDB.js” and will performa simple JNDI lookup of the DataSource. This shows that we do not need to write so lengthy java scripts as mentioned above in order to interact with the database.

$undertow
    .onGet("/getCustomersViaDataSource",
        {headers: {"content-type": "application/json"}},
        ['jndi:java:jboss/MySqlDS', function ($exchange, db) {
            return db.select("select * from CUSTOMER");
        }])

Step-5). Lets write a simple “index.jsp” page which will have the URL of the above mentioned javascript Get Resources. Lets place this index.jsp file inside the “Part-3_WildFly_ServerSide_JavaScript/src/main/webapp” directory as following:

<HTML>
  <HEAD>
     </TITLE>Nashorn Server Side Java Script Demo Undertow/WildFly</TITLE>
  </HEAD>
  <BODY>
     <Center>

<h3>This is a simple demo explaining how to use Server Side Java Script in WildFly</h3>

       <a href="hello">Click Here to execute to "/hello" resource</a>
       <BR/><BR/>
       <a href="getCustomerRecords">Click Here "/getCustomerRecords" to access customers records from Database</a>  
       <BR/><BR/>
       <a href="getCustomersViaDataSource">Click Here "/getCustomersViaDataSource" to access customers records from Database via DataSource lookup</a>         
      </Center>      
  </BODY>
</HTML>   

Step-6). If needed then we can add the “web.xml” file inside the “Part-3_WildFly_ServerSide_JavaScript/src/main/webapp/WEB-INF” as following (in my case as i do not have anything specific to be written in this file so i am keeping a dummy file here)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" 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_3_0.xsd" version="3.0"> 
</web-app>

Step-7). Now the Most important part. We are going to add the file “undertow-scripts.conf” inside the “Part-3_WildFly_ServerSide_JavaScript/src/main/webapp/WEB-INF”

hello.js
testDB.js
testDataSource.js

NOTE: We need to tell WildFly/Undertow container that where to find our javascript files. So in order to do this we create a file “WEB-INF/undertow-scripts.conf”. In this file we list all our server side JavaScript files one per line. See: http://undertow.io/undertow-docs/undertow-docs-1.3.0/index.html

Step-8). Now we will simply write our Maven “pom.xml” file to build the WAR file containing all the above contents in it and it will also use the “wildfly-maven-plugin<” plugin which will help us in deploying it on WildFly (running on localhost:9990). So lets create “pom.xml” file inside the “Part-3_WildFly_ServerSide_JavaScript” directory as following:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>middleware.magic</groupId>
  <artifactId>WildFlyServerSideJavaScript</artifactId>
  <version>1.0</version>
  <packaging>war</packaging>
  <name>WildFlyServerSideJavaScript</name>
  
  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <version.wildfly.maven.plugin>1.0.2.Final</version.wildfly.maven.plugin>
        <version.wildfly.bom>10.0.0.CR2</version.wildfly.bom>
        <version.wildfly-maven-plugin>1.0.2.Final</version.wildfly-maven-plugin>
        
        <!-- Compiler Related versions -->
        <version.war.plugin>2.5</version.war.plugin>
        <version.maven.compiler.plugin>3.3</version.maven.compiler.plugin>
        <maven.compiler.target>1.7</maven.compiler.target>
        <maven.compiler.source>1.7</maven.compiler.source>
  </properties>  
  
  
  <dependencyManagement>
      <dependencies>
         <dependency>
            <groupId>org.wildfly.bom</groupId>
            <artifactId>jboss-javaee-7.0-wildfly</artifactId>
            <version>${version.wildfly.bom}</version>
            <scope>import</scope>
         </dependency>
      </dependencies>
  </dependencyManagement> 

  <dependencies>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-web-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.37</version>
   </dependency>
  </dependencies>
  
  <build>
   <finalName>WildFlyServerSideJavaScript</finalName>   <!-- WAR name -->
   <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${version.maven.compiler.plugin}</version>
        <configuration>
          <source>${maven.compiler.target}</source>
          <target>${maven.compiler.source}</target>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>${version.war.plugin}</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
        
        <!-- The WildFly Maven Plugin deploys your war to a local WildFly container -->
        <!-- To use, set the JBOSS_HOME environment variable and run: mvn package wildfly:deploy -->
      <plugin>
         <groupId>org.wildfly.plugins</groupId>
         <artifactId>wildfly-maven-plugin</artifactId>
         <version>${version.wildfly-maven-plugin}</version>
      </plugin>
   </plugins>
  </build>
  
</project>

Building and Deploying the application

Lets build and deploy this application as following , Start WildFly default profile “standalone.xml” and open a terminal to run the maven build.

Setting up the environment:
For Unix Based OS

$ export M2_HOME=/PATH/TO/apache_maven_3.2.3
$ export JAVA_HOME=/PATH/TO/jdk1.8.0_60
$ export PATH=$JAVA_HOME/bin:/PATH/TO/apache_maven_3.2.3/bin:$PATH

$ cd Part-3_WildFly_ServerSide_JavaScript
$ mvn clean install

For Windows Based OS

$ set M2_HOME=C:\PATH\TO\apache_maven_3.2.3
$ set JAVA_HOME=C:\PATH\TO\jdk1.8.0_60
$ set PATH=%JAVA_HOME%/bin;C:\PATH\TO\apache_maven_3.2.3\bin;%PATH%

$ cd C:\Part-3_WildFly_ServerSide_JavaScript
$ mvn clean install 

Now make sure that wildfly is ruinning on localhost:9990 , run the maven build as following [mvn clean install wildfly:deploy] the wildfly:deploy task will find the running wildfly instance and will automatically deploy the WAR.


$ mvn clean install wildfly:deploy

########
OUTOUT
########
[INFO] Scanning for projects...
[WARNING] 
[WARNING] Some problems were encountered while building the effective model for middleware.magic:WildFlyServerSideJavaScript:war:1.0
[WARNING] 'dependencyManagement.dependencies.dependency.type' for org.wildfly.bom:jboss-javaee-7.0-wildfly:jar must be 'pom' to import the managed dependencies. @ line 28, column 22
[WARNING] 
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING] 
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING] 
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building WildFlyServerSideJavaScript 1.0
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ WildFlyServerSideJavaScript ---
[INFO] Deleting /Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ WildFlyServerSideJavaScript ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.3:compile (default-compile) @ WildFlyServerSideJavaScript ---
[INFO] No sources to compile
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ WildFlyServerSideJavaScript ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ WildFlyServerSideJavaScript ---
[INFO] No sources to compile
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ WildFlyServerSideJavaScript ---
[INFO] No tests to run.
[INFO] 
[INFO] --- maven-war-plugin:2.5:war (default-war) @ WildFlyServerSideJavaScript ---
[INFO] Packaging webapp
[INFO] Assembling webapp [WildFlyServerSideJavaScript] in [/Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/target/WildFlyServerSideJavaScript]
[INFO] Processing war project
[INFO] Copying webapp resources [/Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/src/main/webapp]
[INFO] Webapp assembled in [54 msecs]
[INFO] Building war: /Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/target/WildFlyServerSideJavaScript.war
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ WildFlyServerSideJavaScript ---
[INFO] Installing /Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/target/WildFlyServerSideJavaScript.war to /Users/jsensharma/.m2/repository/middleware/magic/WildFlyServerSideJavaScript/1.0/WildFlyServerSideJavaScript-1.0.war
[INFO] Installing /Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/pom.xml to /Users/jsensharma/.m2/repository/middleware/magic/WildFlyServerSideJavaScript/1.0/WildFlyServerSideJavaScript-1.0.pom
[INFO] 
[INFO] >>> wildfly-maven-plugin:1.0.2.Final:deploy (default-cli) > package @ WildFlyServerSideJavaScript >>>
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ WildFlyServerSideJavaScript ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.3:compile (default-compile) @ WildFlyServerSideJavaScript ---
[INFO] No sources to compile
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ WildFlyServerSideJavaScript ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ WildFlyServerSideJavaScript ---
[INFO] No sources to compile
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ WildFlyServerSideJavaScript ---
[INFO] No tests to run.
[INFO] Skipping execution of surefire because it has already been run for this configuration
[INFO] 
[INFO] --- maven-war-plugin:2.5:war (default-war) @ WildFlyServerSideJavaScript ---
[INFO] Packaging webapp
[INFO] Assembling webapp [WildFlyServerSideJavaScript] in [/Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/target/WildFlyServerSideJavaScript]
[INFO] Processing war project
[INFO] Copying webapp resources [/Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/src/main/webapp]
[INFO] Webapp assembled in [5 msecs]
[INFO] Building war: /Users/jsensharma/NotBackedUp/MM_Tests/WildFly/JavaScript/Java_8_Nashorn_WildFly/Part-3_WildFly_ServerSide_JavaScript/target/WildFlyServerSideJavaScript.war
[INFO] 
[INFO] <<< wildfly-maven-plugin:1.0.2.Final:deploy (default-cli) < package @ WildFlyServerSideJavaScript <<<
[INFO] 
[INFO] --- wildfly-maven-plugin:1.0.2.Final:deploy (default-cli) @ WildFlyServerSideJavaScript ---
Nov 27, 2015 4:18:54 PM org.xnio.Xnio <clinit>
INFO: XNIO version 3.2.2.Final
Nov 27, 2015 4:18:55 PM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.2.2.Final
Nov 27, 2015 4:18:55 PM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 4.0.3.Final
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.741 s
[INFO] Finished at: 2015-11-27T16:18:55+05:30
[INFO] Final Memory: 14M/245M
[INFO] ------------------------------------------------------------------------

Source code for this demo is present in :
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/WildFly/Java_8/ServerSideJavaScript/Part-3_WildFly_ServerSide_JavaScript
.
.
Regards
Jay SenSharma


Client side Native Management API for monitoring JBossAS7.1.2

Hi,

JBossAS7 is one of the best application server which provides various options to control/manage/monitor the application resources using various options like jboss-cli.sh (CLI scripts) , jboss management console, JSON based monitoring & management using curl/wget, JBoss Native Management APIs …etc

Here in this article we will see how we can manage & monitor JBossAS 7.1.2 using JBoss Native Management APIs, this approach is best for the java developers, as in many production environments it is very convenient to manage the application respources based on java code. The developers wants to mmanage things using java style of programming, So for those develpers JBoss Native Management APIs is much convenient way of managing the JBoss.

More informations on this can be found in the following link: https://docs.jboss.org/author/display/AS7/The+native+management+API

The Source code for the following Demo is available in the github repository:
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/NativeManagement_API_JBossAS712

Step1). First of all we will create a directory somewhere in our file system as “/home/jaysensharma/NativeManagement_API_JBossAS712” and then we will create a directory with name “src” inside “/home/jaysensharma/NativeManagement_API_JBossAS712”:

Step2). Now we will use the “org.jboss.as.controller.client.ModelControllerClient” API to establish connection to the JBoss Server/Controller, So create a program as “NativeManagementClient.java” inside “/home/jaysensharma/NativeManagement_API_JBossAS712/src” as following:

import java.net.UnknownHostException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.sasl.RealmCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.ModelControllerClient.Factory;
import java.net.InetAddress;
import java.io.IOException;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;


public class NativeManagementClient
{
    //static String host = "10.10.10.96"; // "localhost";
    static String host = "localhost";
    static int port = 9999;
    static String password = "admin";
    static String userid = "admin123";
    static String hostControllerName="master";
    static String serverName="JayServer";
    static boolean standaloneMode=true;     //  If you are running your Servers in Domain Mode then set this to false.
    static ModelControllerClient client = null;

    public static void main (String[] args)
       {
           try {
                 createAndCheckClientConnection();
                 performOperations(client);
               }

           catch (java.io.IOException ex)
               {
                 System.out.println("nn Unable to Connect to the Host: "+host+" or Port:"+port+"tt" + ex.getMessage());
                 //ex.printStackTrace();
               }
           catch (Exception ex)
               {
                 System.out.println("nnSomeThing is Wrong: "+ex.getMessage());
                 //ex.printStackTrace();
               }

           try {
                 if (client != null ) client.close();
               }
           catch (Exception e)
               {
                 System.out.println ("Exception: " + e.getMessage());
                 e.printStackTrace();
               }
        }


    public static void createAndCheckClientConnection() throws IOException
     {
                 // NOTE: For hostname as "localhost" there is no need to pass the username & password  */
                 //client = ModelControllerClient.Factory.create(host, port, null);

                 // If you are running this program remotely then you need to pass the credentials */
                 client = createClient (InetAddress.getByName(host), port, userid, password.toCharArray(), "ManagementRealm" );
                 System.out.println("Got the client: "+client);

                 // Checking whether Client is actually connected to Controller or not by executing dummy ModelNode? */
                 ModelNode op = new ModelNode();
                 op.get("operation").set("read-resource");
                 ModelNode returnVal=client.execute(op);
                 System.out.println("nnrelease-version: " + returnVal.get("result").get("release-version").asString());
                 System.out.println("release-codename: " + returnVal.get("result").get("release-codename").asString());
     }

   public static void performOperations(ModelControllerClient client)
      {
                  if(standaloneMode==true)
                     {
                        // FOR STANDALONE MODE use the "TestStandaloneModel" class as following:
                        TestStandaloneModel testStandaloneModel=new TestStandaloneModel();

                        // Getting Web Subsystem runtime Details */
                        testStandaloneModel.getWebSubsystemRuntimeDetails(client);
                        // Testing Non XA DataSource ExampleDS */
                        testStandaloneModel.testNonXADataSource(client,"ExampleDS");
                        // Monitoring Application Statistics where application name is "Log4jDemo.war" */
                        testStandaloneModel.monitorApplicationStatistics(client,"Log4jDemo.war");
                     }
                  if(standaloneMode==false)
                    {
                        TestDomainModeModel testDomainModeModel= new TestDomainModeModel();
                        // Getting Web Subsystem runtime Details */
                        testDomainModeModel.getWebSubsystemRuntimeDetails(client,hostControllerName,serverName);
                        // Testing Non XA DataSource ExampleDS */
                        testDomainModeModel.testNonXADataSource(client,hostControllerName,serverName,"ExampleDS");
                        // Monitoring Application Statistics where application name is "Log4jDemo.war" */
                        testDomainModeModel.monitorApplicationStatistics(client,hostControllerName,serverName,"Log4jDemo.war");
                    }
      }

     static ModelControllerClient createClient (final InetAddress host, final int port, final String username, final char[] password, final String securityRealmName)
      {
         final CallbackHandler callbackHandler = new CallbackHandler() {
                 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
                   {
                       for (Callback current : callbacks) {
                          if (current instanceof NameCallback) {
                             NameCallback ncb = (NameCallback) current;
                             System.out.println("nttncb.setName() = "+new String(password));
                             ncb.setName(new String(password));
                            } else if (current instanceof PasswordCallback) {
                             PasswordCallback pcb = (PasswordCallback) current;
                             System.out.println("nttpcb.setPassword() = "+username);
                             pcb.setPassword(username.toCharArray());
                            } else if (current instanceof RealmCallback) {
                             RealmCallback rcb = (RealmCallback) current;
                             System.out.println("nttrcb.getDefaulttest() = "+rcb.getDefaultText());
                             rcb.setText(securityRealmName);
                            } else {
                             throw new UnsupportedCallbackException(current);
                        }
                    }
               }
             };
          return ModelControllerClient.Factory.create(host, port, callbackHandler);
       }
}

Step3). This step is for accessing JBoss informations in Standalone Mode, The most important part here we will write “TestStandaloneModel.java” program inside the “/home/jaysensharma/NativeManagement_API_JBossAS712/src” using the “org.jboss.dmr.ModelNode” and “ModelControllerClient” in order to access the “web” subsystem, deployment and “DataSource statistics” related informations as following:

import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.as.controller.client.ModelControllerClient;

public class TestStandaloneModel
  {
   public void getWebSubsystemRuntimeDetails(ModelControllerClient client)
    {
       System.out.println("nnn************************************************");
       System.out.println("Web Subsystem Runtime Details");
       System.out.println("************************************************");
       try{
             ModelNode op = new ModelNode();
             op.get("operation").set("read-resource");
             ModelNode address = op.get("address");
             address.add("subsystem", "web");
             address.add("connector", "http");
             op.get("recursive").set(true);
             op.get("include-runtime").set(true);
             op.get("operations").set(true);

             ModelNode returnVal = client.execute(op);
             String result=returnVal.get("result").toString();
             String path="/subsystem=web/connector=http";
             if(result.equals("undefined"))
                {
                   System.out.println("ntCheck ["+path+"] ** Server may not be Running");
                }
             else
                {
                   System.out.println(returnVal.get("result").toString());
                }
          }
        catch(Exception e)
          {
             e.printStackTrace();
             System.out.println("getWebSubsystemRuntimeDetails Failed: "+e);
          }
    }


   public void testNonXADataSource(ModelControllerClient client,String dataSourceName)
    {
       System.out.println("nnn************************************************");
       System.out.println("DataSource ""+dataSourceName+"" TestResults");
       System.out.println("************************************************");

       try{
             ModelNode op = new ModelNode();
             op.get("operation").set("test-connection-in-pool");
             ModelNode address = op.get("address");
             address.add("subsystem", "datasources");
             address.add("data-source", dataSourceName);
             op.get("operations").set(true);

             ModelNode returnVal = client.execute(op);
             String result=returnVal.get("result").toString();
             String path="/subsystem=datasources/data-source="+dataSourceName;
             if(result.equals("[true]"))
                {
                   System.out.println("ntNon XA DataSource ""+dataSourceName+"" is RUNNING Successfully.");
                }
             else if(result.equals("[false]"))
                {
                   System.out.println("ntNon XA DataSource ""+dataSourceName+"" is TEST FAILED Successfully. Check PATH exist or not? ["+path+"]");
                }
             else if(result.equals("undefined"))
                {
                   System.out.println("ntDataSource ""+dataSourceName+"" might not be deployed, ["+path+"]  ** Server may not be Running"+"Please Check the DataSource ""+dataSourceName+"" name, It may be INCORRECT. ntCheck PATH exist or not? ["+path+"]");
                }
          }
        catch(Exception e)
          {
             e.printStackTrace();
             System.out.println("testNonXADataSource Failed: "+e);
          }
    }


   public void monitorApplicationStatistics(ModelControllerClient client,String applicationName)
    {
       System.out.println("nnn******************************************************");
       System.out.println("Application ""+applicationName+"" RuntimeStatistics");
       System.out.println("******************************************************");
       try{
             ModelNode op = new ModelNode();
             op.get("operation").set("read-resource");
             ModelNode address = op.get("address");
             address.add("deployment", applicationName);
             op.get("recursive").set(true);
             op.get("include-runtime").set(true);
             op.get("include-defaults").set(true);
             op.get("operations").set(true);

             ModelNode returnVal = client.execute(op);
             String result=returnVal.get("result").toString();
             String path="/deployment="+applicationName;
             if(result.equals("undefined"))
                {
                   System.out.println("ntApplication ""+applicationName+ "" might not have deployed. ** Server may not be Running. Check PATH exist or not? ["+path+"]");
                }
             else
                {
                   System.out.println("ntMonitoring ""+applicationName+ """+result);
                }
          }
        catch(Exception e)
          {
             e.printStackTrace();
             System.out.println("testNonXADataSource Failed: "+e);
          }
    }
  }

Step4). This step is for accessing JBoss informations of JBoss instances running in Domain Mode, The most important part here we will write “TestDomainModeModel.java” program inside the “/home/jaysensharma/NativeManagement_API_JBossAS712/src” using the “org.jboss.dmr.ModelNode” and “ModelControllerClient” in order to access the “web” subsystem, deployment and “DataSource statistics” related informations as following:

import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.as.controller.client.ModelControllerClient;

public class TestDomainModeModel
  {
   public void getWebSubsystemRuntimeDetails(ModelControllerClient client,String hostControllerName,String serverName)
    {
       System.out.println("nnn************************************************");
       System.out.println("Web Subsystem Runtime Details");
       System.out.println("************************************************");
       try{
             ModelNode op = new ModelNode();
             op.get("operation").set("read-resource");
             ModelNode address = op.get("address");
             address.add("host", hostControllerName);
             address.add("server", serverName);
             address.add("subsystem", "web");
             address.add("connector", "http");
             op.get("recursive").set(true);
             op.get("include-runtime").set(true);
             op.get("operations").set(true);

             ModelNode returnVal = client.execute(op);
             String result=returnVal.get("result").toString();
             String path="/host="+hostControllerName+"/server="+serverName+"/subsystem=web/connector=http";
             if(result.equals("undefined"))
                {
                   System.out.println("ntCheck ["+path+"] ** HostController HostController or Server may not be Running");
                }
             else
                {
                   System.out.println(returnVal.get("result").toString());
                }
          }
        catch(Exception e)
          {
             e.printStackTrace();
             System.out.println("getWebSubsystemRuntimeDetails Failed: "+e);
          }
    }


   public void testNonXADataSource(ModelControllerClient client,String hostControllerName,String serverName,String dataSourceName)
    {
       System.out.println("nnn************************************************");
       System.out.println("DataSource ""+dataSourceName+"" TestResults");
       System.out.println("************************************************");

       try{
             ModelNode op = new ModelNode();
             op.get("operation").set("test-connection-in-pool");
             ModelNode address = op.get("address");
             address.add("host", hostControllerName);
             address.add("server", serverName);
             address.add("subsystem", "datasources");
             address.add("data-source", dataSourceName);
             op.get("operations").set(true);

             ModelNode returnVal = client.execute(op);
             String result=returnVal.get("result").toString();
             String path="/host="+hostControllerName+"/server="+serverName+"/subsystem=datasources/data-source="+dataSourceName;
             if(result.equals("[true]"))
                {
                   System.out.println("ntNon XA DataSource ""+dataSourceName+"" is RUNNING Successfully.");
                }
             else if(result.equals("[false]"))
                {
                   System.out.println("ntNon XA DataSource ""+dataSourceName+"" is TEST FAILED Successfully. Check PATH exist or not? ["+path+"]");
                }
             else if(result.equals("undefined"))
                {
                   System.out.println("ntDataSource ""+dataSourceName+"" might not be deployed on this ["+path+"]  ** HostController or Server may not be Running"+"Please Check the DataSource ""+dataSourceName+"" name, It may be INCORRECT. ntCheck PATH exist or not? ["+path+"]");
                }
          }
        catch(Exception e)
          {
             e.printStackTrace();
             System.out.println("testNonXADataSource Failed: "+e);
          }
    }


   public void monitorApplicationStatistics(ModelControllerClient client,String hostControllerName,String serverName,String applicationName)
    {
       System.out.println("nnn******************************************************");
       System.out.println("Application ""+applicationName+"" RuntimeStatistics");
       System.out.println("******************************************************");
       try{
             ModelNode op = new ModelNode();
             op.get("operation").set("read-resource");
             ModelNode address = op.get("address");
             address.add("host", hostControllerName);
             address.add("server", serverName);
             address.add("deployment", applicationName);
             op.get("recursive").set(true);
             op.get("include-runtime").set(true);
             op.get("include-defaults").set(true);
             op.get("operations").set(true);

             ModelNode returnVal = client.execute(op);
             String result=returnVal.get("result").toString();
             String path="/host="+hostControllerName+"/server="+serverName+"/deployment="+applicationName;
             if(result.equals("undefined"))
                {
                   System.out.println("ntApplication ""+applicationName+ "" might not have deployed on this host="+hostControllerName+"/server="+serverName+"  ** HostController or Server may not be Running. Check PATH exist or not? ["+path+"]");
                }
             else
                {
                   System.out.println("ntMonitoring ""+applicationName+ """+result);
                }
          }
        catch(Exception e)
          {
             e.printStackTrace();
             System.out.println("testNonXADataSource Failed: "+e);
          }
    }
  }

Step5). Now the most important part of building & running the Native Management API client which we created, so in order to achieve that we will create a simple ant build script, So Create a “build.xml” file inside the “/home/jaysensharma/NativeManagement_API_JBossAS712” directory as following:

<project name="JBossAS712NativeManagementClient" default="all">
<property name="jboss.home" value="/home/jaysensharma/jboss-as-7.1.2.Final" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="src.dir" value="src" />
<property name="output.dir" value="build" />
<property name="client.jar.name" value="jbossModelAPIClient.jar" />

        <!-- Following 5 Jars are needed for Client. Client Needs the following Jar to be present in the CLASSPATH including -->
        <path id="jboss.client.classpath">
           <fileset dir="${jboss.module.dir}/org/jboss/as/controller-client/main">
               <include name="jboss-as-controller-client*.jar"/>
           </fileset>
           <fileset dir="${jboss.module.dir}/org/jboss/threads/main">
               <include name="jboss-threads*.jar"/>
           </fileset>
           <fileset dir="${jboss.module.dir}/org/jboss/as/protocol/main">
               <include name="jboss-as-protocol*.jar"/>
           </fileset>

           <fileset dir="${jboss.module.dir}/org/jboss/dmr/main">
               <include name="jboss-dmr*.jar"/>
           </fileset>
           <fileset dir="${jboss.home}/bin/client" >
               <include name="jboss-client.jar" />
           </fileset>
        </path>

        <target name="all" depends="run" />

        <target name="run">
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
           <delete dir="${output.dir}" />
           <mkdir dir="${output.dir}" />
           <javac srcdir="${src.dir}" destdir="${tmp.dir}"  includes="NativeManagementClient.java,TestStandaloneModel.java,TestDomainModeModel.java" classpathref="jboss.client.classpath"/>
           <jar jarfile="${output.dir}/${client.jar.name}" basedir="${tmp.dir}" compress="true" />
           <delete dir="${tmp.dir}"/>
           <java classname="NativeManagementClient" fork="true">
               <classpath>
                  <pathelement location="${output.dir}/${client.jar.name}"/>
                  <path refid="jboss.client.classpath"/>
               </classpath>
           </java>
        </target>

</project>

NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script to point to your own JBoss AS7 directory. It requires 5 Jars to be present in the Client’s classpath as mentioned in the above xml file.

Step-6). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/jaysensharma/jdk1.6.0_21/bin:/home/jaysensharma/org.apache.ant_1.6.5/bin:$PATH

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

Step-7). Now once the PATH is set In the command/Shell prompt you can move inside the directory “/home/jaysensharma/NativeManagement_API_JBossAS712” and then run the ant to build and deploy the EJB based EAR applicationon your JBoss Standalone full profile, by running the command “ant deploy”

[jsenshar@localhost NativeManagement_API_JBossAS712]$ ant
Buildfile: build.xml

run:
    [mkdir] Created dir: /home/jaysensharma/NativeManagement_API_JBossAS712/tmp
   [delete] Deleting directory /home/jaysensharma/NativeManagement_API_JBossAS712/build
    [mkdir] Created dir: /home/jaysensharma/NativeManagement_API_JBossAS712/build
    [javac] Compiling 3 source files to /home/jaysensharma/NativeManagement_API_JBossAS712/tmp
      [jar] Building jar: /home/jaysensharma/NativeManagement_API_JBossAS712/build/jbossModelAPIClient.jar
   [delete] Deleting directory /home/jaysensharma/NativeManagement_API_JBossAS712/tmp
      Got the client: org.jboss.as.controller.client.impl.RemotingModelControllerClient@7f971afc
      Nov 27, 2012 12:06:02 AM org.xnio.Xnio <clinit>
      INFO: XNIO Version 3.0.4.GA-redhat-1
      Nov 27, 2012 12:06:02 AM org.xnio.nio.NioXnio <clinit>
      INFO: XNIO NIO Implementation Version 3.0.4.GA-redhat-1
      Nov 27, 2012 12:06:02 AM org.jboss.remoting3.EndpointImpl <clinit>
      INFO: JBoss Remoting version 3.2.8.GA-redhat-1
     
     
      release-version: 7.1.2.Final-redhat-1
      release-codename: Steropes
     
     
     
      ************************************************
      Web Subsystem Runtime Details
      ************************************************
      {
          "bytesReceived" => "0",
          "bytesSent" => "0",
          "enable-lookups" => false,
          "enabled" => true,
          "errorCount" => "0",
          "executor" => undefined,
          "max-connections" => undefined,
          "max-post-size" => 2097152,
          "max-save-post-size" => 4096,
          "maxTime" => "0",
          "name" => "http",
          "processingTime" => "0",
          "protocol" => "HTTP/1.1",
          "proxy-name" => undefined,
          "proxy-port" => undefined,
          "redirect-port" => 8433,
          "requestCount" => "0",
          "scheme" => "http",
          "secure" => false,
          "socket-binding" => "http",
          "ssl" => undefined,
          "virtual-server" => undefined
      }
     
     
     
      ************************************************
      DataSource "ExampleDS" TestResults
      ************************************************
     
      	Non XA DataSource "ExampleDS" is RUNNING Successfully.
     
     
     
      ******************************************************
      Application "Log4jDemo.war" RuntimeStatistics
      ******************************************************
     
      	Monitoring "Log4jDemo.war"{
          "content" => [{
              "path" => "deployments/Log4jDemo.war",
              "relative-to" => "jboss.server.base.dir",
              "archive" => true
          }],
          "enabled" => true,
          "name" => "Log4jDemo.war",
          "persistent" => false,
          "runtime-name" => "Log4jDemo.war",
          "status" => "OK",
          "subdeployment" => undefined,
          "subsystem" => {"web" => {
              "active-sessions" => 0,
              "context-root" => "/Log4jDemo",
              "duplicated-session-ids" => 0,
              "expired-sessions" => 0,
              "max-active-sessions" => 0,
              "rejected-sessions" => 0,
              "session-avg-alive-time" => 0,
              "session-max-alive-time" => 0,
              "sessions-created" => 0,
              "virtual-host" => "default-host",
              "servlet" => {"servlets.TestServlet" => {
                  "load-time" => 0L,
                  "maxTime" => 9223372036854775807L,
                  "min-time" => 0L,
                  "processingTime" => 0L,
                  "requestCount" => 0,
                  "servlet-class" => "servlets.TestServlet",
                  "servlet-name" => "servlets.TestServlet"
              }}
          }}
      }

all:

BUILD SUCCESSFUL
Total time: 2 seconds

Step-8). If you are running your JBoss in Domain mode then you need to just edit the “NativeManagementClient.java” file, and just change the variable “standaloneMode” value to “false” as following:

static boolean standaloneMode=false;

.
.
Thanks
MiddlewareMagic Team 🙂


SAR dependency alternate approach using @Singleton in JBossAS7.1.2

Hi,

SAR files are called as Service Archives. The extension of SAR files are *.sar which contains a “META-INF/jboss-service.xml” file, this file describes the custom MBeans which has to be exposed at the time of deployment or JBoss Startup. JBoss’s service archive architecture is based on the JMX and the SAR files which are basically JBoss specific can be deployed in the jboss inorder to publish your MBean based services. At the time of JBoss startup these service archive deployer (SARDeployer) instantiates the JBoss service classes and exposes them as manageable beans through JMX.

In previous release of JBoss 5/6 the SAR provided mbeans dependency could be very easily defined using <depends> tag, as following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE server>
<server>
    <mbean code="custom.mbean.MyServerMonitor" name="service.server.monitor:service=MyMonitor">
         <attribute name="Frequency">5000</attribute>
         <depends>jboss.jca:service=DataSourceBinding,name=MySqlDS</depends>
    </mbean>
</server>

@org.jboss.ejb3.annotation.Service and @org.jboss.ejb3.annotation.Management are no longer supported which could be used to define Services. However in JBossAS7 this approach of defining the dependency is not good and you may see following kind of exceptions at the time of server startup:

JBAS014775:    New missing/unsatisfied dependencies:
      service jboss.mbean.service."jboss.as:subsystem=datasources,data-source=MySqlDS".create (missing) dependents: [service jboss.mbean.service."service.server.monitor:service=MyMonitor".create]
      service jboss.mbean.service."jboss.as:subsystem=datasources,data-source=MySqlDS".start (missing) dependents: [service jboss.mbean.service."service.server.monitor:service=MyMonitor".start]

JBossAS7 is fully EE6 certified application server and it provides a much better approach to create a Service with the help of EJB3.1 specific “javax.ejb.Startup” and “javax.ejb.Singleton” annotations. This kind of service can be made dependent to other services like DataSource. In this example we will see What is the better approach to define a service (without using container specific SAR feature).

The Source code for this demo can be found in the following github link:
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/SingletonServiceDemo

Creating DataSource in JBossAS7.1.2

As we are going make our Service dependent on a DataSource, sothat we can see how the dependency goes.

Configuration-1). So here first of all we will create a DataSource by running the following CLI script in batch mode. So create a file with name “createDataSource.cli” somewhere in your filesystem like “/home/jaysensharma/SingletonServiceDemo/createDataSource.cli” as following:

deploy  /home/jaysensharma/SingletonServiceDemo/mysql-connector-java-5.1.13-bin.jar

/subsystem=datasources/data-source="MySqlDS":add(jndi-name="java:jboss/datasources/MySqlDS",driver-name="mysql-connector-java-5.1.13-bin.jar",connection-url="jdbc:mysql://localhost:3306/testDB",user-name="root",password="redhat")

Configuration-2). Now start your “$JBOSS_HOME/bin/jboss-cli.sh” script in order to run the above deploy the mysql driver and create DataSource as following:

./jboss-cli.sh -c --controller=10.10.10.10:9999 --file=/home/jaysensharma/SingletonServiceDemo/createDataSource.cli

Configuration-3). As soon as you will run the cli script as mentioned above you will see that the following kind of datasource is created on your standalone*.xml.

                <datasource jndi-name="java:jboss/datasources/MySqlDS" pool-name="MySqlDS">
                    <connection-url>jdbc:mysql://localhost:3306/testDB</connection-url>
                    <driver>mysql-connector-java-5.1.13-bin.jar</driver>
                    <security>
                        <user-name>root</user-name>
                        <password>redhat</password>
                    </security>
                </datasource>

Creating @Singleton service dependent on the DataSource

Step1). First of all we will create a directory somewhere in our file system as “/home/jaysensharma/SingletonServiceDemo” and then we will create a directory with name “src” inside “/home/jaysensharma/SingletonServiceDemo”:

Step2). Now write a @Startup @Singleton EJB3.1 service using “SingletonServiceBean.java” inside “/home/jaysensharma/SingletonServiceDemo/src” as following:

package sar.dependency.alternative;
import javax.ejb.Startup;
import javax.ejb.Singleton;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

//commons logging
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

// DataSource related
import javax.sql.DataSource;
import java.sql.Connection;

// Resource Injection related
import javax.annotation.Resource;

@Startup
@Singleton

public class SingletonServiceBean
 {
     private static Log logger = LogFactory.getLog(SingletonServiceBean.class);
     Connection con=null;


     public SingletonServiceBean()
            {
               logger.info("SingletonServiceBean constructor invoked.");
            }


     @Resource(name = "java:jboss/datasources/MySqlDS")
     DataSource ds;
     /* This @PostConstruct annotation is required to tell JBoss to invoke the "performOperations" immediately after the "SingletonServiceBean" creation. */
     @PostConstruct
     public void performOperations()
	    {
               logger.info("SingletonServiceBean performOperations() invoked.");
               try{
                     con=ds.getConnection();
                     logger.info("***** DataSource = "+ds+" . Connection con = "+con+" retrieved from the ConnectionPool.*****");
                  }
               catch(Exception e)
                 {
                     logger.error("Unable to get Connection From DataSource = "+ds+" ERROR: "+e.getMessage());
                     e.printStackTrace();
                 }
	    }


	@PreDestroy
	public void cleanUp() throws Exception {
	  logger.info("cleaning up connections.");
          if(con!=null)
            {
               try{
                     con.close();
                     logger.info("Connection con = "+con+" is successfully returned to the ConnectionPool.");
                  }
               catch(Exception e)
                 {
                     logger.error("Unable to Close Connection con = "+con+" ERROR: "+e.getMessage());
                     e.printStackTrace();
                 }
               finally{
                        try{   con.close(); }
                        catch(Exception ee) { ee.printStackTrace(); }
                      }
            }
	}
 }

Step3). Now the most important part of building / deploying the Singleton Service which we created, so in order to achieve that we will create a simple ant build script, So Create a “build.xml” file inside the “/home/jaysensharma/SingletonServiceDemo” directory as following:

<project name="SingletonStartupService" default="all">
<property name="jboss.home" value="/home/jaysensharma/jboss-as-7.1.2.Final" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="src.dir" value="src" />
<property name="output.dir" value="build" />
<property name="ear.name" value="TestSingletonService.ear" />
<property name="ejb.jar" value="singletonServiceEJB.jar" />


        <path id="jboss.classpath">
           <fileset dir="${jboss.module.dir}">
               <include name="**/*.jar"/>
           </fileset>
        </path>

        <target name="all" depends="deploy" />

        <target name="build_ear">
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
           <javac srcdir="${src.dir}" destdir="${tmp.dir}"  includes="*.java" classpathref="jboss.classpath"/>

           <jar jarfile="${tmp.dir}/${ejb.jar}" basedir="${tmp.dir}" compress="true" />

           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}/sar"/>
           </delete>
           <mkdir dir="${tmp.dir}/META-INF"/>
           <copy todir="${tmp.dir}/META-INF">
                <fileset dir="${src.dir}/">
                  <include name="application.xml"/>
                </fileset>
           </copy>
           <jar jarfile="${tmp.dir}/${ear.name}" basedir="${tmp.dir}" compress="true" />
           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}/META-INF"/>
           </delete>
           <delete file="${tmp.dir}/${ejb.jar}"/>

           <copy file="${tmp.dir}/${ear.name}" tofile="${output.dir}/${ear.name}"/>
           <delete dir="${tmp.dir}"/>
        </target>


        <target name="deploy" depends="build_ear">
            <echo message="*******************  Deploying the EAR file ${ear.name} *********************" />
            <echo message="********** ${output.dir}/${ear.name} to ${jboss.home}/standalone/deployments **********" />
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${ear.name}"/>
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />
        </target>

</project>

NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script to point to your own JBoss AS7 directory.

Step-4). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/jaysensharma/jdk1.6.0_21/bin:/home/jaysensharma/org.apache.ant_1.6.5/bin:$PATH

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

Step-5). Now once the PATH is set In the command/Shell prompt you can move inside the directory “/home/jaysensharma/SingletonServiceDemo” and then run the ant to build and deploy the EJB based EAR applicationon your JBoss Standalone full profile, by running the command “ant deploy”

[jaysensharma@localhost SingletonServiceDemo]$ ant
Buildfile: build.xml

build_ear:
    [mkdir] Created dir: /home/jaysensharma/SingletonServiceDemo/tmp
    [javac] Compiling 1 source file to /home/jaysensharma/SingletonServiceDemo/tmp
      [jar] Building jar: /home/jaysensharma/SingletonServiceDemo/tmp/singletonServiceEJB.jar
    [mkdir] Created dir: /home/jaysensharma/SingletonServiceDemo/tmp/META-INF
      [jar] Building jar: /home/jaysensharma/SingletonServiceDemo/tmp/TestSingletonService.ear
   [delete] Deleting: /home/jaysensharma/SingletonServiceDemo/tmp/singletonServiceEJB.jar
     [copy] Copying 1 file to /home/jaysensharma/SingletonServiceDemo/build
   [delete] Deleting directory /home/jaysensharma/SingletonServiceDemo/tmp

deploy:
     [echo] *******************  Deploying the EAR file TestSingletonService.ear *********************
     [echo] ********** build/TestSingletonService.ear to /home/jaysensharma/jboss-as-7.1.2.Final/standalone/deployments **********
     [copy] Copying 1 file to /home/jaysensharma/jboss-as-7.1.2.Final/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************

all:

BUILD SUCCESSFUL
Total time: 1 second

Step-6). As the application is deployed on your JBoss so now try restarting your JBoss and then see whether the Above service us successfully get the DataSource and JDBC Connection or not. If the Dependency is correctly working then after restarting your JBoss you will see the following kind of message on your JBoss console / logs.

22:41:51,569 INFO  [sar.dependency.alternative.SingletonServiceBean] (MSC service thread 1-1) ***** DataSource = org.jboss.jca.adapters.jdbc.WrapperDataSource@43877c42 . Connection con = org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@5424bf0 retrieved from the ConnectionPool.*****

.
.
Thanks
MiddlewareMagic Team 🙂


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