Monday, December 05, 2005

JBoss Shutdown and Restart

Dimitris fixed an issue which minor though, but important for system administrators:
jboss.system:type=Server (exit|halt) 10 doesn't restart jboss

Wednesday, November 16, 2005

J2EE Security: Authentication and Authorization

JSR-115 (JACC) defines a container contract for authorization purposes. JSR-115 defines a SPI for authentication for containers. I think these two specs are very important for a J2EE container provider when it comes to security.

Now, JACC can be used for externalizing authorization decisions.
(Reference: IBM Material)

The following sections describe how the provider is called for both the enterprise bean and the Web resources.

Access decisions for enterprise beans:
When security is enabled, and an EJB method is accessed, the EJB container delegates the authorization check to the security run time. If JACC is enabled, the security run time uses the following process to perform the authorization check:

1. Creates the EJBMethodPermission object using the bean name, method name, interface name, and the method signature.
2. Creates the context ID and sets it on the thread by using the PolicyContext.setContextID(contextID) method.
3. Registers the required policy context handlers, including the Subject policy context handler.
4. Creates the ProtectionDomain object with principal in the Subject. If no principal exists, null is passed for the principal name.
5. The access decision is delegated to the JACC provider by calling the implies method of the Policy object, which is implemented by the provider. The EJBMethodPermission and the ProtectionDomain objects are passed to this method.
6. The isCallerInRole access check also follows the same process, except that an EJBRoleRefPermission object is created instead of an EJBMethodPermission object.

Access decisions for Web resources:
When security is enabled and configured to use a JACC provider, and when a Web resource such as a servlet or a JavaServer Pages (JSP) file is accessed, the security run time delegates the authorization decision to the JACC provider by using the following process:

1. A WebResourcePermission object is created to see if the URI is cleared. If the provider honors the Everyone subject it is also selected here.
A. The WebResourcePermission object is constructed with the urlPattern and the HTTP method accessed.
B. A ProtectionDomain object with a null principal name is created.
C. The JACC provider Policy.implies method is called with the permission and the protection domain. If the URI access is cleared or given access to the Everyone subject, the provider permits access (return true) in the implies method. Access is then granted without further checks.
2. If access is not granted in the previous step, a WebUserDataPermission object is created and used to see if the Uniform Resource Identifier (URI) is precluded, excluded or must be redirected using the HTTPS protocol.
A. The WebUserDataPermission object is constructed with the urlPattern accessed, the HTTP method invoked, and the transport type of the request. If the request is over HTTPS, the transport type is set to CONFIDENTIAL; otherwise, null is passed .
B. A ProtectionDomain object with a null principal name is created.
C. The JACC provider Policy.implies method is called with the permission and the protection domain. If the request is using the HTTPS protocol and the implies method returns false, the HTTP 403 error is returned to imply excluded and precluded permission. In this case no further checks are performed. If the request is not using the HTTPS protocol, and the implies returns false, the request is redirected over HTTPS.
3. The security run time attempts to authenticate the user. If the authentication information already exists (for example, LTPA token), it is used. Otherwise, the user's credentials must be entered.
4. After the user credentials are validated, a final authorization check is performed to see if the user is granted access privileges to the URI.
A. As in Step 1, the WebResourcePermission object is created. The ProtectionDomain object now contains the Principal that is attempting to access the URI. The Subject policy context handler also contains the user’s information, which can be used for the access check.
B. The provider implies method is called using the Permission object and the ProtectionDomain object created previously. If the user is granted permission to access the resource, the implies method returns true. If the user is not granted access, the implies method returns false.


Related Articles/Resources
JAAS Authorization
Java Access Control Mechanism [Good PDF on XACML Site]
Java Authorization Internals (Great Article)
Simplify enterprise Java authentication with single sign-on

Authorization Resources
XACML -- A No-Nonsense Developer's Guide

Wednesday, November 02, 2005

Hashtable and HashCode

I am a big fan of Richard Monson-Haefel's technical books (EJB, JMS and J2EE Web Services).

Here is an explanation of Hashtable and Hashcodes that few developers grasp in practice:
A Hashtable is designed to provide fast lookups by binding an object to a key. Given any object's key, looking the object up in a hash table is a very quick operation. For the lookup, the key is converted to an integer value using the key's hashCode() method.


Hash codes do not need to be unique, only well-distributed. By "well-distributed," we mean that given any two keys, the chances are very good that the hash codes for the keys will be different. A well-distributed hash code algorithm reduces, but does not eliminate, the possibility that different keys evaluate to the same hash code. When keys evaluate to the same hash code, they are stored together and uniquely identified by their equals() method. If you look up an object using a key that evaluates to a hash code that is shared by several other keys, the Hashtable locates the group of objects that have been stored with the same hash code; then it uses the key's equals() method to determine which key (and hence, which object) you want. (That's why you have to override the equals() method in primary keys, as well as the hashCode() method.) Therefore, the emphasis in designing a good hash code algorithm is on producing codes that are well-distributed rather than unique. This allows you to design an index for associating keys with objects that is easy to compute, and therefore fast.


Source: Enterprise Java Beans, Second Edition



A decent writeup on HashCode and Equals is here:
HashCode and Equals in Java

Tuesday, October 25, 2005

When is a Programmer a developer?

Ever wondered the difference between a Programmer and a Developer? I did long ago. An interesting weblog of a person who runs a small ISV. Interesting read though.

Gives you a good insight into startup life. Many of you have worked in big companies and are transitioning into a small firm/ startups. This weblog reading is a good thing to remember:

You need Developers, not Programmers

By the way, the following link that describes patterns for programming is excellent:
From Apprentice to Journeyman

and the other excellent article from E.Djikstra is at:
The Humble Programmer

Friday, October 14, 2005

Good Programmers are lazy and dumb?

Good Programmers are lazy and dumb

Look at additional resources:
Ottinger's Rules for Variable and Class Naming


Take a lifetime to be a good (and happy) programmer

Another interesting post on the JavaLobby website:
My Top Ten Tips on how to become a Rock Star Programmer

An inspirational article from Dr. Heinz M. Kabutz:
Java Programmers aren't Born

Thursday, October 13, 2005

Tuesday, September 27, 2005

CVS Tricks

Objective: You want to merge from a branch Branch_Q into branch Branch_P

cvs -q update -j Branch_P -j Branch_Q

Objective: Create a branch Branch_P at the location where a branch Branch_M has been tagged.

cvs rtag -r Branch_M Branch_P directory

Objective: TAGGING, BRANCHING and MERGING.
Let's say you want to try something out but still be able to easily come back to the current version of the code if your experiment doesn't work. However, you want to keep the experiment around, or you want to be able to edit the main branch at the same time.

1. Commit current code.

> cvs commit

2. Tag the current code

> cvs tag before_new_image_code

3. Create a new branch

> cvs tag -b new_image_code

4. Move to new branch

> cvs update -r new_image_code

Now any changes which are made will be commited to the new branch. To switch back and forth between the branch and the trunk use the following commands.

* Move back to trunk/main version of code.

cvs update -A

* Move back to specified branch

cvs update -r new_image_code

Make sure to do a commit before switching to another branch. Update will overwrite your current working files with the latest version from the branch you specify, so all changes will be lost unless they have been committed.

Let's say your experiment worked and you want to merge the branches.

1. Move to main branch

> cvs update -A

2. See what the differences are between the branch we want to merge with and the main branch.

> cvs diff -r new_image_code

3. Merge the branch into the main branch.

> cvs update -j new_image_code

You will be told about any conflicts during the merge, and you won't be allowed to commit the files until those conflicts are dealt with.

REFERENCE
CVS Notes

Sunday, September 25, 2005

Good Web Services Resources

Web Services can be key when working towards SOA or light coupled systems. A good resource on web services is the MSDN library on .Net web services. It contains good stuff for people who are trying to understand the ins and outs of web services.
.Net Web Services
SOAP Headers


SAAJ: No strings attached

Wednesday, September 21, 2005

JVM Heap Tuning

I am going to just compile a list of urls that refer to JVM tuning.


  1. Java Forums - Large JVM heap sizes under windows xp?


  2. Change JDK DLL rebasing on win32 to allow larger maximum heap

  3. Look at the following article that talks on JVM Stack/Heap based allocation plus threadlocal allocation etc in this nice article:

  4. JVM Performance

Sunday, September 18, 2005

Understanding memory management with Caching Objects in Memory

This is a common problem. How much should we cache in memory? Will we run into Out Of Memory Errors?

I suggest you have a look at the SoftReference class in Java. It is an excellent construct that can save you this OOM headache.

Articles:

  1. Implementing a SoftReference-based HashMap

  2. SoftReference, WeakReference, and WeakHashMap in Java

  3. Garbage Collection

  4. Java: Performance Tuning and Memory Management

Friday, August 19, 2005

JBossMQ in JBoss

JBossMQ is the JMS 1.1 spec compliant provider in JBoss 4.x

Adrian points to a discussion on MDB singleton semantics:
MDB Singleton Semantics
(Working with NonJBoss deployments)

Sonic MQ is an industry leading vendor on messaging. They have a tutorial to integrate SonicMQ 6.1 to use with MDBs running on JBoss 3.2.5. The link is:
SonicMQ integration with JBoss

Now an user has reported a workaround to make the tutorial work on JBoss 4.0.1 onwards.


1)Edit the sonicmq-service.xml file in the deploy directory and
2) change org.jboss.jms.jndi.JBossMQProvider to
org.jboss.jms.jndi.JNDIProviderAdapter.
3) Restart JBoss and the example MDBs will work as advertised.


A great resource to look at configuring MDBs deployed on the JBoss platform to talk to remote queues is.
HowDoIConfigureAnMDBToTalkToARemoteQueue??

Case for J2EE Web Services with JBoss(Part 2)

This will be the placeholder to discuss J2EE Web Services with JBoss. Part 2.

Friday, August 12, 2005

Case for J2EE Web Services with JBoss(Part 1)

Importance of Web Services


Web Services have an important role to play in an enterprise. They can act as the glue between disparate systems, many of them written in different languages. The basis of integration can be:
a) Through files written on a common shared server.
b) Through a database that is shared between systems.
c) Sending messages between systems.
d) Using a common format(XML) on an universally accepted transport protocol (HTTP).

Section d) is what constitutes the world of Web Services.

The key terms to note in Web Services are as follows:
a) SOAP: It is the protocol used to exchange standard xml messages.
b) WSDL: This is the universally accepted contract for web services. Basically describes the service, the operations it supports, the message formats and the data types.
c) UDDI: It is a registry that acts as a yellow page for service discovery.
d) Marshalling: Convert Java Objects to XML Messages.
e) UnMarshalling: Convert XML Messages to Java Objects.

J2EE Web Services


Now given the basic stuff, lets move on to the J2EE paradigm of developing Web Services. The J2EE world defines a mechanism to use objects, classes and xml deployment descriptors to define web services.

Now lets discuss developing J2EE Web Services with JBoss, a robust J2EE Application Server which provides J2EE 1.4 compliant Web Services since v4.0.x

As a service provider, you will either want to expose a POJO or a SLSB. Now, these two are implementation classes, right? that contain the Web Service. Given this, the client (whether remote or local to the J2EE container) needs to see an INTERFACE.

J2EE 1.4 Web Service aptly defines an interface called SERVICE ENDPOINT INTERFACE (SEI) which basically extends java.rmi.Remote and all its methods have to throw RemoteException in addition to application exceptions. Now this SEI should front the Web Service implementation. J2EE 1.4 defines a deployment archive for the webservices - POJO is deployed as a war (Web Archive) and a SLSB is deployed as a EJB jar.

JBoss and J2EE Web Services



JBoss 4.x supports J2EE 1.4 Web Services. It supports rpc/literal and document/literal style web services only in line with WS-I Basic Profile 1.0 compliance.

Now lets take a very simple example of rpc based web services.

Lets say I have the following Web Service implementation as a POJO:

public class MyTestService
{
public void print(String name)
{
System.out.println("Hello "+name);
}
}

Okay, this is a simple example. Now this is our implementation class. If you want to deploy this as a J2EE Web Service, u will need to define a SEI. It is shown below:

public interface MyInterface extends Remote
{
public void print(String name) throws RemoteException;
}


Serverside Deployment


Now use wscompile tool from Sun's JWSDP and generate the serverside artifacts using this SEI. The artifacts will be a WSDL file, a jaxrpc mapping file. Ignore all the other stuff like serializers, stuns, ties etc. If there are any user defined types that are used in the SEI (remember this was just a simple example), then you need those.

Lets look at the wscompile configuration file(MyService-config.xml) for the serverside generation.

<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<service name="MyService"
targetnamespace="http://jboss.org/test"
typenamespace="http://jboss.org/test/types"
packagename="org.jboss.test">
<interface name="org.jboss.test.MyInterface ">
</interface>
</service>
</configuration>


The command line usage of wscompile is shown below:

wscompile.bat -cp classes -d build -gen:server -keep -mapping
mapping/jaxrpc-mapping.xml config/MyService-config.xml


Plus, you will need to hand edit a webservices.xml file that lists the SEI and a servlet-link. Plus create a web.xml file, just the way you do web programming. The servlet name will be the same as the servlet-link in the webservices.xml file. Also the servlet class will be the webservices implementation class, in our case, a POJO or MyTestService.

Serverside Packaging
Now package the war file with the implementation class, the SEI class, weservices.xml file, web.xml file and the WSDL file (Remember that it has to be RPC/Literal in our case. If it is RPC/Encoded, u might as well take a hike).
Thats it- that constitutes the serverside deployment.

Lets look at how my serverside deployment archive looks like (as we are exposing a POJO, we will be using a war file).

$ jar tvf MyTest.war
0 Tue Aug 16 01:51:08 CDT 2005 META-INF/
106 Tue Aug 16 01:51:06 CDT 2005 META-INF/MANIFEST.MF
0 Tue Aug 16 01:51:08 CDT 2005 WEB-INF/
0 Tue Aug 16 01:51:08 CDT 2005 WEB-INF/classes/
0 Tue Aug 16 01:10:36 CDT 2005 WEB-INF/classes/org/
0 Tue Aug 16 01:10:36 CDT 2005 WEB-INF/classes/org/jboss/
0 Tue Aug 16 01:50:58 CDT 2005 WEB-INF/classes/org/jboss/test/
237 Tue Aug 16 01:31:20 CDT 2005 WEB-INF/classes/org/jboss/test/MyServiceInterface.class
405 Tue Aug 16 01:51:02 CDT 2005 WEB-INF/classes/org/jboss/test/MyTestService.class
1734 Mon Aug 15 23:15:42 CDT 2005 WEB-INF/jaxrpc-mapping.xml
857 Tue Aug 16 01:29:12 CDT 2005 WEB-INF/webservices.xml
0 Mon Aug 15 23:12:10 CDT 2005 WEB-INF/wsdl/
1378 Mon Aug 15 23:12:10 CDT 2005 WEB-INF/wsdl/MyService.wsdl
393 Tue Aug 16 01:42:48 CDT 2005 WEB-INF/web.xml


Please make a good note of the file structure. Also note that MyTestService.class is my implementation of the service endpoint interface.

Want to have a look at the webservices.xml file, I hand edited?


<?xml version="1.0" encoding="UTF-8" ?>
<webservices xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:impl="http://org.jbos
ss.test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocatio
n="http://java.sun.com/xml/ns/j2ee http://www.ibm.com/webservices/xsd/j2ee_web_s
ervices_1_1.xsd" version="1.1">
<webservice-description>
<webservice-description-name>MyTestService</webservice-description-name>
<wsdl-file>WEB-INF/wsdl/MyService.wsdl</wsdl-file>
<jaxrpc-mapping-file>WEB-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file>
<port-component>
<port-component-name>MyInterfacePort</port-component-name>
<wsdl-port>impl:MyInterfacePort</wsdl-port>
<service-endpoint-interface>org.jboss.test.MyInterface</service-endpoint-interface>
<service-impl-bean>
<servlet-link>MyServlet</servlet-link>
</service-impl-bean>
</port-component>
</webservice-description>
</webservices>


Client Side Deployment

Still in Jboss deploy directory
We are not done yet. We need to do a client side deployment on JBoss so that javax.xml.rpc.Service object gets bound to JNDI for use by clients using the Dynamic Proxy approach. For more information on Dynamic Proxy introduced since JDK 1.3, I suggest looking for documentation on java.lang.reflect.Proxy and the invocation handlers.

With JBoss, client can either use Dynamic Proxy approach or the Dynamic Invocation Interface (DII) approach. Dynamic Proxy approach is recommended for the most compatibility. If you need to use Generated stubs/ties, sorry, using the wrong application server. Read the paragraph carefully. Only Dynamic Proxy or DII. Lets stick to Dynamic Proxy approach.

Client Side Deployment

Now when u deploy the serverside deployment on JBoss, the wsdl will be published to the context provided by the war. In our example,
http://localhost:8080/MyTest?wsdl that will give you the wsdl. Note that I would have packaged my was as MyTest.war

Now use wscompile to do client side generation using the wsdl location I just mentioned or having a physical copy of the wsdl on disk. Now out of the generated artifacts, choose:
a) Generated Service class.
b) SEI class.
c) Generated User types.
d) wsdl file
e) j2ee client file called application-client.xml that contains the service-ref element.

Lets look at the client side configuration file(MyServiceClient-config.xml) for wscompile:


<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<wsdl location="build/MyService.wsdl" packagename="org.jboss.test">
</wsdl>
</configuration>


Lets look at the command line usage of wscompile to generate client side artifacts

wscompile.bat -cp classes -d build -gen:client -keep -mapping
mapping/jaxrpc-client-mapping.xml config/MyServiceClient-config.xml


Package this together as a jar file and deploy on JBoss. This will bind a Service Proxy to JNDI to be downloadable by WS clients.

Lets have a look at my client side jar that needs to be deployed in the deploy directory of JBoss.


$ jar tvf MyTest-client.jar
0 Tue Aug 16 01:51:08 CDT 2005 META-INF/
106 Tue Aug 16 01:51:06 CDT 2005 META-INF/MANIFEST.MF
797 Tue Aug 16 01:19:58 CDT 2005 META-INF/application-client.xml
242 Tue Aug 16 01:19:58 CDT 2005 META-INF/jboss-client.xml
1602 Tue Aug 16 01:19:58 CDT 2005 META-INF/jaxrpc-client-mapping.xml
0 Tue Aug 16 01:37:48 CDT 2005 META-INF/wsdl/
1382 Tue Aug 16 01:37:48 CDT 2005 META-INF/wsdl/MyService.wsdl
0 Tue Aug 16 01:51:08 CDT 2005 My.jar


Note My.jar contains the Service class wscompile generates. I have attached the structure below:

$ jar tvf My.jar
0 Tue Aug 16 01:51:08 CDT 2005 org/
106 Tue Aug 16 01:51:06 CDT 2005 org/jboss
797 Tue Aug 16 01:19:58 CDT 2005 org/jboss/test
242 Tue Aug 16 01:19:58 CDT 2005 org/jboss/test/MyServiceInterface.class
1602 Tue Aug 16 01:19:58 CDT 2005 org/jboss/test/MyService.class

As shown you will still need to package the service endpoint interface along with the Service interface generated by wscompile.

Now let me show you application-client.xml that is packaged.


<?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>webservice client</display-name>
<service-ref>
<service-ref-name>service/MyService</service-ref-name>
<service-interface>javax.xml.rpc.Service</service-interface>
<wsdl-file>META-INF/wsdl/MyService.wsdl</wsdl-file>
<jaxrpc-mapping-file>META-INF/jaxrpc-client-mapping.xml</jaxrpc-mapping-file>
<port-component-ref>
<service-endpoint-interface>org.jboss.test.MyInterface</service-endpoint-interface>
</port-component-ref>
</service-ref>
</application-client>


Lets look at the jboss-client.xml that is packaged.


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

<!DOCTYPE jboss-client PUBLIC
"-//JBoss//DTD Application Client 3.2//EN"
"http://www.jboss.org/j2ee/dtd/jboss-client_3_2.dtd">

<jboss-client>
<jndi-name>ws-client</jndi-name>
</jboss-client>


Note jboss-client.xml is very important as it identifies the client context under which the JNDI bindings will happen.

Web Services Consumers




import javax.xml.namespace.*;
import java.net.URL;
import javax.xml.rpc.*;
import javax.naming.*;
import java.util.*;

import org.jboss.test.*;

public class TestClient
{
private static final String WSDL_LOCATION = "http://localhost:8080/MyTest?wsdl"
;
private static String NAMESPACE = "http://jboss.org/test";
private static final QName SERVICE_NAME = new QName(NAMESPACE, "MyService");
private static String NS_XSD = "http://www.w3.org/2001/XMLSchema";

public static void main(String[] args) throws Exception
{
InitialContext iniCtx = getInitialContext();
Service service = (Service)iniCtx.lookup("java:comp/env/service/MyService");
MyServiceInterface endpoint =
(MyServiceInterface)service.getPort(MyServiceInterface.class);
//Invoke the Web Service
endpoint.print();
}

/**
* Get the client's env context
*/
protected static InitialContext getInitialContext() throws NamingException
{
Properties env = new Properties();
env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
env.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming.client");
env.setProperty(Context.PROVIDER_URL, "jnp://localhost:1099");
env.setProperty("j2ee.clientName", "ws-client");
return new InitialContext(env);
}


Notice the j2ee.clientName that uses the value from the jboss-client.xml file that was packaged in the client deployment jar. As you can see the test client code uses Dynamic Proxy approach.


Thats it for rpc literal webservices. For more information, please refer to the JBossWS Wiki page in the resources section. Also there are a lot of testcases/samples in the testsuite module of the JBoss CVS source repostitory.


Resources:
XML Data Binding Resources
Accessing Web Services from J2EE Components
JBoss Web Services

General Articles on the Web
Consuming a webservice using JAX-RPC
Web Services with JAX-RPC
Apache Axis 1.2 User Guide
The Argument Against SOAP Encoding

Frequent Questions:
- How Do I get the ServletRequest and associated certificated from a WS Invocation
in JBoss Web Services?



MessageContext messageContext = this.ctx.getMessageContext();
HttpServletRequest request = (HttpServletRequest) messageContext.getProperty("transport.http.servletRequest");
X509Certificate[] certificates = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");

Sunday, August 07, 2005

Open Source Jaxr implementation (Apache Scout)

I would like you to try out Apache Scout, the first open source implementation of the Java API for XML Registries (JAXR). Why am I preaching it? I wrote it.

JAXR is a specification that is mandated by J2EE 1.4 specification. I integrated Apache Scout (JAXR implementation) and Apache jUDDI (UDDI v2.0 compliant) into JBoss, since v4.0.2

So if you are in need of a UDDI registry and a standard way of accessing it, please try out JBoss v4.0.2 (or later).
JAXR in JBoss

Tuesday, July 26, 2005

Case for a POJO MicroContainer

People who are familiar with J2EE realize that it is a complicated/bloated and cumbersome world. How easy it would be if we could deal with Plain Old Java Objects [POJOs]? Remember writing a "Hello World" program with EJB 2.1

Pundits will tell you that EJBs are not for Hello World kind of programs. I agree. It was just an example.

J2EE provides you a container and as a component running in the container, you get all the services the container is capable of - naming via JNDI, Security, Transactions (Yummy), EIS Integration via JCA (includes good old JDBC connections), caching, pooling etc etc.

Consider the case where I have a POJO. Lets call it the Employee POJO. Nothing fancy about it. Now as an Employee POJO, I want database access, transactions to update my salary (ha ha), security controls (so that only my Manager Pojo) updates my salary etc etc.

To get all this, I would go J2EE. I would write an EJB and cry a lot because to test my business logic, I would need a container. AND the container takes a hell lot of time to start (Paradigm changed by JBoss of course - fast startup).

Now since you have read this much on my blog, lets cut to the chase.

Since I mentioned I want to deal with POJOs and POJOs alone, lets do POJOs only. But what about the services I need from the container? Gawd, I will have to instrument my code to lookup the service, implement the EJB container callbacks etc.

Here is my code:


public class Employee
{
String name;
float salary;

public void updateSalary(float addAmount)
{salary += addAmount;}

}


Damn, simple POJO. Now I want to implement this as a stateless session bean and I want the container to provide the "REQUIRED" transactional isolation. Only the "Manager" roled user cannot invoke the updateSalary method. All this is possible by making the POJO implement javax.ejb.SessionBean interface and add dummy container callback methods. Go to the f***ing deployment descriptor, set the security and transactional semantics. Excellent work, Joe. I said I wanna deal with POJOs alone. Now you made me do SLSB. What if I want my POJO to be a servlet, a Web Service endpoint. Sweet Jesus, you are asking too much.

Don't despair! There is help on the way. With the introduction of JDK5 annotations, life will be simpler for developers. Plus less XML deployment descriptor hell. With J2EE5 and EJB3, annotations will do all the work AND THE CONTAINER WILL iNjEcT the services you need.

Lets look at the same POJO.


public class Employee
{
@Inject EntityManager manager;
String name;
float salary;

public void updateSalary(float addAmount)
{salary += addAmount;}

}


Don't go with the syntax. I am just trying to get the message across. Now the @Inject annotation will tell the container that I need this POJO to be persistent. Wow!! I got the entity bean capability for my POJO.

Now how about if my bean needs transactions. I will need the services of a transaction manager. Let the container inject it.


public class Employee
{
@Inject TransactionManager manager;
String name;
float salary;

@Transaction (type=required)
@Security (role=Manager)
public void updateSalary(float addAmount)
{salary += addAmount;}

}


Now I explicitly asked my method to have the REQUIRED semantics. If I do not specify, just because the container injected a TM, it can choose the default transaction semantics.

I am not done. Where are you going? Now I want to expose this bean as a web service. Thanks to JSR 181 annotations, all I need to do to the pojo is the @WebService annotation.


@WebService
public class Employee
{
String name;
float salary;

public void updateSalary(float addAmount)
{salary += addAmount;}
}


So having a POJO container, server or microcontainer or whatever you wanna call it, is going to be good. The container will be lightweight, can help in testing and will be mostly driven by annotations or some form of a xml dd. The idea is not the declarative descriptors in xml to drive the pojos.

The things you need to derive from this blog post are:
1) POJO based development is easier.
2) POJOs running in a container when annotated appropriately, can run an enterprise.
3) The POJO container can inject services into the POJO at runtime. As a POJO, you can specify which services you will need and the container will inject them. Instead of the gazillion default services that an EJB undergoes prior to J2EE5.
4) Take a POJO, add annotations and drop it in a container - it will become an EJB or a Servlet or a Web Service based on the services that are injected.

Now what if my team mate is a dumb ass and he does not know which annotations to use. Just specify the annotation and do not provide a type for the annotation. Let the container inject the default service [Eg: By default, the transaction type that is injected is "REQUIRED"]. Now if my dumbass team mate annotates @Transaction(type=never), the container will run the pojo method with no transaction.Now you know why he is a dumbass.

Monday, July 25, 2005

J2EE Classloading Mysteries

The J2EE specification has not clearly mandated the classloading scheme to be used by the containers. Hence every app server vendor does it in a different way. WebSphere does it differently, JBoss does it diff, Oracle does it diff and WebLogic does it diff.

Remember that in J2EE, Thread.currentThread.getContextLoader() is the king and the only method that should be utilised to do classloading. Debu Panda from Oracle has a blog on some best practices for J2EE classloading. J2EE Classloading Best Practices

OnJava Article on classloading. Inside Class Loaders: Debugging

Now if you want to learn about the internals of classloading, the following article is useful,Internals of Java Class Loading

Ok, for advanced classloading, read Advanced Classloading

Classloaders are powerful and are key to hot deployment of applications, that we have come to love, as developers. Thanks to JBoss.

XDoclet versus Java Annotations

I have nothing against XDoclet. It eases the development process for many developers. One issue I see is standards/maintenance. If somebody develops some custom doclet tags, be assured that they will not maintain them for ever.

Instead with the introduction of annotations in JDK5, you can get the power of xdoclet in a standard way. Plus EJB3, J2EE 5 as well as JSR-181 annotations for webservices all aim to ease development pain and the wrath of xml files.

I feel annotations are the way to go for developers.

Thursday, July 21, 2005

.Net versus Java

I moved over to the Java world from the MS world around 1998. Ever since, I have been attached to open standards, open forums, zero monopoly blah blah.

I fell in love with Java ever since, as I did not have to deal with the platform idiosynchracies. Now .Net is trying to make a comeback in my mind.

I had taken a huge laugh when MS created C# and then .Net and then Passport. Okay, C# gives you the best of C++ and Java. As I have been focussing on Web Services, a topic that is hot right now is how to make .Net programs communicate with Java programs.

MS, IBM etc created Web Services for this reason. Interoperability!!!

Since Web Services has promise, I need to give .Net a shot.

Apart from this, there is discussion about integrating .Net and J2EE via JMS. Ofcourse messaging can be the glue. Take a look at: .Net/J2EE via JMS

But I think there are two simpler ways of integrating .Net and J2EE (or JEE - whatever):- Databases and Regular files. BUT the developer has to do the brunt work in a non standard way.

I was reading Eric Newcomer's book: "Understanding Web Services". In that he mentions that J2EE views Web Services as Objects and Classes that will be turned into webservices by the webservice provider, whereas .Net views Web Services as something that will be created by a developer, which will be turned into Objects and classes by the .Net implementation. How true? Microsoft has always been the King at providing point and click tools to the developer/end user and does the brunt work (however mysterious it may be) in the background.

Java and Portability

Writing Java programs was a blessing to developers who did not have to bother about the platforms on which the programs would run. But as Java became enterprise quality and an enterprise darling, developers have to be aware of JVM issues and other platform issues. They should also befriend their sysadmin and their DBA, as they are as relevant to your project success as your quality code is.


Googling, I found this link, which talks of why Java is a nightmare for Sysadmins. Java Sucks For Sysadmins

Java IO abstraction creates the most problems on various platforms in my opinion.

Get to know swap spaces, file descriptors, ulimit command. Just because you know java.io.File, you are not an enterprise developer. Kidding!

Wednesday, July 20, 2005

CJUG Panel on Java Performance

Last evening (Tuesday) was a great evening. I hosted the first ever panel on Java Performance at the Chicago Java Users Group. CJUG's PR Janet Traub made it happen by getting the support of Bank Of America. So we used the great conference room at the Bank location on Lasalle Street, adjacent to the Chicago Board of Trade.



Since it was the first time, we were holding such an exercize, we invited panelists from the Chicagoland region only. Why take the trouble of inviting panelists from out of town, to disappoint them, if we do not meet their expectations?



Ok, lets get to the story now.



When it comes to Java and the topic is performance, the first thing that eludes anybody's mind, is the JVM performance. Very few Java knowledgeable people know about the JVM tuning/settings. They take the JVM for granted. Hence CJUG was very fortunate to have Brian Doherty from Sun Microsystems on the panel. Brian is a Chicago native and he works in the performance group dealing with the Sun JVM. So when it comes to benchmarking, Brian is the guy.We needed a representative from BEA to talk on JRockit and BEA suite of products. Siva Krishnan from BEA was present at the panel.There were two representatives from Oracle - Phil Bergman (Principal Solutions Architect, J2EE Application Server) and Phil McGlaughlin, formerly Actional and now Oracle.



Jon Hansen, formerly Sun Professional Services and now an independent consultant was on the panel. Jon is an expert in real world deployment of SOA, XML and Web Services for many big customers.



Tim O'Brien, author of a book on Maven and Jakarta Commons, who is an independent consultant, was also on the panel. Rob Lambert who is an independent consultant and has experience in Spring Framework was on the panel. But Rob did not get too much of a window to participate in the discussion. Dave Orme, Eclipse Visual Editor Lead and currently working for db4objects was on the panel too. Brian Pontarelli, CJUG president and Senior Engineer at Orbitz was there.



Questions from attendees.



Do the vendors like Sun,BEA, JBoss,Oracle etc do performance benchmarks before they release the product?



The answer from the vendors was that they do run a lot of industry standard benchmarks before they release the products. A general consensus was that many times benchmarks are done to clinch sales deals, as customers request for benchmark numbers. Also, benchmarks do not always cover real performance issues that may exist, but they do provide a lot of insight into the product for the engineers who are running the benchmarks.

What are the steps one can do to achieve performance?



Brian Doherty quoted Donald Knuth's famous quote: "Premature optimization is the root of all evil.". There was an argument as to whether it is suitable to first implement the algorithm and then optimize it or write a simple/optimized/maintainable algorithm.

General notes from the panel:



- Java Performance is the onestop location for Java Performance.

- VisualGC and JConsole are great tools to attach to the JVM in production where regular profiling tools like JProbe etc are not recommended.

- Brian Pontarelli discussed how Orbitz was revolutionizing computing via Jini and he discussed various benefits of Jini over traditional RMI.

- Some panelists agreed that the root of performance issues or a project being in mess is not really a technology problem but because of personnel and business expectations.

Sunday, July 17, 2005

Chicago Java Users Group: Panel on Java Performance

Its been two years since I have been associated with CJUG. On Tuesday (July 19), CJUG is holding a very important event, a panel on Java Performance. It will cover all facets on Java - JVM Performance, J2EE Performance, Applications performance, Monitoring etc.

Be sure to be there. http://www.cjug.org

Kent Spillner in Bangalore

Kent Spillner is a good friend of mine from Chicago. He is as old as my younger brother. He has helped me in moving furniture to my place from IKEA, Harlem Furniture etc.

He is now in Bangalore, getting trained at Thoughtworks. He was reading a lot of travel books before he went to India. I have asked him to find a nice Indian girl and get hooked when he comes back to the US.

He has told me over AIM that he likes Bangalore. I personally liked Old Bangalore, that was laidback and it was lot more fun + less crowded.

Who wants to see traffic jams on Sunday at 11am? Hey, it was just after 'Mahabharat' on TV. Kent is enjoying Bangalore. Eating all the yummy dosas, chats and the hustle/bustle of big city.

Kent, your 'firangi' story of drycleaning and underwears is hilarious.

For others, here is Kent's blog address:
Ken's Bangalore Blog


And his usual rants:
http://sl4mmy.blogspot.com


Now, Kent being in Guzzlers Paradise, I suggest that you retain the habit you will learn at Bangalore, when you are back in Chicago. I am counting on you for a decent New Year Binge. We need to celebrate with Prashanth (my other buddy)

Where to blog?

I have been blogging at various places - JBossBlog, Jroller etc. Never found one place to blog on technology as well as general stuff. Blogspot looks like a good place to blog about the day to day events.