Monday, October 4, 2010

Exception Handling Principles

1.  System.out.println is expensive. These calls are synchronized for the duration of disk I/O, which

significantly slows throughput.

2. By default, stack traces are logged to the console. But browsing the console for an exception trace isn't feasible in

a production system.

3. In addition, they aren't guaranteed to show up in the production system, because system administrators can map

System.out and System.errs to ' ' [>nul] on NT and dev/nul on UNIX. Moreover, if you're running the

J2EE app server as an NT service, you won't even have a console.

4. Even if you redirect the console log to an output file, chances are that the file will be overwritten when the

production J2EE app servers are restarted.

5. Using System.out.println during testing and then removing them before production isn't an elegant solution

either, because doing so means your production code will not function the same as your test code.

6. If you can't handle an exception, don't catch it.

7. Catch an exception as close as possible to its source.

8. If you catch an exception, don't swallow it.

9. Log an exception where you catch it, unless you plan to re-throw it.

10. Preserve the stack trace when you re-throw the exception by wrapping the original exception in the new one.

11. Use as many typed exceptions as you need, particularly for application exceptions. Do not just use

java.lang.Exception every time you need to declare a throws clause. By fine graining the throws clause, it is self-

documenting and becomes evident to the caller that different exceptions have to be handled.

12. If you programming application logic, use unchecked exceptions to indicate an error from which the user cannot

recover. If you are creating third party libraries to be used by other developers, use checked exceptions for

unrecoverable errors too.

13. Never throw unchecked exceptions in your methods just because it clutters the method signature. There are some

scenarios where this is good (For e.g. EJB Interface/Implementations, where unchecked exceptions alter the bean

behavior in terms of transaction commit and rollback), but otherwise this is not a good practice.

14. Throw Application Exceptions as Unchecked Exceptions and Unrecoverable System exceptions as unchecked

exceptions.

15. Structure your methods according to how fine-grained your exception handling must be.


Wednesday, August 4, 2010

Develop a simple Maven plugin

While this is a really old topic, the process to develop a maven plugin still need some time to sort our especially for people who are not familiar with Maven, like me. So here is a very short introduction on how to develop a maven plugin and how to integrate it with your existing application.

Prerequisite: of course, you need Maven, and all other things will totally depend on your wish. For me, I use Eclipse with m2eclipse plugin which saves me some time to create the archetype of Maven plugin project. However, this is a rather simple process and everyone can do it in command line with only a few typing.

1. Create a new Maven plugin project in Eclipse. Here, we name the project groupid: Featheast, artifactid: maven-test-plugin. Please pay attention to the naming convention of artifactid which we will use a little bit later.

2. Under the src directory, create a new Class naming MyMojo which extends AbstractMojo. AbstractMojo is the class you must inherit for plugin to work, and the only method you have to implement is execute(), where the real business will happens.

3. In order for other project to recognize your plugin function, you have to specify what the Mojo does. In Maven, this is accomplished by add an annotation @goal for the class in the comment of class. This goal name will be used later for other projects to reference this function.

4. You can create any number of variables in the class which acts like a parameter for later process. Consider the whole class as a function, then this variables will be the arguments you passed in. For each variable, another annotation @parameter will be used to specify how to like the variable to external usage.

5. Set the real business logic in the execute() function. You can use the Maven log to print out or debug for your convenience. An internal method getLog() is always there for you to do so and the usage of it is quite similar to the log4j.

/**

*

* @author yudong

*

* @goal realmojo

*/

public class MyRealMojo extends AbstractMojo{



/**

* @parameter expression="${mymojo.username}"

*/

private String username;



/**

* @parameter expression="${mymojo.password}"

*/

private String password;







public void execute() throws MojoExecutionException, MojoFailureException {

if(password.length()<10){

getLog().info("Hey" + username +", your password is too short!");

}else{

getLog().info("Congratulations " + username + ", your password is all right!");

}

Set set = getPluginContext().keySet();

getLog().info("The context include " + set.size() + " entries");

Iterator iterator = set.iterator();



while(iterator.hasNext()){

Object key = iterator.next();

getLog().info(key.toString() + " : " + getPluginContext().get(key));

}

}

}

6. In the pom.xml, add any dependency you need, then add the maven-plugin-plugin  to build the plugin. Specify any goals that you want to be included in the build output.

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-plugin-plugin</artifactId>

<version>2.5.1</version>

<configuration>

<goalPrefix>Plugin.Test</goalPrefix>

<username>Featheast</username>

</configuration>

<goals>

<goal>

realmojo

</goal>

</goals>

</plugin>

</plugins>

</build>

7. Now your Maven plugin is created, build it with standard command: mvn install.

8. Create another project to use this plugin. Add the plugin configuration in the pom.xml, and specify the goal.

<build>

<plugins>

<plugin>

<groupId>Featheast</groupId>

<artifactId>maven-test-plugin</artifactId>

<version>0.0.1-SNAPSHOT</version>  

<executions>

<execution>

<phase>install</phase>

<goals>

<goal>realmojo</goal>

</goals>

<configuration>

<username>This is the usernmae</username>

</configuration>

</execution>

</executions>

</plugin>

</plugins>

</build>

9. You could specify the parameters in the configuration tag, or you can add -Dusername = XXX in the command line to pass in the parameters.

10. Finally what you did will be print on the console, once you build the new project.

Monday, August 2, 2010

Pre-EJB 3.0 Enterprise Bean

An enterprise bean is a server-side software component that can be deployed in a distributed multi-tiered environment, and it will remain that way going forward. Anyone who has worked with Enterprise JavaBeans technology before knows that there are three types of beans - session beans, entity beans, and message-driven beans. Historically an EJB component implementation has neven been contained in a single source file; a number of files work together to make up an implementation of an enterprise bean. Let us briefly go through these EJB implementation artifacts:

1) Enterprise bean class

The primary part of the bean used to be the implementation itself - which contained the guts of your logic - called the enterprise bean class. This was simply a Java class that conformed to a well-defined interface and obeyed certain rules. For instance, the EJB specification defined a few standard interfaces forced your bean class had to implement. Implementing these interfaces forced your bean class to expose certain methods that all bean must provide, as defined by the EJB component model. The EJB container called these required methods to manage your bean and alert your bean to significant events. The most basic interface that all of the session, entity and message-driven bean classes implemented is the javax.ejb.EnterpriseBean interface. This interface served as a marker interface, meaning that implementing this interface indicated that your class was indeed an enterprise bean class. Session beans, entity beans, and message-driven beans each had more specific interfaces that extended the component interface javax.ejb.EnterpriseBean, viz. javax.ejb.SessionBean, javax.ejb.EntityBean, and javax.ejb.MessageDrivenBean.

2) EJB Object

When a client wants to use an instance of an enterprise bean class, the client never invokes the method directly on an actual bean instance. Rather, the invocation is intercepted by the EJB container and then delegated to the bean instance. By intercepting requests, the EJB container can provide middleware services implicitly. Thus, the EJB container acted as a layer of indirection between the client code and the bean. This layer of indirection manifested itself as a single network-aware object called the EJB object. The container would generate the implementation of javax.ejb.EJBObject or javax.ejb.EJBLocalObject, depending on whether the bean was local or remote, that is whether it supported local or remote clients, at deployment time.

3) Remote interface

A remote interface, written by the bean provider, consisted of all the methods that were made available to the remote client of the bean.These methods usually would be business methods that the bean provider wants the remote clients of the bean to use. Remote interfaces had to comply with special rules that EJB specification defined. For example, all remote interfaces must be derived from the javax.ejb.EJBObject interface. The EJB object interface consisted of a number of methods, and the container would implement them for you.

4) Local interface

The local interface, written by the bean provider, consisted of all the methods that were made available to the local clients of the bean. Akin to the remote interface, the local interface provided business methods that the local bean clients could call. The local interface provided an efficient mechanism to enable use of EJB objects within the Java Virtual MAchine, without incurring the overhead of RMI-IIOP. An enterprise bean that expected to be used by remote as well as local clients had to support both local and remote interfaces.

5) Home interface

Home interfaces defined methods for creating, destroying, and finding local or remote EJB objects. They acted as life cycle interfaces for the EJB objects. Each bean was supposed to have a corresponding home interface. All home interfaces had to extend standard interface javax.ejb.EJBHome or javax.ejb.EJBLocalHome, depending on whether the enterprise bean was local or remote. The container generated home objects implementing the methods of this interface at the time of deployment. Clients acquired references to the EJB objects via these home objects. Even though the container implemented home interfaces as home objects, an EJB developer was still required to follow certain rules pertaining to the life-cycle methods of a home interface. For instance, for each createXXX() method in the home interface, the enterprise bean class was required to have a corresponding ejbCreateXXX() method.

6) Deployment descriptor

To inform the container about your middleware needs, you as a bean provider were required to declare your component' middleware needs - such as life-cycle management, transaction control, security services, and so on - in an XML-based deployment descriptor file. The container inspected the deployment descriptor and fulfilled the requirements laid out by you. The deployment descriptor thus played the key role in enabling implicit middleware services in the EJB framework.

7) Vendor-specific files

Since all EJB server vendors are different, they each have some proprietary value-added features. The EJB specification did not touch these features, such as how to configure load balancing, clustering, monitoring, and so on. Therefore, each EJB server vendor required you to include additional files specific to that vendor, such as a vendor specific XML or text-based deployment descriptor that the container would inspect to provide vendor-specific middleware services.

8) The Ejb-jar file

The Ejb-jar file, the packaging artifact, consisted of all the other implementation artifacts of your bean. Once you generated your bean classes, your home interfaces, your remote interfaces, and your deployment descriptor, you'd package them into an Ejb-jar file. It is this Ejb-jar file that you, as a bean provider, would pass around for deployment purpose to application assembles.

Sunday, August 1, 2010

Maven tips

1) Try to ensure there is no duplicates or different versions of dependencies in a project, which will lead errors or conflicts later on.

2) If only want dependencies to exist during the compile phase and then be removed, the scope of such dependency should be set to PROVIDED. PROVIDED scope is not transitive, and the dependencies is supposed to be provided by JDK or container.

3) Use mvn dependency:tree to display the dependencies structure of the whole project, and try to pipeline the output to a file will be more easily to be observed.

4) If you are sitting behind a firewall, set proxy configurations in settings.xml under your .m2 directory.

More to be continued.

Monday, July 12, 2010

Pipe or Redirect within Java Command

it's common knowledge to use Runtime.getRuntime().exec(command) to execute any Unix command or Windows command in a Java application. However, when you try to include the pipe '|' or  redirect '>' in the command to alter any output pattern, most of the time the Java will not interpret your command as expected which will turn out to be an error finally. For example, when I tried to run ffmpeg command to encode any video and would like to capture those outputs into a log file, an error of "Unable to find a suitable output format for '>'" will appear.

In order to make Java "understand" out purpose, you cannot directly insert the usual command into the exec() parameter. There is a workaround which will solve the issue.

Construct an array:

String[] commands = {
"/bin/sh",
"-c",
YOUR REAL COMMAND HERE
}

and pass the commands as argument to the Runtime.getRuntime().exec(commands). In this way, the Java environment will make a sh (YOU COULD USE BASH) environment to execute your command, which will take the pipe and redirect into consideration.

Thursday, July 8, 2010

Seven Java EE Performance Problems

1) Slow-running applications

2) Applications that degrade over tim

3) Slow memory leaks that gradually degrade performance

4) Huge memory leaks that crash the application server

5) Periodic CPU spikes and application freezes

6) Applications that behave significantly differently under a heavy load under normal usage patterns

7) Problems or anomalies that occur in production but cannot be reproduced in a test environment

Wednesday, July 7, 2010

Long IP Address

Most of the time, people will think of an IP adress as a String. Especially in Java, most of the time, developers will deal with IP address either with URL or String class. However, representing an IP adress with String has several disadvantages. First a String usually takes more memory comparing to the "same" value int or long, and it will be difficult to compare with other IP addresses with a String. And more importantly, it will not be possible for people to easily determine whether an IP address is in the range of another two IP addresses.

Since IP addresses (IPv4) are composed by four integers ranging from 0 - 255, it will be obviously easy to convert an String IP address to an numerical form which can also uniquely represent the IP address. That's how Long IP address emerges.

A simple method to convert the String IP address to a Long IP address (A.B.C.D) would be:

256*256*256*A + 256*256*B + 256*C + D

Using Long IP address will be helpful in certain scenarios, one is when you dealing with IP-Location mapping in Google App Engine. A very popular data called GeoIP created by MaxMind is heavily used in a lot of different projects. However, when parsing the IP addresses, what they have done in the Java library is first transform the IP String into an InetAddress, and then using getAddress() to get its byte[], and finally get the Long value. There will be no problem when you using this library in other platforms. But in Google App Engine, things will got stuck because of the InetAddress is on the black-list of GAE, which means you will not be able to play with this class. The workaround here would be using the converting method above, you can directly get the Long value which is what they have calculated all the way along.

There might be some other places Long IP addresses is useful, especially when dealing with range query of IP addresses.