Friday, March 21, 2014

How to develop EJB client applications for EJB deployed in different ejb containers?

i am going to develop a standalone java application to access the EJB has been deployed. first of all forget about the underlying EJB container impletation and focus only on developing the client.

we are going to develop a EJB client for the EJB deployed with http://chathurangat.blogspot.com/2014/03/create-simple-stateless-session-bean.html post.


1. Add the deployed EJB jar file to the classpath of the client being developed. this is because, the client program needs the access for the EJB business interface and methods.  i have added it as a maven dependency and it will be downloaded with my local maven repo.
   
       

            com.chathurangaonline.ejb.samples

            ejb-business-interface

            1.0

        

The JNDI and other configuration properties will differ between EJB containers. therefore we need to change those properties based on the EJB container that is we are going to access.

pom.xml

 
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.chathurangaonline.samples</groupId>
    <artifactId>ejb-client-example</artifactId>
    <packaging>jar</packaging>
    <version>1.0</version>
    <name>ejb-client-example</name>
    <url>http://maven.apache.org</url>
    <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.chathurangaonline.ejb.samples</groupId>
            <artifactId>ejb-business-interface</artifactId>
            <version>1.0</version>
        </dependency>

         <!--this dependency is required if the client is going to access the EJB deployed in the glassfish server-->
        <dependency>
            <groupId>org.glassfish.main.appclient.client</groupId>
            <artifactId>gf-client</artifactId>
            <version>3.1.2</version>
            <scope>system</scope>
            <systemPath>/home/chathuranga/Softwares/glassfish3/glassfish/lib/gf-client.jar</systemPath>
        </dependency>

    </dependencies>
</project>



EJB client for Jboss server

 
package com.chathurangaonline.ejb.samples;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Properties;

public class EJBClientJboss {

    public static void main(String[] args) {

        final String jndiName = "ejb-business-interface-1.0/SalaryCalculatorImpl!com.chathurangaonline.ejb.samples.SalaryCalculator";

        //configurations for accessing the EJB deployed in the glassfish server
        Properties jndiProps = new Properties();
        jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");
        jndiProps.put(Context.PROVIDER_URL,"remote://localhost:4447");
        jndiProps.put(Context.SECURITY_PRINCIPAL, "appuser");
        jndiProps.put(Context.SECURITY_CREDENTIALS, "appuser123");
        jndiProps.put("jboss.naming.client.ejb.context", true);

        try{
            Context ctx = new InitialContext(jndiProps);

            Object obj = ctx.lookup(jndiName);
            System.out.println("lookup returned " + obj);

            SalaryCalculator salaryCalculator = (SalaryCalculator) obj;
            Double salaryIncrement =  salaryCalculator.getAnnualIncrementOnBasicSalary(55000.00);
            System.out.println(" salary increment is ["+salaryIncrement+"]");

        }
        catch (NamingException ex){
            System.out.println(" message ["+ex.getMessage()+"]");
            System.out.println(" ex ["+ex+"]");
        }
    }
}




EJB Client for glassfish server 

 
package com.chathurangaonline.ejb.samples;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Properties;

public class EJBClientGlassfish {

    public static void main(String[] args) {

        final String jndiName = "java:global/ejb-business-interface-1.0/SalaryCalculatorImpl!com.chathurangaonline.ejb.samples.SalaryCalculator";

        //configurations for accessing the EJB deployed in the glassfish server
        Properties jndiProps = new Properties();
        jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
        jndiProps.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
        // glassfish default port value will be 3700
        jndiProps.setProperty("org.omg.CORBA.ORBInitialPort", "3700");

        try{
            Context ctx = new InitialContext(jndiProps);

            Object obj = ctx.lookup(jndiName);
            System.out.println("lookup returned " + obj);

            SalaryCalculator salaryCalculator = (SalaryCalculator) obj;
            Double salaryIncrement =  salaryCalculator.getAnnualIncrementOnBasicSalary(55000.00);
            System.out.println(" salary increment is ["+salaryIncrement+"]");

        }
        catch (NamingException ex){
            System.out.println(" message ["+ex.getMessage()+"]");
            System.out.println(" ex ["+ex+"]");
        }
    }
}



You will notice that we have change only the properties based on the EJB container/server.


Thanks
Chathuranga Tennakoon


Thursday, March 20, 2014

Create Simple Stateless session bean with EJB 3.x


You can create a simple java application project with maven. then you need to create the business interface and implementation beans for the EJB.

 Then the application will looks like as below.


 pom.xml

    4.0.0
    com.chathurangaonline.ejb.samples
    ejb-business-interface
    jar
    1.0
    ejb-business-interface
    http://maven.apache.org
    

        
            junit
            junit
            3.8.1
            test
        

        
            org.testng
            testng
            6.8.8
        

        
            javax
            javaee-api
            7.0
        

        
            org.jboss
            jboss-remote-naming
            1.0.7.Final
        

        
            org.jboss.xnio
            xnio-nio
            3.0.3.GA
        

    

    
        
            
                maven-compiler-plugin
                
                    1.7
                    1.7
                
            
        
    




SalaryCalculator.java (Business Interface)


package com.chathurangaonline.ejb.samples;

import javax.ejb.Remote;

@Remote
public interface SalaryCalculator {

    Double getAnnualIncrementOnBasicSalary(Double basicSalary);
}




@Remote annotation will be used because, i am planing to run the client in a separate JVM from the JVM where the EJB deployed and runs.




SalaryCalculatorImpl.java (Implementation Bean)


package com.chathurangaonline.ejb.samples;

import javax.ejb.Stateless;

@Stateless
public class SalaryCalculatorImpl implements SalaryCalculator{

    @Override
    public Double getAnnualIncrementOnBasicSalary(Double basicSalary) {
        if(basicSalary > 0 && basicSalary <= 35000){
            return basicSalary*0.2;
        }
        else if(basicSalary >35000){
            return  basicSalary*0.1;
        }
        else{
            throw new IllegalArgumentException();
        }
    }
}

this will be a stateless session bean.



SalaryCalculatorImplTest.java (TestNg Unit tests)


package com.chathurangaonline.ejb.samples;

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class SalaryCalculatorImplTest {

    private static SalaryCalculator salaryCalculator;

    @Test(expectedExceptions = IllegalArgumentException.class)
    public void testGetAnnualIncrementOnBasicSalaryWithNull() throws Exception {

       salaryCalculator.getAnnualIncrementOnBasicSalary(null);
    }

    @Test(expectedExceptions = IllegalArgumentException.class)
    public void testGetAnnualIncrementOnBasicSalaryWithNegativeValue() throws Exception{

     salaryCalculator.getAnnualIncrementOnBasicSalary(-90000D);
    }

    @Test(expectedExceptions = IllegalArgumentException.class)
    public void testGetAnnualIncrementOnBasicSalaryWithZero() throws Exception{

        salaryCalculator.getAnnualIncrementOnBasicSalary(0d);
    }

    @Test
    public void testGetAnnualIncrementOnBasicSalary(){

       double increment = salaryCalculator.getAnnualIncrementOnBasicSalary(50000d);
        System.out.println(" increment ["+increment+"]");
        Assert.assertTrue(increment>0);
    }

    @BeforeClass
    private void setUp(){
        if(salaryCalculator == null){
             salaryCalculator = new SalaryCalculatorImpl();
        }
    }
} 
 




Once this is developed, this can be compiled and packaged as a jar file.
then it can be deployed in any  EJB container (like Glassfish, Jboss etc...).
once it is deployed, check the log in the EJB continer to get the required JNDI
configurations for the EJB being deployed. those will be required when the
client is developed.

 we will look at in the next post, how to develop EJB cline tapplication for the EJB deployed in different EJB containers.


Thanks
Chathuranga Tennakoon
http://www.chathurangaonline.com/




Tuesday, March 11, 2014

How to set up Jenkins in your local development environment?

today i am going to discuss how to set up jenkins in your local machine. in oder to do that, you can follow the steps given below.


1. Install Apache Tomcat Server.

2. Download jenkins.war file from the http://jenkins-ci.org and deploy it in the tomcat server. (webapps)

3. Once the jenkins.war file was deployed successfully, you can open jenkins web console from the following url.
http://localhost:8080/jenkins


4. Now we need to configure Jenkins to use Java, Maven and Ant for building the projects.
    for most of the time, i prefer to build maven based projects. i am not a fan of Ant anymore ;)
    therefore i am going to configure Only Maven and Java. this can be done as follows.

   Manage Jenkins => Configure System




JDK Configurations

setting up the java home.




Maven Configurations

setting up the maven home




Now we have done the most of the required configurations for the jenkins.

Now it is gpood time to install some important/required plugins  for the jenkins.
i prefer to build the application form the Git repository. that is the Source Code Management and Versioning tool i have been using for more than 4 years. so i need to install that plugin for the Jenkins. that can be done as follows.

   Manage Jenkins => Manage Plugins


then install the Git-Plugin . you may see that plugin in the tab called "Available".

once the plugin is installed, your jenkins set up is done and it is  good time to test with first build.


First we will try to build maven web project from following GitHub url.

https://github.com/chathurangat/jax-ws-server-side-soap-handler


First we need to create a New Job for that purpose. that can be created By Clicking on the New Item in the left menu.


then you will get the folowing screen



Give a Name for the Build under Item Name.

Since i am going to build a maven based project, i am going to select the Maven Project option.


Then you need to select the JDK version that should be used  for the build.

Under  Source Code Management select the Git as SCM and configure the parameters accordinghly. refer the below screenshot.


Once SCM is added, you need to save the whole configurations before leaving the page.


then you will see the list of availble, build jobs in the Jenkins dashboard and you can execute the build job as required.

build history link can be used to check the status of the build job.

In next article, i am going to demostrate how to automate the deploy process in tomcat with Jenkins.



Thanks
Chathuranga Tennakoon
www.chathurangaonline.com

Thursday, March 6, 2014

How to create Spring based web service client with Apache CXF

In previous article, i have explained how to develop the Web Service using the Apache CXF framework. today i am planning to demonstrate on developing spring based web service client using Apache CXF.


In here, i will be developing a web service client for the above web service. you may follow the following steps.

first of all, you need to make sure that your web service is up and running.
if so, you can follow the steps given below to create your spring based web service client.


1. first create a maven based project. i have created a maven based simple java application.


2. Then add the spring dependency for the pom.xml

3. Then add the Apache CXF dependencies for the pom.xml


eventually your pom.xml will looks as below.

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.chathurangaonline.apache.cxf.jaxws.spring.samples</groupId>
    <artifactId>apache-cxf-jaxws-spring-jaxws-spring-client</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    <name>apache-cxf-jaxws-spring-jaxws-spring-client Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <cxf.version>3.0.4</cxf.version>
        <spring.version>4.0.2.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!--spring dependencies-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--apache cxf dependencies-->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>apache-cxf-jaxws-spring-jaxws-spring-client</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>




4. Now generate the client side libraries/stubs that required for the web service client from the WSDL of the service. then integrate the generated client stub files with your client application. this can be done with the following command.
if you need more information, you can refer this article for it.

wsimport  -keep  -verbose -d /home/chathuranga/Projects/jax-ws-tutorial/jax-ws-jaxb-sample-app/webClient/jaxb-client/src/main/java/  http://localhost:8080/employee-service/empServiceUrl?wsdl


5. create a applicationContext.xml file in the resource folder and add the following configurations there.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    <context:property-placeholder location="classpath*:configuration.properties"/>

    <jaxws:client id="calcServiceBean"
                  serviceClass="com.chathurangaonline.apache.cxf.jaxws.spring.samples.impl.CalculatorService"
                  address="${web.service.multiplication.url}" />


</beans>


6. create the configuration.properties file in resources directory and add the following entry to it.

 web.service.multiplication.url = http://localhost:8080/apache-cxf-jaxws-spring-sample/calcService


7. now you can create the client as follows.

package com.chathurangaonline.apache.cxf.jaxws.client.samples;

import com.chathurangaonline.apache.cxf.jaxws.spring.samples.impl.CalculatorService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class CXFTestClient {

    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
        CalculatorService calculatorService = (CalculatorService) applicationContext.getBean("calcServiceBean");
        double answer =  calculatorService.multiply(10,22);
        System.out.println(" answer is ["+answer+"]");
    }
}



you can download the fully source code from the following repository.

Source Code :- https://github.com/chathurangat/apache-cxf-jaxws-spring-client

Hope this will be helpful for you!

Thanks
Chathuranga Tennakoon
www.chathurangaonline.com