Andre Broers’ personal blog

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

Change oc4jadmin password

Filed under: oc4j, oracle, security — broersa @ 2:23 pm

To change the password for the oc4jadmin administrator in oc4j stand alone you have to type a new password in the the system-jazn-data.xml file. Replace the encrypted string with the plain new password superseded with an exclamation point “!”. The next time you start oc4j it will encrypt the password.

December 19, 2007

Default Administrator login Oracle BI EE 10.1.3

Filed under: bi, business intelligence, oracle, security — broersa @ 2:16 pm

After installing Oracle Business Intelligence 10.1.3 on linux it was hard to find the default login to the Dashboard. Here it is:

username Administrator

password Administrator

Mind the capitals!

December 7, 2007

DNS resolve from Oracle Database 11g

Filed under: 11g, database, oracle, security — broersa @ 8:20 pm

For a a small home test datawarehouse I import all access.log data in a oracle database star shema. In 10g I used the following function to resolve the ip address to a hostname:


create or replace function resolve (ip varchar2) return varchar2 as
begin
  return utl_inaddr.get_host_name(ip);
exception
when others then
  return '-';
end;
 

In Oracle 10g this works out of the box. In 11g I get the following error:

SQL> select  utl_inaddr.get_host_name(‘127.0.0.1′) from dual;
select  utl_inaddr.get_host_name(‘127.0.0.1′) from dual
*
ERROR at line 1:
ORA-24247: network access denied by access control list (ACL)
ORA-06512: at “SYS.UTL_INADDR”, line 4
ORA-06512: at “SYS.UTL_INADDR”, line 35
ORA-06512: at line 1

SQL>

The solution is to create an acl for the user broersa with the privilege resolve granted. After this we have to assign the acl to all hosts.

connect / as sysdba

exec dbms_network_acl_admin.create_acl(acl => ‘resolve.xml’,description => ‘resolve acl’, principal => ‘BROERSA’, is_grant => true, privilege => ‘resolve’)
exec dbms_network_acl_admin.assign_acl(acl => ‘resolve.xml’, host => ‘*’);
connect broersa/xxxxxx

SQL>  select  utl_inaddr.get_host_name(‘127.0.0.1′) from dual;

UTL_INADDR.GET_HOST_NAME(‘127.0.0.1′)
——————————————————————————–
localhost.bekijkhet.com

SQL>

December 6, 2007

JMX Managed Bean with multiple agents

Filed under: java, jmx, mbean — broersa @ 12:31 pm

In this example I created a counter that gets updated from multiple instances. All examples I found on internet are using a single agent instance. The crux is to create a static MBean object that is available to all instances of the agent class. Let’s get to the code:

/home/broersa/work/mbean/mypack/MyCounterMBean.java


package mypack;
public interface MyCounterMBean {
   public int getCounter();
   public void sayCounter();
}

/home/broersa/work/mbean/mypack/MyCounter.java


package mypack;

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

   public MyCounter() {
      counter = 0;
   }

   public int getCounter() {
      return counter;
   }

   public void incCounter() {
     counter++;
   }

   public void sayCounter() {
      System.out.println(counter);
   }
}

/home/broersa/work/mbean/mypack/SimpleAgent.java


package mypack;

import javax.management.*;
import java.lang.management.*;

public class SimpleAgent {
   private static MyCounter counterBean = new MyCounter();
   private MBeanServer mbs = null;

   public SimpleAgent() {

      // Get the platform MBeanServer
       mbs = ManagementFactory.getPlatformMBeanServer();

      // Unique identification of MBeans
      // replaced by static var.     Hello helloBean = new Hello();
      ObjectName myCounterName = null;

      try {
         // Uniquely identify the MBeans and register them with the platform MBeanServer
         myCounterName = new ObjectName("SimpleAgent:name=MyCounter");
         mbs.registerMBean(counterBean, myCounterName);
      } catch (InstanceAlreadyExistsException e) {
         System.out.println("Instance Already Exists");
      } catch(Exception e) {
         e.printStackTrace();
      }
      counterBean.incCounter();
   }

   // Utility method: so that the application continues to run
   private static void waitForEnterPressed() {
      try {
         System.out.println("Press  to continue...");
         System.in.read();
      } catch (Exception e) {
         e.printStackTrace();
      }
    }

   public static void main(String argv[]) {
      SimpleAgent agent1 = new SimpleAgent();
      SimpleAgent agent2 = new SimpleAgent();
      System.out.println("SimpleAgent is running...");
      SimpleAgent.waitForEnterPressed();
   }
}

goto the directory mbean and compile the code:

javac -d . mypack/MyCounter.java

javac -d . mypack/SimpleAgent.java

run the code:

java -Dcom.sun.management.jmxremote mypack.SimpleAgent

Instance Already Exists
SimpleAgent is running…
Press  to continue…

When we connect to the MBeanServer using the jconsole utility we see the counter has the value 2:

JConsole sample

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

Blog at WordPress.com.