Showing posts with label J2EE. Show all posts
Showing posts with label J2EE. Show all posts

Wednesday, January 12, 2011

Hello world EJB 3.1 with JBOSS

I’ve been in the Microsoft world for a while, there are a lot distributed technology in the Microsoft stack. DCOM, COM+,Remoting, ASMX/WCF.  What’s the equivalent term for EJB? I would say that’s dot net remoting.

for a typical remoting project, we need define the MBR Object, Host it ( single call, singleton or Client control activation.) using different options, (IIS or in-process hosting. the runtime will take care the proxy/sub stuff.)

here I will put a hello world EJB. Jboss will be the role of IIS.

like remoting,First define a Interface (shared as a contract between server and client. )

public interface ICalculatorBusinessObjects {
     public int Add(int ... args);
}

then Implement a MBR like remoting. 

@Stateless
@Remote
public class CalculatorBeanBase implements ICalculatorBusinessObjects {

    @Override
    public int Add(int... args) {
        // TODO Auto-generated method stub
        int i=0;
        System.out.println("------------------" + "get HIt on Server side, My hashcode" + this.hashCode() );
        for (int j : args) {
            i+=j;
        }
        return i;
    }

}

    

like the Microsoft attribute, those @xx are annotations.  the runtime will check thos annotation and enforce some ad-hoc logic. like provide different hosting control, transaction control,etc.

Once Done, need deployed it to a container or server . for .net , it’s just a assembly or a dll. for J2ee, a zip file called EJB jar.  you can click eclipse and export the build to a jar file firstEjb.jar

image 

then deploy the jar to Jboss.  drag and drop the jar to c:\jboss6\server\default\deploy folder. ( for standard configuration,  c:\jboss6\server\all\deploy  if you run with –c all option.)

the server discovers new bits and host it, also register a JDNI entry.  like the remoting .rem stuff.
image
the ejb is hosted and ready for client connection now.

for client code, just find the proxy by querying the JNDI server and call the biz logic.

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class main {

    public static void main(String[] args) throws NamingException {
        // TODO Auto-generated method stub
        Context context=new  InitialContext();
        ICalculatorBusinessObjects o=(ICalculatorBusinessObjects)context.lookup("java:CalculatorBeanBase/remote");
        System.out.println(o.getClass().getCanonicalName());
        System.out.println(o.Add(1,2,3,4,5));
    }

}

when you run the jboss, Jboss is also one JNDI server listening one a specific port , 1099 by default.

so you need tell the client, which jndi server we should talk to by put some environment variables like the following.

-Djava.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
-Djava.naming.provider.url=jnp://localhost:1099
-Djava.naming.factory.url.pkgs=org.jnp.interfaces

-Djnp.timeout=0
-Djnp.sotimeout=0

When you run the client, you will get the result as you expected, a simple calculator. but all logic runs on server, the Jboss jvm.

image

Jboss log.

image

here concludes the basic tutorial. have fun.

How to : test hibernate data access with SQL Server 2008

there are some prerequisites to test the hibernate data access with SQL server.

I will provide some snippets as following,

Create a java project, add the jars to the builder path. 101 with Hibernate, first create one POJO ( a basic entity bean with “attributes”), I will create a basic Class called TODO with two attributes, ID and Title.

package Domain;

public class TODO {

    private int ID;

    private String Title;

    public void setID(int iD) {
        ID = iD;
    }

    public int getID() {
        return ID;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getTitle() {
        return Title;
    }
}

Then Add one XML mapping for this Class. (the file will used by hibernate to interpret the field-column mapping, ID generation rules.) , always using the naming rules as [ENtity].HBM.XML which is optional.
for the entitye TODO, will be mapped to a table called TODOs, the ID generation rule is implemented by SQL server( identity column)

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Domain">

    <class table="TODOs" name="TODO">
        <id name="ID" column="ID">
            <generator class="native">
            </generator>
        </id>

        <property name="Title"></property>

    </class>
</hibernate-mapping>

 
then create one file HIbernate.cfg.xml ( the driver used to communicate with sql server. )

<?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>        <!-- Database connection settings -->
        <property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
        <property name="connection.url">jdbc:sqlserver://localhost;databaseName=test;integratedSecurity=true; </property>
        <property name="connection.username">not required</property>
        <property name="connection.password"></property>        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.SQLServer2008Dialect</property>        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">create-drop</property>
        <mapping resource="test/TODO.hbm.xml" />
    </session-factory>
</hibernate-configuration>

Then, read /write to and from DB using the hibernate API.

package test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Main {

    /**
     * @param args
     * @throws ClassNotFoundException
     */
    public static void main(String[] args) {

        SessionFactory factory = new Configuration().configure(
                "test/hibernate.cfg.xml").buildSessionFactory();
        Session session = factory.getCurrentSession();
        Transaction trans = session.beginTransaction();

        Domain.TODO newobj = new Domain.TODO();
        newobj.setTitle("FirstTODO");
        session.save(newobj);

        Domain.TODO newobj2 = new Domain.TODO();
        newobj2.setTitle("SecondTODO");
        session.save(newobj2);
        // list all objects

        java.util.List lists = session.createQuery("from TODO").list();
        System.out.println(lists.size());
        for (int i = 0; i < lists.size(); i++) {
            System.out.println(((Domain.TODO) lists.get(i)).getTitle());
        }

        trans.commit();

    }

}

When you run the program, it will create two records and save it to DB. here is the sql used captured by SQL profiler.

image

If you get the error when you run the app,

Jan 12, 2011 2:19:19 PM com.microsoft.sqlserver.jdbc.AuthenticationJNI <clinit>
WARNING: Failed to load the sqljdbc_auth.dll cause :- no sqljdbc_auth in java.library.path

that means the JDBC driver need loaded some DLL in order to work with SQL server. just copy this dll [located in the driver auth folder] to the class path folder. or just c:\windows folder.
this only applies if we use the Windows authentication against sql server instead of sql authentication.

<property name="connection.url">jdbc:sqlserver://localhost;databaseName=test;integratedSecurity=false; </property>





 

 
Locations of visitors to this page