Andre Broers’ personal blog

January 31, 2008

EJB3 + JPA on OC4J with Client

Filed under: 11g, ejb, j2ee, java, jpa, oc4j, oracle — broersa @ 9:08 am

Let’s use the previous JPA sample in an EJB. We start creating a datasource on the OC4J container. Then we create the entities again. After this we use the entities in a Stateless EJB which we will deploy to OC4J 11g. Finally we create a stand-alone client which calls the EJB.

We start with the creation of the datasource. We need a ConnectionPool.

java -jar $OC4J_ADMIN/j2ee/home/admin_client.jar deployer:oc4j:localhost oc4jadmin welcome -CreateJDBCConnectionPool -applicationName default -name HrConnectionPool -factoryClass oracle.jdbc.pool.OracleDataSource -user hr -password hr -url jdbc:oracle:thin:@localhost:1521:orcl

Test the connectionpool:

java -jar $OC4J_ADMIN/j2ee/home/admin_client.jar deployer:oc4j:localhost oc4jadmin welcome
-testConnectionPool -connectionPoolName HrConnectionPool -sqlStatement “select
* from dual” And the datasource:

java -jar $OC4J_ADMIN/j2ee/home/admin_client.jar deployer:oc4j:localhost oc4jadmin welcome -createManagedDataSource -applicationName default -dataSourceName HrDataSource -jndiLocation jdbc/HrDataSource -connectionPoolName HrConnectionPool

After this we create the entities:

/home/broersa/work/CountryApp/CountryJPAEJB/src/com/bekijkhet/entity/Country.java:


package com.bekijkhet.entity;

import java.io.Serializable;
import javax.persistence.*;

@Entity
@Table(name="COUNTRIES")
public class Country implements Serializable {
        private String id;
        private String name;
        private Region region;

        @Id
        @Column(name="COUNTRY_ID")
        public String getId() {
                return id;
        }

        public void setId(String id) {
                this.id = id;
        }

        @Column(name="COUNTRY_NAME")
        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        @ManyToOne(cascade={CascadeType.ALL})
        @JoinColumn(name="REGION_ID",nullable=false)
        public Region getRegion() {
                return region;
        }

        public void setRegion(Region region) {
                this.region = region;
        }
}

/home/broersa/work/CountryApp/CountryJPAEJB/src/com/bekijkhet/entity/Region.java


package com.bekijkhet.entity;

import java.io.Serializable;
import javax.persistence.*;
import static javax.persistence.CascadeType.*;
import static javax.persistence.FetchType.*;

import java.util.List;
import java.util.ArrayList;

@Entity
@Table(name="REGIONS")
public class Region implements Serializable {
        private int id;
        private String name;
        private List<Country> countries = new ArrayList<Country>();;

        @Id
        @Column(name="REGION_ID")
        public int getId() {
                return id;
        }

        public void setId(int id) {
                this.id = id;
        }

        @Column(name="REGION_NAME")
        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        @OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.ALL}, mappedBy="region")
        public List<Country> getCountries() {
                return countries;
        }

        public void setCountries(List<Country> newValue) {
                this.countries = newValue;
        }
}

The EJB:/home/broersa/work/CountryApp/CountryJPAEJB/src/com/bekijkhet/country/CountryEJBLocal.java:


package com.bekijkhet.country;

import com.bekijkhet.entity.*;
import java.util.List;

public interface CountryEJBLocal {
  public List<Country> getCountriesByRegion(String region);
  public Region getRegionByCountry(String country);
}

/home/broersa/work/CountryApp/CountryJPAEJB/src/com/bekijkhet/country/CountryEJB.java:


package com.bekijkhet.country;
import java.util.List;
import com.bekijkhet.entity.*;
public interface CountryEJB {
  public List<Country> getCountriesByRegion(String region);
  public Region getRegionByCountry(String country);
  public void addorchangeCountry(Country country) ;
  public void addorchangeRegion(Region region) ;
  public void removeCountry(Country country) ;
  public void removeRegion(Region region) ;
  public List<Region> getAllRegions() ;
  public List<Country> getAllCountries();
}

/home/broersa/work/CountryApp/CountryJPAEJB/src/com/bekijkhet/country/CountryEJBBean.java


package com.bekijkhet.country;
import javax.ejb.Stateless;
import javax.ejb.Remote;
import javax.ejb.Local;

import java.util.List;
import com.bekijkhet.entity.*;
import javax.persistence.*;

@Stateless
@Remote(CountryEJB.class)
@Local(CountryEJBLocal.class)
public class CountryEJBBean implements CountryEJB,CountryEJBLocal {
  @PersistenceContext
  EntityManager em;

  public List<Country> getCountriesByRegion(String region) {
    Query q = em.createQuery("select r from Region r where r.name = :name");
    q.setParameter("name",region);
    Region r = (Region) q.getSingleResult();
//    r.getCountries().size();  // get the LAZY relation
    return r.getCountries();
  }

  public Region getRegionByCountry(String country) {
    Query q = em.createQuery("select c from Country c where c.name = :name");
    q.setParameter("name",country);
    Country c = (Country) q.getSingleResult();
    return c.getRegion();
  }

  public void addorchangeCountry(Country country) {
    em.persist(country);
  }

  public void addorchangeRegion(Region region) {
    em.persist(region);
  }

  public void removeCountry(Country country) {
    Country c = em.merge(country);
    em.remove(c);
  }

  public void removeRegion(Region region) {
    Region r = em.merge(region);
    em.remove(r);
  }

  public List<Region> getAllRegions() {
    Query q = em.createQuery("select r from Region r");
    List<Region> l = q.getResultList();
    return l;
  }

  public List<Country> getAllCountries() {
    Query q = em.createQuery("select c from Country c");
    List<Country> l = q.getResultList();
    return l;
  }
}

We need a persistence descriptor : /home/broersa/work/CountryApp/CountryJPAEJB/src/META-INF/persistence.xml:

<persistence>
  <persistence-unit name="MyPU">
    <jta-data-source>jdbc/HrDataSource</jta-data-source>
  </persistence-unit>
</persistence>

We need the build file:/home/broersa/work/CountryApp/CountryJPAEJB/build.xml:


<project name="CountryJPAEJB" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

 <path id="files-classpath">
     <!--fileset dir="$HOME/oc4j_client_11110_preview/j2ee/home/lib" >
         <include name="persistence.jar"/>
     </fileset-->
     <pathelement location="/home/broersa/oc4j_client_11110_preview/j2ee/home/lib/persistence.jar"/>
     <pathelement location="/home/broersa/oc4j_client_11110_preview/j2ee/home/lib/ejb.jar"/>
 </path>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}">
      <classpath refid="files-classpath" />
    </javac>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}"/>
    <copy todir="${build}/META-INF">
                        <fileset dir="src/META-INF">
                                <include name="*" />
                        </fileset>
                   </copy>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/CountryBean.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

We can build and deploy the EJB:type “ant” to build the EJB.use the next command to deploy the ejb:

java -jar $OC4J_ADMIN/j2ee/home/admin_client.jar deployer:oc4j:localhost oc4jadmin welcome -deploy -file $HOME/work/CountryApp/CountryJPAEJB/dist/CountryBean.jar -deploymentName CountryBean

Now this is done we can create the client:

/home/broersa/work/CountryApp/CountryClient/com/bekijkhet/CountryClient.java:


package com.bekijkhet;
import javax.naming.*;
import com.bekijkhet.country.CountryEJB;
import com.bekijkhet.entity.*;
import java.util.Properties;
import java.util.List;

public class CountryClient {
  public static void main(String[] args) {
    try {
      Properties props = new Properties();
      props.put("java.naming.factory.initial","com.evermind.server.ApplicationClientInitialContextFactory");
      props.put("java.naming.provider.url","ormi://localhost/CountryBean");
      props.put("java.naming.security.principal","oc4jadmin");
      props.put("java.naming.security.credentials","welcome");
      InitialContext ctx = new InitialContext(props);
      CountryEJB h = (CountryEJB)ctx.lookup("CountryEJBBean");

      System.out.println("The Netherlands has region: " + h.getRegionByCountry("Netherlands").getName());
      List<Country> l1 = h.getCountriesByRegion("Europe");
      System.out.println("Europe has the following countries:");
      for (Country c : l1) {
       System.out.println("  " + c.getName());
      }
      System.out.println("All regions:");
      List<Region> l2 = h.getAllRegions();
      for (Region r : l2) {
       System.out.println("  " + r.getName());
      }
      System.out.println("All countries:");
      List<Country> l3 = h.getAllCountries();
      for (Country c2 : l3) {
       System.out.println("  " + c2.getName() + " - " + c2.getRegion().getName());
      }

      Region r3 = new Region();
      r3.setName("MyRegion1");
      r3.setId(1001);
      Country c3 = new Country();
      c3.setName("MyCountry1");
      c3.setId("31");
      c3.setRegion(r3);
      r3.getCountries().add(c3);
      h.addorchangeCountry(c3);

      Region r4 = new Region();
      r4.setName("MyRegion2");
      r4.setId(1002);
      Country c4 = new Country();
      c4.setName("MyCountry2");
      c4.setId("32");
      c4.setRegion(r4);
      r4.getCountries().add(c4);
      h.addorchangeRegion(r4);

      System.out.println("All regions:");
      List<Region> l5 = h.getAllRegions();
      for (Region r5 : l5) {
       System.out.println("  " + r5.getName());
      }
      System.out.println("All countries:");
      List<Country> l6 = h.getAllCountries();
      for (Country c6 : l6) {
       System.out.println("  " + c6.getName() + " - " + c6.getRegion().getName());
      }
    }
    catch (Exception e) {
      System.out.println(e);
      e.printStackTrace();
    }
  }
}

/home/broersa/work/CountryApp/CountryClient/com/bekijkhet/META-INF/application-client.xml:

<?xml version="1.0" encoding="UTF-8"?>
<application-client version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd">
  <display-name>CountryClient</display-name>
  <description>test</description>
</application-client>

Compile the client:javac -cp $OC4J_HOME/j2ee/home/oc4jclient.jar:/home/broersa/work/CountryApp/CountryJPAEJB/dist/CountryBean.jar:. -d . CountryClient.javaAnd test the client:java -cp $OC4J_HOME/j2ee/home/oc4jclient.jar:/home/broersa/work/CountryApp/CountryJPAEJB/dist/CountryBean.jar:. com.bekijkhet.CountryClient

The Netherlands has region: Europe
Europe has the following countries:
Belgium
Switzerland
Germany
Denmark
France
Italy
Netherlands
United Kingdom
All regions:
Europe
Americas
Asia
Middle East and Africa
All countries:
Argentina – Americas
Australia – Asia
Belgium – Europe
Brazil – Americas
Canada – Americas
Switzerland – Europe
China – Asia
Germany – Europe
Denmark – Europe
Egypt – Middle East and Africa
France – Europe
HongKong – Asia
Israel – Middle East and Africa
India – Asia
Italy – Europe
Japan – Asia
Kuwait – Middle East and Africa
Mexico – Americas
Nigeria – Middle East and Africa
Netherlands – Europe
Singapore – Asia
United Kingdom – Europe
United States of America – Americas
Zambia – Middle East and Africa
Zimbabwe – Middle East and Africa
All regions:
Europe
Americas
Asia
Middle East and Africa
MyRegion1
MyRegion2
All countries:
MyCountry1 – MyRegion1
MyCountry2 – MyRegion2
Argentina – Americas
Australia – Asia
Belgium – Europe
Brazil – Americas
Canada – Americas
Switzerland – Europe
China – Asia
Germany – Europe
Denmark – Europe
Egypt – Middle East and Africa
France – Europe
HongKong – Asia
Israel – Middle East and Africa
India – Asia
Italy – Europe
Japan – Asia
Kuwait – Middle East and Africa
Mexico – Americas
Nigeria – Middle East and Africa
Netherlands – Europe
Singapore – Asia
United Kingdom – Europe
United States of America – Americas
Zambia – Middle East and Africa
Zimbabwe – Middle East and Africa

December 20, 2007

Counter MBean to measure EJB calls

Filed under: ejb, glassfish, j2ee, java, jmx, mbean — broersa @ 7:14 pm

In this example I create a Counter MBean which I will install in the Glassfish server. This bean has three methods getCounter, incrementCounter and resetCounter. After this I create an EJB which will increment the counter each time sayHello is called. We can then monitor the counter with the jconsole app. After reading a lot of different implementations I think this is in my opinion the best way to implement this. The problem I have with this implementation is that I can call the increment function from jconsole with which I can influence the counter.

Let’s start with the MBean:

/home/broersa/work/HelloApp/MyCounterMBean/src/com/bekijkhet/MyCounterMBean.java


package com.bekijkhet;

public interface MyCounterMBean {
  public int getCounter();
  public void incrementCounter();
  public void resetCounter();
}

/home/broersa/work/HelloApp/MyCounterMBean/src/com/bekijkhet/MyCounter.java


package com.bekijkhet;

public class MyCounter implements MyCounterMBean {
  public int counter = 0;

  public int getCounter() {
    return counter;
  }

  public void incrementCounter() {
    counter++;
  }

  public void resetCounter() {
    counter = 0;
  }
}

/home/broersa/work/HelloApp/MyCounterMBean/build.xml


<project name="MyCounterMBean" default="compile" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
  </target>
</project>

type:asant compileto compile the MBean.cd build

cp -r com /home/broersa/glassfish/domains/domain1/applications/mbeans

asadmin create-mbean com.bekijkhet.MyCounter

to deploy the managed bean.

Now it is time to create the statefull EJB which increments the counter in the MBean.

/home/broersa/work/HelloApp/MyCounterEJB/src/com/bekijkhet/MyCounterEJB.java


package com.bekijkhet;
public interface MyCounterEJB {
  public String sayHello();
}

/home/broersa/work/HelloApp/MyCounterEJB/src/com/bekijkhet/MyCounterEJB.java


package com.bekijkhet;
import javax.ejb.Stateless;
import javax.ejb.EJB;
import javax.ejb.Remote;
import java.util.Properties;
import java.net.URL;
import javax.naming.*;
import javax.management.*;
import java.lang.management.*;

@Stateless
@Remote(MyCounterEJB.class)
public class MyCounterEJBBean implements MyCounterEJB {

  private MyCounterMBean mbean = null;

  public MyCounterEJBBean() {

    try {
      // Get the platform MBeanServer
      MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
      ObjectName name = new ObjectName("user:impl-class-name=com.bekijkhet.MyCounter,name=com.bekijkhet.MyCounter,server=server");

      mbean = (MyCounterMBean) MBeanServerInvocationHandler.newProxyInstance(mbs, name, MyCounterMBean.class, false);
    } catch(Exception e) {
      e.printStackTrace();
    }
  }

  public String sayHello() {
    mbean.incrementCounter();
    return "Hello From Glassfish!!!! ";
  }
}

/home/broersa/work/HelloApp/MyCounterEJB/build.xml


<project name="MyCounterEJB" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="/home/broersa/work/HelloApp/MyCounterMBean/src" destdir="${build}"/>
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/MyCounterEJB.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

In this build.xml I included a second javac rule that includes the MBean classes in this ejb.Now we build and deploy the ejb:

asant dist

asadmin deploy dist/MyCounterEJB.jar

Now it is time to create the client that calls the ejb sayhello method that increments our counter in the mbean.


package com.bekijkhet.helloclient;
import javax.naming.*;
import com.bekijkhet.MyCounterEJB;
public class HelloClient {
  public static void main(String[] args) {
    try {
      InitialContext ctx = new InitialContext();
      MyCounterEJB m = (MyCounterEJB)ctx.lookup("com.bekijkhet.MyCounterEJB");
     System.out.println(m.sayHello());
    }
    catch (Exception e) {
      System.out.println(e);
      e.printStackTrace();
    }
  }
}

compile the code:javac -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/MyCounterEJB/dist/MyCounterEJB.jar:. -d . HelloClient.java

open a jconsole to monitor our Mbean. connect to localhost:8686 (which is the default portnumber) and connect with admin pwd: adminadmin

jconsole

See the counter which has the value 0.

Now we run our client:

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/MyCounterEJB/dist/MyCounterEJB.jar:. com.bekijkhet.helloclient.HelloClient

And the counter is incremented by one:

jconsole1

December 5, 2007

Secure EJB with stand alone client on Glassfish (part 2)

Filed under: ejb, glassfish, j2ee, java, security — broersa @ 9:47 am

In part 1 we created a sessionbean with authorization on the methods. In this exemple we get the same sessionbean but we add some progammatic logic in the method the make the authorization a bit more controllable. We add two functions to get the group info and one to get the current username.

For this example we use the same code from part 1. The only file we change is the one below:

/home/broersa/work/HelloApp/HelloSecurity/src/com/bekijkhet/HelloBean.java


package com.bekijkhet;
import javax.ejb.Stateless;
import javax.ejb.Remote;
import javax.annotation.security.RolesAllowed;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.DeclareRoles;
import javax.annotation.Resource;
import java.security.Principal;
import javax.ejb.SessionContext;
@Stateless
@Remote(Hello.class)
@DeclareRoles({"superuser","user"})
public class HelloBean implements Hello {
  @Resource SessionContext ctx;
  @RolesAllowed("superuser")
  public String sayHellosuperuser() {
    return "sayHellosuperuser";
  }
  @RolesAllowed({"user","superuser"})
  public String sayHellousersuperuser() {
    return "sayHellousersuperuser";
  }
  @RolesAllowed("user")
  public String sayHellouser() {
    return "sayHellouser";
  }
  @PermitAll
  public String sayHelloPermitAll() {
    Principal callerPrincipal = ctx.getCallerPrincipal();
    if (ctx.isCallerInRole("superuser")) {
      return "sayHelloPermitAll as role superuser by "+callerPrincipal.getName();
    }
    if (ctx.isCallerInRole("user")) {
      return "sayHelloPermitAll as role user by "+callerPrincipal.getName();
    }
    return "sayHelloPermitAll as role <unknown> by "+callerPrincipal.getName();
  }
  @DenyAll
  public String sayHelloDenyAll() {
    return "sayHelloDenyAll";
  }
}

use asant dist to recreate the jar.

redeploy the jar with asadmin deploy dist/HelloSecurity.jar

rerun the client with the myadmin account:

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/appserv-admin.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloSecurity/dist/HelloSecurity.jar:. -Djava.security.auth.login.config=$GLASSFISH_HOME/lib/appclient/appclientlogin.conf com.bekijkhet.helloclient.HelloClient myadmin myadmin

1
2
3
sayHellosuperuser: sayHellosuperuser
sayHellousersuperuser: sayHellousersuperuser
sayHellouser: No Permission
sayHelloPermitAll: sayHelloPermitAll as role superuser by myadmin
sayHelloDenyAll: No Permission

We see that we get the role and the username.  You can do the same with the myuser1 and myuser2 accounts and discover that they are in the user role.

December 4, 2007

Secure EJB with stand alone client on Glassfish (part 1)

Filed under: ejb, glassfish, j2ee, java, security — broersa @ 7:44 pm

Security is hot these days, so let’s start with a sample to implement it in the EJB session beans.

First thing to do is create three users in Glassfish:

asadmin create-file-user –groups myusergrp myuser1

asadmin create-file-user –groups myusergrp myuser2

asadmin create-file-user myadmin

We now created two users that have the group myusergrp and a myadmin user with no group.

After this we can create the secure bean:

/home/broersa/work/HelloApp/HelloSecurity/src/com/bekijkhet/Hello.java


package com.bekijkhet;
public interface Hello {
  public String sayHellosuperuser();
  public String sayHellousersuperuser();
  public String sayHellouser();
  public String sayHelloPermitAll();
  public String sayHelloDenyAll();
}

/home/broersa/work/HelloApp/HelloSecurity/src/com/bekijkhet/HelloBean.java


package com.bekijkhet;
import javax.ejb.Stateless;
import javax.ejb.Remote;
import javax.annotation.security.RolesAllowed;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
@Stateless
@Remote(Hello.class)
public class HelloBean implements Hello {
  @RolesAllowed("superuser")
  public String sayHellosuperuser() {
    return "sayHellosuperuser";
  }
  @RolesAllowed({"user","superuser"})
  public String sayHellousersuperuser() {
    return "sayHellousersuperuser";
  }
  @RolesAllowed("user")
  public String sayHellouser() {
    return "sayHellouser";
  }
  @PermitAll
  public String sayHelloPermitAll() {
    return "sayHelloPermitAll";
  }
  @DenyAll
  public String sayHelloDenyAll() {
    return "sayHelloDenyAll";
  }
}

Next we create the mapping wherein we map the application roles to the applicationserver users and groups./home/broersa/work/HelloApp/HelloSecurity/META-INF/sun-ejb-jar.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
<sun-ejb-jar>
  <security-role-mapping>
        <role-name>user</role-name>
        <group-name>myusergrp</group-name>
    </security-role-mapping>
    <security-role-mapping>
        <role-name>superuser</role-name>
        <principal-name>myadmin</principal-name>
    </security-role-mapping>
</sun-ejb-jar>

and the buil.xml file/home/broersa/work/HelloApp/HelloSecurity/build.xml


<project name="HelloSecurity" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac classpath="$GLASSFISH_HOME/lib/javaee.jar" srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}"/>
    <copy todir="${build}/META-INF">
                        <fileset dir="META-INF">
                                <include name="*" />
                        </fileset>
                   </copy>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/HelloSecurity.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

build the ejb with:asant distdeploy:asadmin deploy dist/HelloSecurity.jar

Now we must create the client:

/home/broersa/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient/HelloClient.java


package com.bekijkhet.helloclient;
import javax.naming.*;
import com.bekijkhet.Hello;
import com.sun.appserv.security.ProgrammaticLogin;
public class HelloClient {
  public static void main(String[] args) {
    try {
      ProgrammaticLogin login = new ProgrammaticLogin();
      login.login(args[0],args[1]);

      System.out.println("1");

      InitialContext ctx = new InitialContext();

      System.out.println("2");

      Hello n = (Hello)ctx.lookup("com.bekijkhet.Hello");

      System.out.println("3");

      try {
        System.out.print("sayHellosuperuser: ");
        System.out.println(n.sayHellosuperuser());
      } catch (javax.ejb.EJBException t) { System.out.println("No Permission"); }
      try {
        System.out.print("sayHellousersuperuser: ");
        System.out.println(n.sayHellousersuperuser());
      } catch (javax.ejb.EJBException t) { System.out.println("No Permission"); }
      try {
        System.out.print("sayHellouser: ");
        System.out.println(n.sayHellouser());
      } catch (javax.ejb.EJBException t) { System.out.println("No Permission"); }
      try {
        System.out.print("sayHelloPermitAll: ");
        System.out.println(n.sayHelloPermitAll());
      } catch (javax.ejb.EJBException t) { System.out.println("No Permission"); }
      try {
        System.out.print("sayHelloDenyAll: ");
        System.out.println(n.sayHelloDenyAll());
      } catch (javax.ejb.EJBException t) { System.out.println("No Permission"); }
    }
    catch (Exception x) {
      System.out.println("Invalid Username Password");
    }
  }
}

Compile the code:javac -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/appserv-admin.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloSecurity/dist/HelloSecurity.jar:. -d . HelloClient.java

Run the code with different users:

as myadmin which is in the superuser role:

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/appserv-admin.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloSecurity/dist/HelloSecurity.jar:. -Djava.security.auth.login.config=$GLASSFISH_HOME/lib/appclient/appclientlogin.conf com.bekijkhet.helloclient.HelloClient myadmin myadmin

1
2
3
sayHellosuperuser: sayHellosuperuser
sayHellousersuperuser: sayHellousersuperuser
sayHellouser: No Permission
sayHelloPermitAll: sayHelloPermitAll
sayHelloDenyAll: No Permission

as myuser1 which is in the myusergrp which has the user role:

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/appserv-admin.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloSecurity/dist/HelloSecurity.jar:. -Djava.security.auth.login.config=$GLASSFISH_HOME/lib/appclient/appclientlogin.conf com.bekijkhet.helloclient.HelloClient myuser1 myuser1

1
2
3
sayHellosuperuser: No Permission
sayHellousersuperuser: sayHellousersuperuser
sayHellouser: sayHellouser
sayHelloPermitAll: sayHelloPermitAll
sayHelloDenyAll: No Permission

as myuser2 which is also in the myusergrp which has the user role:

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/appserv-admin.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloSecurity/dist/HelloSecurity.jar:. -Djava.security.auth.login.config=$GLASSFISH_HOME/lib/appclient/appclientlogin.conf com.bekijkhet.helloclient.HelloClient myuser2 myuser2

1
2
3
sayHellosuperuser: No Permission
sayHellousersuperuser: sayHellousersuperuser
sayHellouser: sayHellouser
sayHelloPermitAll: sayHelloPermitAll
sayHelloDenyAll: No Permission

When you call the client with an invalid username password combination you get an exception on the call to the Lookup of the bean. This is catched in the last catch in the client main method:

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/appserv-admin.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloSecurity/dist/HelloSecurity.jar:. -Djava.security.auth.login.config=$GLASSFISH_HOME/lib/appclient/appclientlogin.conf com.bekijkhet.helloclient.HelloClient myuser1 myuser

1
2
Invalid Username Password

November 23, 2007

Create an EJB as JMS client

Filed under: ejb, glassfish, j2ee, java, jms, mdb — broersa @ 12:25 pm

In this sample we create an EJB  that calls the MDB from previous blog.

Lets start with the EJB code (don’t look at the method names, I copied from a previous example :-) )

broersa@debian1:~/work/HelloApp/HelloMDBEJB/src/com/bekijkhet$ cat HelloMDBEJBLocal.java


package com.bekijkhet;
public interface HelloMDBEJBLocal {
  public String sayHelloStateless();
  public String sayHelloStatelessLocal();
  public void setMember(String member);
}

broersa@debian1:~/work/HelloApp/HelloMDBEJB/src/com/bekijkhet$ cat HelloMDBEJB.java


package com.bekijkhet;
public interface HelloMDBEJB {
  public String sayHelloStateless();
  public String sayHelloStatelessRemote();
  public void setMember(String member);
}
 

broersa@debian1:~/work/HelloApp/HelloMDBEJB/src/com/bekijkhet$ cat HelloMDBEJBBean.java


package com.bekijkhet;
import javax.ejb.Stateless;
import javax.ejb.Remote;
import javax.ejb.Local;
import javax.jms.*;
import javax.naming.*;
@Stateless
@Remote(HelloMDBEJB.class)
@Local(HelloMDBEJBLocal.class)
public class HelloMDBEJBBean implements HelloMDBEJB,HelloMDBEJBLocal {

  private String member = "Not set!";

  public String sayHelloStateless() {
          try {
            Context ctx = new InitialContext();
            ConnectionFactory     connectionFactory = (ConnectionFactory)ctx.lookup("jms/ConnectionFactory");
            Queue     queue = (Queue)ctx.lookup("jms/SampleQueue");
            javax.jms.Connection  connection = connectionFactory.createConnection();
            javax.jms.Session        session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
            MessageProducer messageProducer = session.createProducer(queue);
            TextMessage message = session.createTextMessage();
            message.setText("my test message");
            System.out.println( "MDBEJB:"+ message.getText());
            messageProducer.send(message);
            connection.close();
          } catch (Exception e) {System.out.println(e.toString());}
    return "Hello Stateless "+member;
  }
  public String sayHelloStatelessLocal() {
    return "Hello Local Stateless "+member;
  }
  public String sayHelloStatelessRemote() {
    return "Hello Remote Stateless "+member;
  }
  public void setMember(String member) {
    this.member=member;
  }
}

broersa@debian1:~/work/HelloApp/HelloMDBEJB$ cat build.xml


<project name="HelloEJB" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/HelloMDBEJB.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

after this build with

asant dist

and deploy

asadmin deploy dist/HelloMDBEJB.jar

than the client to call the EJB which is similar to the client  in the previous samples:

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ cat HelloMDBEJBClient.java


package com.bekijkhet.helloclient;
import javax.naming.*;
import com.bekijkhet.HelloMDBEJB;
public class HelloMDBEJBClient {
  public static void main(String[] args) {
    try {
      InitialContext ctx = new InitialContext();
      HelloMDBEJB h = (HelloMDBEJB)ctx.lookup("com.bekijkhet.HelloMDBEJB");

      System.out.println(h.sayHelloStateless());
    }
    catch (Exception e) {
      System.out.println(e);
      e.printStackTrace();
    }
  }
}

compile:

javac -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloMDBEJB/dist/HelloMDBEJB.jar:. -d . HelloMDBEJBClient.java

run:

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloMDBEJB/dist/HelloMDBEJB.jar:. com.bekijkhet.helloclient.HelloMDBEJBClient
Hello Stateless Not set!

and the output in the $GLASSFISH_HOME/domains/domain1/logs/server.log

[#|2007-11-23T13:49:49.076+0100|INFO|sun-appserver9.1|javax.enterprise.system.stream.out|_ThreadID=26;_ThreadName=p: thread-pool-1; w: 61;|
MDBEJB:my test message|#]

[#|2007-11-23T13:49:49.091+0100|INFO|sun-appserver9.1|javax.enterprise.system.stream.out|_ThreadID=26;_ThreadName=p: thread-pool-1; w: 61;|
Got message: my test message|#]

Create a Message Driven Bean (MDB) and stand alone client

Filed under: ejb, glassfish, j2ee, java, jms, mdb — broersa @ 10:58 am

Next example is a message driven bean deployed on glassfish that gets called by a stand alone client. Let start with creating the JMS Connection Factory and the JMS Queue on glassfish.

Issue the following statement to create the connection factory:

asadmin create-jms-resource –restype javax.jms.ConnectionFactory jms/ConnectionFactory

After this create the resource destination:

asadmin create-jmsdest -T queue sampleQueue

Create the JMS destination:

asadmin create-jms-resource –restype javax.jms.Queue –property Name=sampleQueue jms/SampleQueue

Now we can create the Message Driven Bean:

broersa@debian1:~/work/HelloApp/HelloMDB/src/com/bekijkhet$ cat HelloMDB.java


package com.bekijkhet;
import javax.ejb.MessageDriven;
import javax.jms.MessageListener;
import javax.jms.Message;
import javax.jms.TextMessage;

@MessageDriven(mappedName="jms/SampleQueue")
public class HelloMDB implements MessageListener {

    public void onMessage(Message msg) {
      try {
        if (msg instanceof TextMessage) {
          TextMessage txtmsg = (TextMessage) msg;
          System.out.println("Got message: "+txtmsg.getText());
        }
      } catch (Exception e) { System.out.println(e.toString()); }
    }

}

broersa@debian1:~/work/HelloApp/HelloMDB$ cat build.xml


<project name="HelloMDB" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/HelloMDB.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

Build and deploy the MDB:asant dist

asadmin deploy dist/HelloMDB.jar

Let’s go on creating the stand alone client to call the MDB.

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ cat HelloMDBClient.java


package com.bekijkhet.helloclient;
import javax.naming.*;
import javax.jms.*;

public class HelloMDBClient {
  public static void main(String args[]) {
    try {
      // will get the local default context from appserv-rt.jar
      Context ctx = new InitialContext();
      ConnectionFactory connectionFactory = (ConnectionFactory)ctx.lookup("jms/ConnectionFactory");
      Queue queue = (Queue)ctx.lookup("jms/SampleQueue");
      javax.jms.Connection connection = connectionFactory.createConnection();
      javax.jms.Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
      MessageProducer messageProducer = session.createProducer(queue);
      TextMessage message = session.createTextMessage();
      message.setText("my own text message");
      System.out.println( "Send: "+ message.getText());
      messageProducer.send(message);
      connection.close();
    } catch (Exception e) {System.out.println(e.toString());}
  }
}

Compile and run:

javac -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:. -d . HelloMDBClient.java

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$GLASSFISH_HOME/lib/install/applications/jmsra/imqjmsra.jar:$GLASSFISH_HOME/lib/appserv-admin.jar:. com.bekijkhet.helloclient.HelloMDBClient

<snipped a lot of initialisation output..>

Send: my own text message

When we look at the server log file ($GLASSFISH_HOME/domains/domain1/logs/server.log) we can see the MDB got fired:

[#|2007-11-23T12:17:45.309+0100|INFO|sun-appserver9.1|javax.enterprise.system.stream.out|_ThreadID=23;_ThreadName=p: thread-pool-1; w: 34;|
Got message: my own text message|#]
After this my client app (HelloMDBClient) hangs….. Press ctrl-c to end the process. I can’t find a solution to get the program exit normally… It looks like another thread got starten to listen for incomming messages??

In the next sample I create an EJB to send messages which will be run from inside the container. This seams to work without hanging. Maybe someone can explain?

November 21, 2007

Stateful and Stateless EJB sample

Filed under: ejb, glassfish, j2ee, java — broersa @ 6:58 pm

In this example I show the difference between Stateful en Stateless EJB’s. First I create and deploy the stateful bean.

broersa@debian1:~/work/HelloApp/HelloStateful/src/com/bekijkhet$ cat HelloStateful.java


package com.bekijkhet;
public interface HelloStateful {
  public String sayHelloStateful();
  public String sayHelloStatefulRemote();
  public void setMember(String member);
}

broersa@debian1:~/work/HelloApp/HelloStateful/src/com/bekijkhet$ cat HelloStatefulLocal.java


package com.bekijkhet;
public interface HelloStatefulLocal {
  public String sayHelloStateful();
  public String sayHelloStatefulLocal();
  public void setMember(String member);
}

broersa@debian1:~/work/HelloApp/HelloStateful/src/com/bekijkhet$ cat HelloStatefulBean.java


package com.bekijkhet;
import javax.ejb.Stateful;
import javax.ejb.Remote;
import javax.ejb.Local;
@Stateful
@Remote(HelloStateful.class)
@Local(HelloStatefulLocal.class)
public class HelloStatefulBean implements HelloStateful,HelloStatefulLocal {

  private String member = "Not set!";

  public String sayHelloStateful() {
    return "Hello Stateful "+member;
  }
  public String sayHelloStatefulLocal() {
    return "Hello Local Stateful "+member;
  }
  public String sayHelloStatefulRemote() {
    return "Hello Remote Stateful "+member;
  }
  public void setMember(String member) {
    this.member=member;
  }
}

broersa@debian1:~/work/HelloApp/HelloStateful$ cat build.xml


<project name="HelloEJB" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/HelloStateful.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

Then build: asant distThen deploy: asadmin deploy dist/HelloStateful.jarNow the stateless bean:

broersa@debian1:~/work/HelloApp/HelloStateless/src/com/bekijkhet$ cat HelloStateless.java


package com.bekijkhet;
public interface HelloStateless {
  public String sayHelloStateless();
  public String sayHelloStatelessRemote();
  public void setMember(String member);
}

broersa@debian1:~/work/HelloApp/HelloStateless/src/com/bekijkhet$ cat HelloStatelessLocal.java


package com.bekijkhet;
public interface HelloStatelessLocal {
  public String sayHelloStateless();
  public String sayHelloStatelessLocal();
  public void setMember(String member);
}

broersa@debian1:~/work/HelloApp/HelloStateless/src/com/bekijkhet$ cat HelloStatelessBean.java


package com.bekijkhet;
import javax.ejb.Stateless;
import javax.ejb.Remote;
import javax.ejb.Local;
@Stateless
@Remote(HelloStateless.class)
@Local(HelloStatelessLocal.class)
public class HelloStatelessBean implements HelloStateless,HelloStatelessLocal {

  private String member = "Not set!";

  public String sayHelloStateless() {
    return "Hello Stateless "+member;
  }
  public String sayHelloStatelessLocal() {
    return "Hello Local Stateless "+member;
  }
  public String sayHelloStatelessRemote() {
    return "Hello Remote Stateless "+member;
  }
  public void setMember(String member) {
    this.member=member;
  }
}

broersa@debian1:~/work/HelloApp/HelloStateless$ cat build.xml


<project name="HelloEJB" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/HelloStateless.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

And finally the client:broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ cat HelloStatefulClient.java


package com.bekijkhet.helloclient;
import javax.naming.*;
import com.bekijkhet.HelloStateful;
import com.bekijkhet.HelloStateless;
public class HelloStatefulClient {
  public static void main(String[] args) {
    try {
      InitialContext ctx = new InitialContext();
      HelloStateful h = (HelloStateful)ctx.lookup("com.bekijkhet.HelloStateful");
      HelloStateful i = (HelloStateful)ctx.lookup("com.bekijkhet.HelloStateful");
      System.out.println(h.sayHelloStateful());
      h.setMember("Initialized!");
      System.out.println(h.sayHelloStateful());
      System.out.println(i.sayHelloStateful());
    }
    catch (Exception e) {
      System.out.println(e);
      e.printStackTrace();
    }
    try {
      InitialContext ctx = new InitialContext();
      HelloStateless j = (HelloStateless)ctx.lookup("com.bekijkhet.HelloStateless");
      HelloStateless k = (HelloStateless)ctx.lookup("com.bekijkhet.HelloStateless");
      System.out.println(j.sayHelloStateless());
      j.setMember("Init!");
      System.out.println(j.sayHelloStateless());
      System.out.println(k.sayHelloStateless());
    }
    catch (Exception e) {
      System.out.println(e);
      e.printStackTrace();
    }
  }
}

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ javac -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloStateful/dist/HelloStateful.jar:$HOME/work/HelloApp/HelloStateless/dist/HelloStateless.jar:. -d . HelloStatefulClient.javaRun for the first time:

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloStateful/dist/HelloStateful.jar:$HOME/work/HelloApp/HelloStateless/dist/HelloStateless.jar:. com.bekijkhet.helloclient.HelloStatefulClient
Hello Stateful Not set!
Hello Stateful Initialized!
Hello Stateful Not set!
Hello Stateless Not set!
Hello Stateless Init!
Hello Stateless Init!
Run for the second time:

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloStateful/dist/HelloStateful.jar:$HOME/work/HelloApp/HelloStateless/dist/HelloStateless.jar:. com.bekijkhet.helloclient.HelloStatefulClient
Hello Stateful Not set!
Hello Stateful Initialized!
Hello Stateful Not set!
Hello Stateless Init!
Hello Stateless Init!
Hello Stateless Init!

Notice that everytime you create a new stateful session bean you get a new fresh instance. But when you set it it keeps its state during the client session.

When a stateless session bean is created you always get the same instance (from out of a pool). It looks like the state is kept, but this is server independant and can never been garenteed. When we call the client again after +/- half an hour we get a fresh stateless bean, so it gets cleaned up. This clean up process can happen all the time, even between two calls of the same instance in the same client session.

November 20, 2007

Client calls EJB on Glassfish which calls EJB on OC4J 11G

Filed under: ejb, glassfish, j2ee, java, oc4j, oracle — broersa @ 9:21 pm

In this blog I’m showing a way to call an EJB in an OC4J container from an EJB in a Glassfish container.

Let’s start with the EJB in the OC4J 11G container:

broersa@debian1:~/work/HelloApp/HelloOrion/src/com/bekijkhet/orion$ cat HelloOrionLocal.java


package com.bekijkhet.orion;
public interface HelloOrionLocal {
  public String sayHello();
  public String sayHelloLocal();
}

broersa@debian1:~/work/HelloApp/HelloOrion/src/com/bekijkhet/orion$ cat HelloOrion.java


package com.bekijkhet.orion;
public interface HelloOrion {
  public String sayHello();
  public String sayHelloRemote();
}

broersa@debian1:~/work/HelloApp/HelloOrion/src/com/bekijkhet/orion$ cat HelloOrionBean.java


package com.bekijkhet.orion;
import javax.ejb.Stateless;
import javax.ejb.Remote;
import javax.ejb.Local;
@Stateless
@Remote(HelloOrion.class)
@Local(HelloOrionLocal.class)
public class HelloOrionBean implements HelloOrion,HelloOrionLocal {
  public String sayHello() {
    return "Hello Orion!!!!";
  }
  public String sayHelloLocal() {
    return "Hello Local Orion!!!!";
  }
  public String sayHelloRemote() {
    return "Hello Remote Orion!!!!";
  }
}

broersa@debian1:~/work/HelloApp/HelloOrion$ cat build.xml


<project name="HelloEJB" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/HelloOrion.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

Type ‘asant dist’ to create the EJB.Deploy the Bean to the OC4J container:

java -jar $ORACLE_HOME/j2ee/home/admin_client.jar deployer:oc4j:localhost oc4jadmin welcome -deploy -file $HOME/work/HelloApp/HelloOrion/dist/HelloOrion.jar -deploymentName HelloOrion

Now it is time to create the Bean in the Glassfish container which calls the HelloOrion Bean.First we need the Interface from the HelloOrion Bean that we gonna call in the OC4J container. I could include it in a jar file, but for the simplicity I just copy it in the HelloEJB project.

broersa@debian1:~/work/HelloApp/HelloEJB/src/com/bekijkhet/orion$ cat HelloOrion.java


package com.bekijkhet.orion;
public interface HelloOrion {
  public String sayHello();
  public String sayHelloRemote();
}

Then we need the actual Bean.

broersa@debian1:~/work/HelloApp/HelloEJB/src/com/bekijkhet$ cat Hello.java


package com.bekijkhet;
public interface Hello {
  public String sayHello();
}

broersa@debian1:~/work/HelloApp/HelloEJB/src/com/bekijkhet$ cat HelloBean.java


package com.bekijkhet;
import javax.ejb.Stateless;
import javax.ejb.EJB;
import javax.ejb.Remote;
import java.util.Properties;
import java.net.URL;
import javax.naming.*;
import com.bekijkhet.orion.HelloOrion;
@Stateless
@Remote(Hello.class)
public class HelloBean implements Hello {

  static String CONFIG_PROPERTIES = "ejb.properties";

  public String sayHello() {
    URL url = null;
    Properties props = null;
    HelloOrion h = null;
    // Use the ClassLoader to get the properties of the Bean to call
    url = Thread.currentThread().getContextClassLoader().getResource(CONFIG_PROPERTIES);
    if (url == null) {
      return "The configuration could not be found: " + CONFIG_PROPERTIES;
    } else {
      props = new Properties();
      try {
        props.load(url.openStream());
      }
      catch (java.io.IOException e) {
        return "Could not read configuration file from URL";
      }
    }
    try {
      Context ctx = new InitialContext(props);
      h = (HelloOrion)ctx.lookup("HelloOrionBean");
    } catch ( Exception e) { return e.toString(); }
    return "Hello From Glassfish!!!! "  + h.sayHelloRemote();
  }
}

broersa@debian1:~/work/HelloApp/HelloEJB/properties$ cat ejb.properties


java.naming.factory.initial=com.evermind.server.rmi.RMIInitialContextFactory
java.naming.provider.url=ormi://localhost/HelloOrion
java.naming.security.principal=oc4jadmin
java.naming.security.credentials=welcome

broersa@debian1:~/work/HelloApp/HelloEJB$ cat build.xml

<project name="HelloEJB" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}"/>
    <copy todir="${build}">
                        <fileset dir="properties">
                                <include name="*" />
                        </fileset>
                   </copy>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/HelloBean.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

Type asant dist to create the distribution jar.Type asadmin deploy dist/HelloBean.jar to deploy the Bean to glassfish.In this bean I use the classloader to get the properties to call the OC4J bean from a flat file which must be in the Classpath. After this I create a Inital context. To create this context Glassfish needs the $ORACLE_HOME/j2ee/home/oc4jclient.jar in $GLASSFISH/lib directory. After copying this jar you need to restart the Glassfish server.Now it is time to create a simple client to call the EJB in the glassfish container which calls the EJB in OC4J.

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ cat HelloClient.java


package com.bekijkhet.helloclient;
import javax.naming.*;
import com.bekijkhet.Hello;
public class HelloClient {
  public static void main(String[] args) {
    try {
      InitialContext ctx = new InitialContext();
      Hello h = (Hello)ctx.lookup("com.bekijkhet.Hello");
     System.out.println(h.sayHello());
    }
    catch (Exception e) {
      System.out.println(e);
      e.printStackTrace();
    }
  }
}

javac -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloEJB/dist/HelloBean.jar:. -d . HelloClient.java

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloEJB/dist/HelloBean.jar:. com.bekijkhet.helloclient.HelloClient

Hello From Glassfish!!!! Hello Remote Orion!!!!

November 9, 2007

Stateless EJB and client using OC4J 11G

Filed under: ejb, j2ee, java, oc4j, oracle — broersa @ 10:50 am

In a previous blog I showed a sample of a helloworld stateless ejb on glassfish. In this entry I use the same EJB but I will deploy the bean to the OC4J 11G container. I will use the same client to connect to the OC4J deployed bean. The principles are the same but to connect to the OC4J container we’ll need some other libraries and some new config files. Lets start with the deployment of the EJB to the OC4J container:

java -jar $ORACLE_HOME/j2ee/home/admin_client.jar deployer:oc4j:localhost oc4jadmin welcome -deploy -file $HOME/work/HelloApp/HelloEJB/dist/lib/HelloBean-<date>.jar -deploymentName HelloEJB

After deploying we get to the client side. First we need the client source.

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ cat HelloClient2.java


package com.bekijkhet.helloclient;
import javax.naming.*;
import com.bekijkhet.Hello;
public class HelloClient2 {
  public static void main(String[] args) {
    try {
      InitialContext ctx = new InitialContext();
      // Piece of code to list all remote JNDI resources
      //NamingEnumeration e = ctx.list("");
      //while (e.hasMore()) {
      //  System.out.println(e.next());
      //}
      Hello h = (Hello)ctx.lookup("HelloBean");
      System.out.println(h.sayHello());
      System.out.println(h.sayHelloRemote());
      // Will fail because we call the Remote Business interface
      // System.out.println(h.sayHelloLocal());
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Notice that by default the lookup needs the Bean name HelloBean.

For OC4J to lookup the InitialContext we need a properties file. This file has to be in the classpath. We use the current directory.

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ cat jndi.properties

java.naming.factory.initial=com.evermind.server.ApplicationClientInitialContextFactory
java.naming.provider.url=ormi://localhost/HelloEJB
java.naming.security.principal=oc4jadmin
java.naming.security.credentials=welcome

OC4J also expects a application-client.xml deployment descriptior:

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient/META-INF$ cat application-client.xml


<?xml version="1.0" encoding="UTF-8"?>

<application-client xmlns="http://java.sun.com/xml/ns/j2ee"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                    http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd"
                    version="1.4">

  <display-name>Client of the earsample</display-name>
  <description>client of the earsample</description>

</application-client>

After this we can compile the client:

javac -cp $ORACLE_HOME/j2ee/home/oc4j.jar:$ORACLE_HOME/j2ee/home/oc4jclient.jar:$HOME/work/HelloApp/HelloEJB/dist/lib/HelloBean-<date>.jar:. -d . HelloClient2.java

And then run the client:

java -cp $ORACLE_HOME/j2ee/home/oc4j.jar:$ORACLE_HOME/j2ee/home/oc4jclient.jar:$HOME/work/HelloApp/HelloEJB/dist/lib/HelloBean-<date>.jar:. com.bekijkhet.helloclient.HelloClient2

Hello World!!!!
Hello Remote World!!!!

Stateless EJB and client using Glassfish

Filed under: ejb, glassfish, j2ee, java — broersa @ 7:36 am

Remote interface to the Bean:
broersa@debian1:~/work/HelloApp/HelloEJB/src/com/bekijkhet$ cat Hello.java

 package com.bekijkhet;
 public interface Hello {
   public String sayHello();
   public String sayHelloRemote();
 }

Local interface to the Bean:
broersa@debian1:~/work/HelloApp/HelloEJB/src/com/bekijkhet$ cat HelloLocal.java

 package com.bekijkhet;
 public interface HelloLocal {
   public String sayHello();
   public String sayHelloLocal();
 }

Bean himself :
broersa@debian1:~/work/HelloApp/HelloEJB/src/com/bekijkhet$ cat HelloBean.java

 package com.bekijkhet;
 import javax.ejb.Stateless;
 import javax.ejb.Remote;
 import javax.ejb.Local;
 @Stateless
 @Remote(Hello.class)
 @Local(HelloLocal.class)
 public class HelloBean implements Hello,HelloLocal {
   public String sayHello() {
     return "Hello World!!!!";
   }
   public String sayHelloLocal() {
     return "Hello Local World!!!!";
   }
   public String sayHelloRemote() {
     return "Hello Remote World!!!!";
   }
 }

Build.xml script:
broersa@debian1:~/work/HelloApp/HelloEJB$ cat build.xml

<project name="HelloEJB" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}/lib"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/lib/HelloBean-${DSTAMP}.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

Do a asant dist to create the EJB jar file and use asadmin deploy <jarfile> to deploy the EJB to Glassfish.
As an example I wil create a simple stand alone client that will call the Remote interface of the EJB. Local isn’t possible because I create a stand alone client which does not reside inside the container.Client code:
broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ cat HelloClient.java

package com.bekijkhet.helloclient;
import javax.naming.*;
import com.bekijkhet.Hello;

public class HelloClient {
  public static void main(String[] args) {
    try {
      InitialContext ctx = new InitialContext();
      // Piece of code to list all remote JNDI resources
      //NamingEnumeration e = ctx.list("");
      //while (e.hasMore()) {
      //  System.out.println(e.next());
      //}

      Hello h = (Hello)ctx.lookup("com.bekijkhet.Hello");
      System.out.println(h.sayHello());
      System.out.println(h.sayHelloRemote());
      // Will fail because we call the Remote Business interface
      // System.out.println(h.sayHelloLocal());
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Use the next steps to compile and run the code:broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ javac -cp $GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/HelloEJB/dist/lib/HelloBean-<date>.jar:. -d . HelloClient.java

broersa@debian1:~/work/HelloApp/HelloClient/src/com/bekijkhet/helloclient$ java -cp $GLASSFISH_HOME/lib/javaee.jar:$GLASSFISH_HOME/lib/appserv-rt.jar:$HOME/work/HelloApp/HelloEJB/dist/lib/HelloBean-20071108.jar:. com.bekijkhet.helloclient.HelloClient

Hello World!!!!
Hello Remote World!!!!

This is a simple Hello world EJB sample. Have fun.

Blog at WordPress.com.