October 27, 2010

The Default Timeout Value for Standard Java Socket is Infinitive!

In my last week I have been doing some stability testing using both the Java standard java.net.Socket and javax.net.ssl.Socket. Which are both are part of the J2SE standard library. What I found out to my big surprise, was the standard value for socket timeout (getSOTimeout()) is infinitive!

What are the consequences of this? Well, except that all blocking socket operation will hang forever. But maybe the biggest problem is, it opens up for Denial of Service (DoS) problems.

Example DoS: A server is overloaded and services it's request slower and slower. And now, if new additional clients connected, even more resources are consumed. What will happen with this system in the end is it will ran out of memory or IO. This is not wanted!

What is wanted is a fail-fast strategy, i.e. client that do not get response in a certain time will close it Socket and report back to interactive user or machine.

October 24, 2010

Ubuntu 10.04 Change Default Size of Terminal

One of the probably first thing you want to change when starting using Ubuntu is to change the default size of the Terminal window. In earlier version of Ubuntu that could be accomplished via the Edit -> Profile Preference menu from the Terminal, but with Ubuntu 10.04 that is no longer possible. Instead do the following:


Go to System -> Preferences -> Preferred Applications -> System (tab)

Change Terminal Emulator to "Custom".
Command: gnome-terminal --geometry=237x24
Execution flag: -x

October 8, 2010

JAOO Day 4 – Not Only SQL, NOSQL

Today I listened to Emil Eifrem CTO at Neo Technology. What I liked most of his talk was the categorization of the today existing NOSQL solution:

Key-Value Database
An Amazons project that uses global key-value mapping to for DB.

Dynamo: Amazon's Highly Available Key-value Store (2007) (http://s3.amazonaws.com/AllThingsDistributed/sosp/amazon-dynamo-sosp2007.pdf).

Other Example:



Column Database
A Google project that uses a big table, with column families.

BigTable: A Distributed Storage System for Structured
 Data (2006) (http://labs.google.com/papers/bigtable.html)

Other Example:



Document Database
Data is organized as document and a document is a key-value pair.

Example:



Graph Database
Data is organized in a graph, which Nodes and Relationships have properties.

Example:

Example of company using NOSQL
  • Google: Bigtable
  • Amazon: Dynamo
  • Amazon: SimpleDB
  • Yahoo: HBase
  • Microsoft: Dynomite
  • Facebook: Cassandra
  • LinkedIn: Voldemort 

October 7, 2010

JAOO Day 4 – Java Future at Oracle

Today I was listening at Brian Goetz in his talk “Java Future at Oracle”. This talk was a warn welcome, since yesterday Java User Group, where it was not so much warmth about the evolving of the Java language, due to the problem in the Java Community Process (JCP). And how this has set footprint in the deliveries of new JDK version.

JDK 1.0 1996
JDK 1.1 1997
JDK 1.2 1998
JDK 1.3 2000
JDK 1.4 2002
JDK 5.0 2004
JDK 6.0 2006

JDK 7.0 2011?
JDK 8.0 ???

So what about new feature, well he said that they going to push out JDK 7.0, but of the expense of cutting functionality, which means in short:


And that's it.

But on the other hand he also said that JDK 8.0 will be planned to be released thereafter 1-2 years, which sounds promising. Which Project Lambda (http://openjdk.java.net/projects/lambda/) will among other stuff be included. Other stuff in the pipe is also the Project Jigsaw (http://openjdk.java.net/projects/jigsaw/).

But the most interesting stuff was the news that they plan to merge the HotSpot with the JRockit! Wow, what a killer that will be! But, an unanswered question is, if they will change the license model of the JDK. It is like Brian put it: Oracle is really an easy company to understand, it is about making money.

And what about the JCP? Well, he quickly mentioned the problem, and this a top priority for Oracle to solve. And I really do hope that they solve this and quickly.

October 5, 2010

JAOO Day 3. The Stagnation of the Java Language

Today I visited one of Java User Group (JUG) at the JAOO conference – the “Next next step for the Java ecosystem.” There were three person in panel James Gosling, Kevlin Henney and Dave Thomas and they all three confirmed on the misfortune fact that the Java Community Process (JCP) is not working properly or as Rod Johnson (member of JCP board) put it in his session “Where Next for Enterprise Java”. Compare the number of Java Specification Request (JSR) produced this year with the number produced 2-3 years back.

And one can really ask when JDK 7 will be released and how much really will be included of the project Coin (minor language feature change), Jigsaw (effort to make Java more modular) and Lambda (bring closure to Java)?!?

And I guess this fact is the why there today are so many new language created for the JVM – the community is responding and will not wait.

But there is rescue to the help and as James put it, if you cannot wait use Scala.

James Gosling
http://nighthacks.com/jag

Kevlin Henney
http://blogs.stickyminds.com
http://programmer.97things.oreilly.com/
http://curbralan.com/

Dave Thomas
davethomas.net
eclipse.org
agilealliance.org

Rod Johnson
http://blog.springsource.com/author/rodj/

Getting Started with Scala - IDE support

The key thing when start using a new library or as in this blog, start writing a completely new language, is to have an IDE that is working with and not against you.

I had the pleasure of talking with both Martin Odersky and Jonas Bonér at JAOO in Aarhus Denmark and they both recommended the IntelliJ Scala plugin, but Martin also added that he had started a company scalasolutions.com with one of the aim to write a better Scala plugin for Eclipse, and when that comes out, I would really recommend you to test it. Another question which IDE to choose is also of course which IDE you have previously worked with and acquainted with.

In this blog I will share my experience of using both the IntelliJ and Eclipse IDE, but also how to build your Scala code with Maven.

IntelliJ
Since I don't have a business license of IntelliJ I used the Community edition, you can find the comparison matrix between the free and commercial edition and also the download link from.
http://www.jetbrains.com/idea/features/editions_comparison_matrix.html

After installing IntelliJ, you install the Scala plugin with the Plugin Manager

File | Settings | Plugins

Select tab Available and search for Scala, then right click to install.

After restarting, you create a new Java Module and add Scala Library from local downloaded Scala distro.

Experience
Plus:
  • Normal code completion and code navigation works.
  • OBS when debugging, you have to append the name mangling '$1' to every variable to be able to Evaluate. This seems a bug in the Plugin, since the name mangling should be shielded from you and is strict Scala internal, to overcome Java restriction of operating overloading, etc.
Minus
  • The IntelliJ Scala plugin compiler is really slow, even for small amount of code. There are ways to get around this by using Scala background compiler server, but I have not got that up and running yet.

Eclipse
I used the Eclipse 3.5.2 (Galileo) and install the Eclipse Scala plugin (http://www.scala-ide.org/) with the Eclipse built in Software Installation.

Help | Install New Software... | http://download.scala-ide.org/update-current Add

After that you can create a new Scala Eclipse Project.

Experience
Plus
  • The Scala Plugin compiles code enormous time faster compared with the IntelliJ, but it also have drawbacks.
  • Code completion is not always working if program Scala in it most compact form, sometime it then helps to program a little more verbose, e.g. anonymous function "kalOk".exists(char => char.isUpperCase) instead of the more compact "kalOk".exists(_.isUpperCase)
  • OBS when debugging, you have to append the name mangling '$1' to every variable to be able to Evaluate. This seems a bug in the Plugin, since the name mangling should be shielded from you and is strict Scala internal, to overcome Java restriction of operating overloading, etc.
Minus
  • Code completion is not always working.

Conclusion
After testing both IDE, I must say that Eclipse wins, and mostly because of the slow compilation in IntelliJ. But I hope even if you choose to use another IDE, that this blog post helped you with choosing which IDE you will use.

Maven
After choosen IDE, you clearly also want to have build tool support and I will here discuss Maven, but I also knew that SBT (http://code.google.com/p/simple-build-tool/) is also a great alternative, but I will not cover that in this blog.

The simplest way is to use the scala archetype, but before please check the page http://docs.codehaus.org/display/MAVENUSER/Archetypes+List, to see that not a newer version has been released.
$ mvn archetype:generate -DarchetypeGroupId=org.scala-tools.archetypes -DarchetypeArtifactId=scala-archetype-simple -DarchetypeVersion=1.2 -DremoteRepositories=http://scala-tools.org/repo-releases -DgroupId=se.msc.example -DartifactId=scala-maven -Dversion=1.0-SNAPSHOT
To check that everything worked install the new Maven project.

Now lets open the new pom and see what has been generated. The first thing you see is that Scala 2.7.0 is used, change that to 2.8.0 but also remove the Scala Spec Test in

scala-maven/src/test/scala/se/msc/example/MySpec.scala

Finally you can also remove the specs dependency. I will in coming post discuss Scala Unit Testing, but for now simply use JUnit 4, that you are probably familiar with.

Thats it happy coding!

Day 2 at JAOO. A Compact Day with James Gosling, Jim Webber and GIT

Day 2 was a packed day with big stars as James Gosling and for you that don't know it, Gosling have quited Oracle, if you want to read more, google or read Gosling own blog http://nighthacks.com/roller/jag/.

But the day started with Cliff Click from Azul Systems (azulsystems.com) and talked about top ten performance problem they seen of hosted Java application in production. This was interesting and I will probably get back with a better blog about that. What also was interesting was suggested tools for detecting different kind of problem:

JVM

  • dtrace, hprof, introscope, jconsole, visual vm yourkit

OS

  • dtrace, oprofile

Network

  • Ganglia, iostat, lsof, nagios and netstat


The next talk was from Google about Scalability, Availability and Stability, which in mine humble opinion, brought not so much new solution to the problems. It all cooked down to sharding, fanning out,  replication vs. caching, eventual consistency and asynchronous calling.

After lunch did Jim Webber talked. Jim Webber is mainly the guy behing REST and if you are intrested about that you should definitely read his book. REST in Practise.
http://www.amazon.com/REST-Practice-Hypermedia-Systems-Architecture/dp/0596805829/ref=sr_1_1?s=books&ie=UTF8&qid=1286232319&sr=1-1

At the end of evening I had the pleasure of talking to both Martin Odersky and Jonas Bonér about the new started company Scala Solution (http://www.scalasolutions.com/) IDE plugns, faster compile time, who is owning the code, founding and Scala akka (http://akkasource.org/), but I will get back more about that later.

October 3, 2010

Day 1 at JAOO Object-Orienteed meets functional: An Overview of Scala

The first Training at JAOO 2010 was held by Martin Odersky in Scala. Scala is truly an interesting new programming language, it runs on top of the JVM, but brings so much new programming technique that is not possible with the existing Java language.

It was a truly refreshing talk, but also a sadly realization that the evolution of the Java language has really slowed down since the release of Java 5. The difference between Java 6 and Java 5 is mostly a faster JVM, that is not bad, but on the functional side of new language technique is quite depressing to see such a short list of new feature. And it is not getting better. A couple of days ago a checked out the Oracle web page of new programmatic feature in Java 7 one can see the list is short.
http://www.oracle.com/technetwork/java/7-138633.html

And what is happening the other main stream programming corner at Microsoft? Well they have not been lazy. On could right fairly argue that C# has been become a more advance language than Java. So with this in mind, I'm really looking forward to participate the Training. So what did Martin talk about. Well, the Scala language is really huge, so the talk for 4 hours, did not covered all parts, but one thing is sure. Looking at Scala is almost like learning a new language. For you out there, that have not started looking at Scala I only got one question for you:

Do you want to program Java 6 or 10? See the complete video of Martin Odersky. http://www.scala-lang.org/node/1305

"If I were to pick a language to use today other than Java, it would be Scala"
by James Gosling, creator of Java
http://www.adam-bien.com/roller/abien/entry/java_net_javaone_which_programming

"I can honestly say if someone had shown me the Programming in Scala book by by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I’d probably have never created Groovy."
by James Strachan, creator of Groovy
http://macstrac.blogspot.com/2009/04/scala-as-long-term-replacement-for.html

"Scala, it must be stated, is the current heir apparent to the Java throne. No other language on the JVM seems as capable of being a "replacement for Java" as Scala, and the momentum behind Scala is now unquestionable. While Scala is not a dynamic language, it has many of the characteristics of popular dynamic languages, through its rich and flexible type system, its sparse and clean syntax, and its marriage of functional and object paradigms."
Charles Nutter, creator of JRuby
http://blog.headius.com/2009/04/future-part-one.html

August 5, 2010

Opening New Window in Ubuntu 10.04 Does Not Get Focused

I had a really annoying problem after installing Ubuntu 10.04 which I found a solution to today. The problem was whenever I was opening a new window that new opened window was not focused. Quite annoying! The solution is following:
  1. System → Preferences → CompizConfig Settings Manager
  2. Select General in the right hand window.
  3. Select General Options.
  4. Select the Focus & Raise Behaviour tab.
  5. Change Focus Prevention Level to Off.

July 5, 2010

Your First Cup of Coffee

A friend of mine asked me to provide a simple getting started guide for a first time Java programmer and it so happened it were other people that also wanted the same thing, so all of you out there here it comes, a simple learning by example guide in Java.

The example is a simple Web application that do simple Create, Retrieve, Update and Delete (CRUD) operation against a MySQL database.

Before starting writing you need to install the following on your system.
Installing programs on Windows is a pain and I will leave that as an exercise and instead show you how that this is done on a Linux platform, Ubuntu (ubuntu.com).
$ sudo apt-get install sun-java6-jdk mysql-server mysql-query-browser maven2 


That's it! That took 3 minutes on a modest Internet connection. Are you still stuck on downloading the files on your Windows machine? And thereafter looking forward to reboot you system after each installation?

The Eclipse Ubuntu installation bundle is sadly quite old and therefore it is better to download the zip file manually and extracted it anywhere of you liking and run eclipse.exe (eclipse) in the eclipse folder.

Now lets create your database. Start the MySQL Query Browser and right click in the Schemata dockable window and then select Create Schema.... Enter simpledb.
Now double click on the newly created schema and then right click again to create a new table.



From here you can take several paths, either create a new project with maven archetype 'simple-webapp' (http://www.sonatype.com/books/mvnex-book/reference/web-sect-creating-project.html) or you can install the m2eclipse plugin (http://m2eclipse.sonatype.org/installing-m2eclipse.html) and create your project from Eclipse. Here, I will hopefully, choose the easiest way and do it manually, since we only will be needing two source files, where one will be empty – web.xml and index.jsp.
$ cd [your local workspace directory] 
$ mkdir -p first-coffee/src/main/webapp/WEB-INF


Now create you Maven Project Object Model file pom.xml in first-coffee/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelversion>4.0.0</modelVersion>
 <groupid>se.msc.example</groupId>
 <artifactid>first-coffee</artifactId>
 <packaging>war</packaging>
 <version>0.0.1-SNAPSHOT</version>
 <name>first-coffee Maven Webapp</name>
 <url>http://www.msc.se/example</url>
 <dependencies>
  <!-- mysql jdbc driver -->
  <dependency>
   <groupid>mysql</groupId>
   <artifactid>mysql-connector-java</artifactId>
   <version>5.1.13</version>
  </dependency> 
  <!-- test support -->
  <dependency>
   <groupid>junit</groupId>
   <artifactid>junit</artifactId>
   <version>4.8.1</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
 <build>
  <finalname>first-coffee</finalName>
  <pluginmanagement>
   <plugins>
    <!-- to compile with JDK 1.6 -->
    <plugin>
     <groupid>org.apache.maven.plugins</groupId>
     <artifactid>maven-compiler-plugin</artifactId>
     <configuration>
      <source>1.6</source>
      <target>1.6</target>
     </configuration>
    </plugin>
   </plugins>
  </pluginManagement>
  <plugins>
   <!-- built-in web server 'mvn jetty:run' -->
   <plugin>
    <groupid>org.mortbay.jetty</groupId>
    <artifactid>maven-jetty-plugin</artifactId>
    <configuration>
     <scanintervalseconds>1</scanIntervalSeconds>
     <stopkey>foo</stopKey>
     <stopport>9999</stopPort>
    </configuration>
   </plugin>
  </plugins>
 </build>
</project>


Now create your first-coffee/src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 version="2.5">
</web-app>


And finally your dynamic web page (first-coffee/src/main/webapp/index.jsp), where all your work be done.
<%@ page import="java.sql.*" %>
<html>
<body>
<%
 // Step 1: Load the JDBC driver. 
 Class.forName("com.mysql.jdbc.Driver");
 // Step 2: Establish the connection to the database. 
 String url = "jdbc:mysql://localhost:3306/simpledb";
 Connection conn = DriverManager.getConnection(url, "root", "root");
 // Step 3: Do possible posted logic - Create, Update or Delete
 if ("Create".equals(request.getParameter("submitCreate"))) {
  String name = request.getParameter("Name");
  Statement statement = conn.createStatement();
  statement.executeUpdate("INSERT INTO Person (Name) VALUES ('" + name + "')");
 } else if ("Update".equals(request.getParameter("submitUpdate"))) {
  String personId = request.getParameter("PersonId");
  String name = request.getParameter("Name");
  Statement statement = conn.createStatement();
  statement.executeUpdate("UPDATE Person SET Name='" + name + "' WHERE PersonId=" + personId);  
 } else if ("Delete".equals(request.getParameter("submitDelete"))) {
  String personId = request.getParameter("PersonId");
  Statement statement = conn.createStatement();
  statement.executeUpdate("DELETE FROM Person WHERE PersonId=" + personId);  
 }
%>
<table border="1">
<tr>
<th>PersonId</th>
<th>Name</th>
<th>Action</th>
</tr>
<%
 // Step 4: Load all content from table
 Statement stmt = conn.createStatement();
 ResultSet rs = stmt.executeQuery("SELECT PersonId, Name FROM Person");
 while (rs.next()) {
%>
<!-- Here we display the content of the DB table. -->
<form action="index.jsp" method="get">
<input type="hidden" name="PersonId" value='<%=rs.getString("PersonId")%>' />
<tr>
<td><%=rs.getString("PersonId")%></td>
<td><input type="text" name="Name" value="<%=rs.getString("Name")%>" /></td>
<td>
<!-- Provide simple Update and Delete Action for each DB table row. -->
<input type="submit" name="submitUpdate" value="Update" />
<input type="submit" name="submitDelete" value="Delete" />
</td>
</tr>
</form><%
 }
%>
<!-- Provide an empty row for creating new DB table row.  -->
<form action="index.jsp" method="get">

<tr>
<td> </td>
<td><input type="text" name="Name" /></td>
<td><input type="submit" name="submitCreate" value="Create" /></td>
</tr>
</form></table></body>
</html>


To test your application, simply start the Maven built in web server, from your first-coffee directory.

$ mvn jetty:run


Now open your web browser and enter the address http://localhost:8080/first-coffee/.

If you want to continue to further evolve this simple example, you can leave the jetty server running and simply refresh you web server, after saving your changes.

July 1, 2010

Getting Started with Apache Camel and Prepare for Apache ServiceMix Deployment

Apache Camel is dream framework for any developers that is confronting with any type of integration task. What makes Apache Camel so great is:
  • Testability. It is design from the beginning to be a framework that going to support Test Driven Development. With this follows a fast development cycle, since all code can be debugged and executed from a simple JUnit test case.
  • Solves the two foremost problem that an integrator faces:
  • Seamless protocol crossing, i.e. no coding for fetching data from e.g. HTTP and forwarding it to JMS.
  • Default implementation of Enterprise Integration Pattern (http://www.eaipatterns.com/toc.html) that is easy to extend and configure. If you are not familiar with EIP, I recommend you to take the time and read the EIP homepage or if you do not want to miss a thing read the complete book written by Hophe and Woolf (http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683).

The next best thing is that Apache Camel is a POJO based solution, which means that it can be deployed and ran in any deployment environment:
  • Standalone Java Application
  • Web Container
  • J2EE Container

When talking of deployment and integration the most common question is. What about ESB? And this is also when Apache Camel shines. Apache Camel is fully supported by Apache Camel parent project Apache ServiceMix, that supports the industry standard Java Business Integration standard. The JBI specification has been criticized about being a slow way of developing integration software and in many aspect that is true, but with Apache Camel as core developing framework that is no longer true.

The reason to select an ESB platform to deploy your integration software is:
  • Management. The ESB platform is specially design to manage integration programs.
  • Redundancy and Scalability. A good ESB platform is specifically design to handle these issues when the load and uptime requirements increases.

But one thing, that in my opinion, the Apache Camel homepage lack is good starting example of showing the above strength. So lets get started with NOT writing a production code example, but instead lets write a JUnit test case that you can debug, then you can continue of writing your production code.

In the below example I will also take into account that one day, you might want or NOT take the next step and move your Apache Camel code into a full blown ESB environment.

Lets first look at your Maven pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>se.msc.example</groupId>
 <artifactId>camel</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>
 <!-- <packaging>jbi-service-unit</packaging> -->
 <name>MSC Example :: Camel</name>
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <servicemix-version>4.2.0</servicemix-version>
  <!--
   servicemix 4.2.0 ships with 'servicemix-camel', thats support camel
   2.2.0
  -->
  <camel-version>2.2.0</camel-version>
  <!--
   'servicemix-camel' has a deviating version compared with 'camel-core'
  -->
  <servicemix-camel-version>2010.01</servicemix-camel-version>
  <!-- supported version for tooling in servicemix 4.2.0 -->
  <servicemix-jbi-plugin-version>4.3</servicemix-jbi-plugin-version>
 </properties>
 <build>
  <pluginManagement>
   <plugins>
    <!-- to compile with JDK 1.6 -->
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-compiler-plugin</artifactId>
     <!--
      Use version
      $M2_HOME/lib/maven-<version>-uber.jar/org/apache/maven/project/pom-4.0.0.xml
     -->
     <configuration>
      <source>1.6</source>
      <target>1.6</target>
      <!-- Plugin ignores default value 'project.build.sourceEncoding' -->
      <encoding>${project.build.sourceEncoding}</encoding>
     </configuration>
    </plugin>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-jar-plugin</artifactId>
     <!--
      Use version
      $M2_HOME/lib/maven-<version>-uber.jar/org/apache/maven/project/pom-4.0.0.xml
     -->
     <configuration>
      <archive>
       <manifest>
        <!-- To include versionnumber in MANIFEST.MF -->
        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
       </manifest>
      </archive>
     </configuration>
    </plugin>
   </plugins>
  </pluginManagement>
  <plugins>
   <!--
    creates the JBI deployment unit <plugin>
    <groupId>org.apache.servicemix.tooling</groupId>
    <artifactId>jbi-maven-plugin</artifactId>
    <version>${servicemix-jbi-plugin-version}</version>
    <extensions>true</extensions> </plugin>
   -->
  </plugins>
 </build>
 <dependencies>
  <!-- servicemix camel core -->
  <dependency>
   <groupId>org.apache.servicemix</groupId>
   <artifactId>servicemix-camel</artifactId>
   <version>${servicemix-camel-version}</version>
   <scope>provided</scope>
  </dependency>
  <!-- optional camel components -->
  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-http</artifactId>
   <version>${camel-version}</version>
  </dependency>
  <!-- test support -->
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <!-- version inherited from 'camel-core' -->
   <version>3.8.2</version>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-core</artifactId>
   <version>${camel-version}</version>
   <type>test-jar</type>
   <scope>test</scope>
  </dependency>
 </dependencies>
</project>


package se.msc.example.camel;

import org.apache.camel.ContextTestSupport;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;

public class MyFirstCamelTest extends ContextTestSupport {

 @Override
 protected RouteBuilder createRouteBuilder() {
  return new RouteBuilder() {
   public void configure() {
    from("direct:start").to("file:///tmp?fileName=foo.txt").to("mock:result");
    // another example, without mocking start endpoint
    // from("http://camel.apache.org/http.html").to("file:///tmp?fileName=foo.txt").to("mock:result");
   }
  };
 }

 public void test_OK() throws Exception {
  MockEndpoint result = resolveMandatoryEndpoint("mock:result", MockEndpoint.class);
  result.expectedMessageCount(1);
  // send somtething from 'direct:start'
  String ls = System.getProperty("line.separator");
  String txt = "Dummy Body åäö";
  template.sendBody("direct:start", txt + ls + txt + ls + txt + ls);
  // execute and assert above 'result.expectedMessageCount(1);'
  result.assertIsSatisfied();
 }

}


To read more about all configuration options for the above endpoints, see http://camel.apache.org/components.html

An Apache Camel route can also be configured in a XML file, which is the natural choice since you want  things to configurable and not static defined in a Java class, but more about in my next blog.

June 28, 2010

Problem Running Eclipse on Ubuntu 10.04 (Lucid Lynx)

I have been using Ubuntu for some time and it is really a great OS, but it is amazing why it is always Eclipse that brings the most headache when upgrading Ubuntu. For a couple a days ago I upgraded to Ubuntu 10.04, and everything works smoothly until I started Eclipse 3.5 SR1, with bug fixes I have previously described.

http://magnus-k-karlsson.blogspot.com/2009/11/problem-running-eclipse-in-ubuntu-910.html

This time the solution was to upgrade to Eclipse 3.5 SR 2 (Galileo), without the above bug fix. But thereafter m2eclipse gave me some problem, but now it seams to work after reinstalling m2eclipse and following the guideline in

http://m2eclipse.sonatype.org/installing-m2eclipse.html

“Note about 0.9.8 Workspace Incompatibility: If you are using m2eclipse 0.10.0 with a workspace that contains projects created under m2eclipse 0.9.8, you must remove the workspaceState.ser file. The workspaceState.ser file is located within the workspace directory in $workspacedir/.metadata/.plugins/org.maven.ide.eclipse/workspaceState.ser. If you remove this file, m2eclipse 0.10.0 will regenerate it as needed.”

June 25, 2010

Getting Starting with Google Web Toolkit, GWT, Development

To get started first install appropriate plug-in for your IDE, in this article we will use Eclipse, but there are other great plug-in for other IDE as well.

Eclipse GWT plugin
http://code.google.com/eclipse/docs/download.html

One of the biggest difference between GWT 1.* and 2.* is the ability to debug and run your GWT application without the need to render/compile it. Now you can directly run/debug your GWT Java code without the time consuming compile step. But to do this you first need to install a plug-in to your web browser.

GWT Development Mode plugin for Firefox, IE and Safari
http://groups.google.com/group/google-web-toolkit/msg/51c5a09630ac61dc

After restarting Eclipse and your Web browser you are now ready to start developing. Begin with creating a new project and select Google → Web Application Project.


Enter project details. In this article we will not create a Google App Engine Application, which is a platform for writing cloud application for the Google cloud platform. To read more about Google App Engine, visit http://code.google.com/appengine/.


After finishing creating your project. Lets fire it up and start debug the complete GWT project. The GWT team has already configured a default debug goal. So simple press the debug icon in the Eclipse toolbar.


Now is a URL presented in the Eclipse Console output View. Right click on that URL and select Copy. Paste the URL in your web browser.


Now lets set a breakpoint in your application and the enter a name in your browser and click submit. And now you are debugging your first GWT application.

April 18, 2010

Administrating JBoss MBean From the Command Line Using twiddle

In production environment you usually monitor and administrate the JBoss Application Server through ssh and command line and this is adequate when starting, stopping and reading logs, but when you want to inspect, see status and change MBean values, the command line alternative is quite limited and since the MBean architecture is central in JBoss one really wants to use the JMX-console. The JMX-console is not the most user friendly tool, but has improved with JBoss 5 and the Web Console.

But there is an alternative if you want (or must) stick with the command line alternative – twiddle. The twiddle tool is not new and has been around since JBoss 4.3. And here follows a short walk through by examples.

To print out help information use:

$ ./twiddle.sh -h


Here you see the most imported commands: info, get, invoke and setattrs.

To get attribute and operation info:

$ ./twiddle.sh info jboss:service=JNDIView


To get attribute value:

$ ./twiddle.sh get jboss:service=JNDIView StateString


To invoke an operation:

$ ./twiddle.sh invoke jboss:service=JNDIView list true

March 24, 2010

How To Remove Automatically Started Programs in Ubuntu 9.10 Karmic Koala

I while ago I blogged about how to setup Apache mod_proxy as a reverse proxy and I installed Tomcat and Apache Web Server with Synaptic Package Manager. The Synaptic Package Manager worked flawless  as usual, but it left me with one problem. The Tomcat Server did start automatically every time I booted Ubuntu, this is typically not wanted on a developer laptop, since you probably also are using some other Java Container that is default using port 8080.

Before we dive into how to remove the auto start in Ubuntu, lets first see how things are configured to be automatically started. As you know the start scripts are located in the

$ /etc/init.d


And to make programs autostart then there are soft links in the

$ /etc/rcX.d


There are several /etc/rc catalogs, and here follows the extract from one of mine catalog.

$ ls -al /etc/rc0.d/
lrwxrwxrwx   1 root root    17 2010-02-19 07:34 K09apache2 -> ../init.d/apache2


So one obvious option would be to directly delete all the soft links in these catalogs, but this is error prone and not recommended, but also it exists a tool to do exactly this – update-rc.d.

$ sudo update-rc.d -f tomcat6 remove 
 Removing any system startup links for /etc/init.d/tomcat6 ... 
   /etc/rc0.d/K08tomcat6 
   /etc/rc1.d/K08tomcat6 
   /etc/rc2.d/S92tomcat6 
   /etc/rc3.d/S92tomcat6 
   /etc/rc4.d/S92tomcat6 
   /etc/rc5.d/S92tomcat6 
   /etc/rc6.d/K08tomcat6


Now is Tomcat no longer automatically started when booting Ubuntu.

February 28, 2010

Using JAX-WS in a Web Archive, as a Servlet, Running on JBoss 5.1

In my previous blog I showed how to get started with JAX-WS in a EJB archieve, in this blog I will show you how to do the same thing, but in a web archive instead, as a Servlet. If you think about it, the two different approaches ends with the same result – a Servlet that answer HTTP request with SOAP content.

Now lets create a simple web archieve with Maven archetype plugin.

$ mvn archetype:create -DgroupId=se.msc.example -DartifactId=ws-web -DarchetypeArtifactId=maven-archetype-webapp


Now lets add EJB dependency and JBoss Maven plugin that will do our deployment work.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelversion>4.0.0</modelVersion>
 <groupid>se.msc.example</groupId>
 <artifactid>ws-web</artifactId>
 <packaging>war</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>ws-web Maven Webapp</name>
 <url>http://www.msc.se/example/ws-web</url>
 <developers>
  <developer>
   <id>magnus.k.karlsson</id>
   <name>Magnus K Karlsson</name>
   <email>magnus.k.karlsson@msc.se</email>
   <organization>MSC</organization>
  </developer>
 </developers>
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <jboss.home>/home/magnus/applications/jboss-5.1.0.GA-jdk6</jboss.home>
 </properties>
 <dependencies>
  <!-- sun's ejb 3.0 api -->
  <dependency>
   <groupid>javax.ejb</groupId>
   <artifactid>ejb-api</artifactId>
   <version>3.0</version>
   <scope>provided</scope>
  </dependency>
  <!-- jboss logging impl (jboss 5.1.0 GA) -->
  <dependency>
   <groupid>log4j</groupId>
   <artifactid>log4j</artifactId>
   <version>1.2.14</version>
   <scope>provided</scope>
  </dependency>
  <!-- unit testing -->
  <dependency>
   <groupid>junit</groupId>
   <artifactid>junit</artifactId>
   <version>4.7</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
 <build>
  <finalname>ws-web</finalName>
  <plugins>
   <!-- to compile with jdk 1.6 -->
   <plugin>
    <groupid>org.apache.maven.plugins</groupId>
    <artifactid>maven-compiler-plugin</artifactId>
    <version>2.1</version>
    <configuration>
     <source>1.6</source>
     <target>1.6</target>
     <debug>true</debug>
     <debuglevel>lines,vars,source</debuglevel>
     <optimize>true</optimize>
     <showdeprecation>true</showDeprecation>
     <showwarnings>true</showWarnings>
    </configuration>
   </plugin>
            <!-- plugin to harddeploy, hardundeploy, start and stop jboss -->
            <plugin>
                <groupid>org.codehaus.mojo</groupId>
                <artifactid>jboss-maven-plugin</artifactId>
                <version>1.4</version>
                <configuration>
                    <jbosshome>${jboss.home}</jbossHome>
                    <servername>default</serverName>
                    <port>8080</port>
                </configuration>
            </plugin>   
  </plugins>
 </build>
</project>


Then we continue with our Web Service class.

package se.msc.example.ws.web;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public class PersonServiceBean {

 @WebMethod
    public String getName() {
     return "Magnus K Karlsson";
    }
}


Not that we don't need to define a interface. Then we write our web.xml, that points to our concrete Web Service class.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 version="2.5">

 <display-name>MSC Demo Web Service</display-name>
 <servlet>
    <servlet-name>PersonServiceBean</servlet-name>
    <servlet-class>se.msc.example.ws.web.PersonServiceBean</servlet-class>
 </servlet>
 <servlet-mapping>
    <servlet-name>PersonServiceBean</servlet-name>
    <url-pattern>/personServiceBean</url-pattern>
 </servlet-mapping>
</web-app>


Finally we need to add the JBoss specific web deployment descriptor. Note the location of the file – src/main/webapp/META-INF/jboss-web.xml, i.e. not in the WEB-INF directory, beside the web.xml.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd"
 version="5.1">
 
 <!-- Read about Schema documentation in $JBOSS_HOME/docs/schema/jboss-web_5_1.xsd -->
</jboss-web>    


Now we are ready to build and deploy our archieve

$ mvn clean install jboss:harddeploy


Then we start our JBoss server and opens a web browser pointing to http://localhost:8080/ws-web/personServiceBean?wsdl and checks that the web service is working. Instead of building a web service client by hand, we use the soapUI tool.

 

 

Now soapUI has created us a testcase that we can double click and click the green play button on.

February 25, 2010

How To See Expiration Date and other Information of a p12 File (PKCS12).

Sooner or later your client or server certificate will expire and it will be nice to update that before it really happens, but to do that you need to know how to get that information. In this blog I will show you how to do that in a Linux environment with openssl, that is a typical scenario when the certificate is located on a remote Linux server that you access with ssh.

First thing to do is to convert the p12 file (PKCS12 format) to X509 format, to do so we use the openssl command.

$ openssl pkcs12 -in maka.p12 -info


When prompted enter the password. Now is the content printed out, find out which CN (Common Name) that is for the server, typically it is the dns name of the server. After located the certificate then copy everything between the below start and end tag,

-----BEGIN CERTIFICATE-----
The content to copy...
-----END CERTIFICATE-----


Past the copied content into a file with prefix .crt. If you were on a Windows system you could now simple double click the crt-file and the information of the certification would be display, but here we will continue using openssl. To use openssl, use the below command using the file name of the file you pasted the certificate into.

$ openssl x509 -in <your_file.crt> -inform PEM -text


Now is the expiration date printed among other information.

February 21, 2010

Configure Apache Web Server as Reverse Proxy in front of a Tomcat or J2EE Container

One production like scenario when using SSL or load balancing is to use a Apache Web Server in front of a Java Web Container or J2EE Container. There are two ways to make the Apache Web Server and the behind Java container – mod_proxy or mod_jk. In this blog I will show you how to use the mod_proxy alternative, acting as a reverse proxy. I will also use Ubuntu to show you how easy there is to install software on Ubuntu with Synaptic Package Manager.

The first thing to do is to install Apache Web Server and the Tomcat Container.

$ sudo apt-get install apache2 tomcat6


After installing the above software you can use the apache2ctl command to view the active sites configuration

$ sudo apache2ctl -S


or you can also list the files in /etc/apache2/sites-enabled

$ ls -al 
lrwxrwxrwx 1 root root   26 2010-02-19 07:34 000-default -> ../sites-available/default 


Before continue you can also check that everything is working by open a web browser and open http://localhost/ (Apache Web Server) and http://localhost:8080/ (Tomcat)

Now we go ahead and creating a new virtual host that is going to act as reverse proxy.

$cd /etc/apache2/sites-available 
$ sudo gedit customerapp


<virtualhost *:80="">
    ServerName customerapp.msc.se
    ServerAlias *.customer.msc.se
    ProxyRequests Off
    <proxy *="">
        Order deny,allow
        Allow from all
    </proxy>
    ProxyPass / http://localhost:8080/examples/
    ProxyPassReverse / http://localhost:8080/examples/
</virtualhost>


After creating the new site we need to link it from sites-enabled, either use ln -s or you can use the apache tool – a2ensite.

$ sudo a2ensite customerapp


With the configuration in place, you need to separate the virtual host in customapp and default. For a locale environment you can separate them by using different IP – 127.0.0.1 and your computer IP.

<virtualhost 192.168.1.4:80="">
<virtualhost 127.0.0.1:80="">


The last thing before restarting the Apache Web Server is to install proxy and proxy_http modules you can do that with the Apache tool a2enmod

$ sudo a2enmod proxy
$ sudo a2enmod proxy_http


And finally you need to restart the Apache Web Server.

$ sudo /etc/init.d/apache2 restart

February 18, 2010

Getting Started with JBoss Web Serivce using JAX-WS on JBoss 5.1 using Maven, OpenEJB and eviware soapUI

The easiest way to get started with writing Web Service is using Java API for XML Web Service, JAX-WS. The downside with this is that the creation of the WSDL file is automatic, and that is not the preferred way of writing cross platform independent web service. If that is your design goal, you should handwrite the WSDL, i.e. contract first. But if you know that the only clients are going to be Java client, than automatically generating the WSDL could be fine.

A good practice when writing all kind of code, is to make the code testable and also make it testable outside the container. To achieve that I will use OpenEJB, if have never heard or used OpenEJB and you are writing EJB 3.0 applications, it is definitely worth the time to check it out.

Lets start with writing a standard Stateless EJB.

package se.msc.example.jbossws;

import javax.ejb.Remote;
import javax.jws.WebService;

@Remote
public interface HelloService {

 public String sayHello();
}


package se.msc.example.jbossws;

import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@Stateless
public class HelloServiceBean implements HelloService {

 @Override
 public String sayHello() {
  return "Hello World.";
 }
}


src/main/resources/META-INF/ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
 version="3.0">

</ejb-jar>


src/main/resources/META-INF/jboss.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 
<jboss xmlns="http://www.jboss.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss_5_1.xsd"
       version="3.0"> 
-->
<jboss>       
 
</jboss>


pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelversion>4.0.0</modelVersion>
 <groupid>se.msc.example</groupId>
 <artifactid>jbossws</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>ejb</packaging>
 <name>JBoss WS Test</name>
 <url>http://www.msc.se/example/jbossws</url>
 <developers>
  <developer>
   <id>magnus.k.karlsson</id>
   <name>Magnus K Karlsson</name>
   <email>magnus.k.karlsson@msc.se</email>
   <organization>MSC</organization>
  </developer>
 </developers>
 <repositories>
  <repository>
   <id>repository.jboss.org</id>
   <name>Jboss Repository for Maven</name>
   <url>http://repository.jboss.org/maven2/</url>
  </repository>
 </repositories>
 <pluginrepositories>
  <pluginrepository>
   <id>repository.jboss.org</id>
   <name>Jboss Repository for Maven</name>
   <url>http://repository.jboss.org/maven2/</url>
  </pluginRepository>
 </pluginRepositories>
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <jboss.home>/home/magnus/applications/jboss-5.1.0.GA-jdk6</jboss.home>
 </properties>
 <dependencies>
  <!-- sun's ejb 3.0 api -->
  <dependency>
   <groupid>javax.ejb</groupId>
   <artifactid>ejb-api</artifactId>
   <version>3.0</version>
   <scope>provided</scope>
  </dependency>
  <!-- jboss logging impl (jboss 5.1.0 GA) -->
  <dependency>
   <groupid>log4j</groupId>
   <artifactid>log4j</artifactId>
   <version>1.2.14</version>
   <scope>provided</scope>
  </dependency>
  <!-- unit testing -->
  <dependency>
   <groupid>junit</groupId>
   <artifactid>junit</artifactId>
   <version>4.7</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
 <build>
  <finalname>jbossws-example</finalName>
  <plugins>
   <!-- to compile with jdk 1.6 -->
   <plugin>
    <groupid>org.apache.maven.plugins</groupId>
    <artifactid>maven-compiler-plugin</artifactId>
    <version>2.1</version>
    <configuration>
     <source>1.6</source>
     <target>1.6</target>
    </configuration>
   </plugin>
   <!-- ejb 3.0 plugin -->
   <plugin>
    <groupid>org.apache.maven.plugins</groupId>
    <artifactid>maven-ejb-plugin</artifactId>
    <version>2.2</version>
    <configuration>
     <ejbversion>3.0</ejbVersion>
    </configuration>
   </plugin>
   <!-- plugin to harddeploy, hardundeploy, start and stop jboss -->
   <plugin>
    <groupid>org.codehaus.mojo</groupId>
    <artifactid>jboss-maven-plugin</artifactId>
    <version>1.4</version>
    <configuration>
     <jbosshome>${jboss.home}</jbossHome>
     <servername>default</serverName>
     <port>8080</port>
    </configuration>
   </plugin>
  </plugins>
 </build>
</project>


Now lets test our EJB with OpenEJB. The first thing we need to do, is to add the OpenEJB dependency to our pom.xml

  <dependency>
   <groupid>org.apache.openejb</groupId>
   <artifactid>openejb-core</artifactId>
   <version>3.1.2</version>
   <scope>test</scope>
  </dependency>


Then we write our JUnit test case.

package se.msc.example.jbossws;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.Properties;

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

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class HelloServiceStatelessTest {
 private InitialContext ctx;

 @BeforeClass
 public static void oneTimeSetUp() throws Exception {
 }

 @AfterClass
 public static void oneTimeTearDown() throws Exception {
 }

 @Before
 public void setUp() throws Exception {
  Properties prop = new Properties();
  prop.setProperty(Context.INITIAL_CONTEXT_FACTORY,
    "org.apache.openejb.client.LocalInitialContextFactory");
  ctx = new InitialContext(prop);
 }

 @After
 public void tearDown() throws Exception {
 }

 @Test
 public void testSayHello() throws Exception {
  Object obj = ctx.lookup("HelloServiceBeanRemote");
  assertNotNull(obj);
  assertTrue(obj instanceof HelloService);
  HelloService remote = (HelloService) obj;
  assertEquals("Hello World.", remote.sayHello());
 }
}


After verifying that our Stateless Session Bean is working, we now continue to deploy it to the JBoss container.

$ mvn clean install jboss:harddeploy


We start our JBoss container and checks that the EJB is successfully deployed.

Now lets add Web Service support to our EJB.

package se.msc.example.jbossws;

import javax.ejb.Remote;
import javax.jws.WebService;

@Remote
@WebService(targetNamespace = "http://www.msc.se/examples/jbossws/wsdl")
public interface HelloService {

 public String sayHello();
}


package se.msc.example.jbossws;

import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@Stateless
@WebService(serviceName = "HelloService", 
  targetNamespace = "http://www.msc.se/examples/jbossws/wsdl", 
  endpointInterface = "se.msc.example.jbossws.HelloService")
@SOAPBinding(style = Style.DOCUMENT)
public class HelloServiceBean implements HelloService {

 @Override
 public String sayHello() {
  return "Hello World.";
 }
}


Now lets write our JUnit test case, to test our web service outside the JBoss container.

package se.msc.example.jbossws;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.net.URL;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class HelloServiceWebServiceTest {
 private InitialContext ctx;

 @BeforeClass
 public static void oneTimeSetUp() throws Exception {
 }

 @AfterClass
 public static void oneTimeTearDown() throws Exception {
 }

 @Before
 public void setUp() throws Exception {
  Properties prop = new Properties();
  prop.setProperty(Context.INITIAL_CONTEXT_FACTORY,
    "org.apache.openejb.client.LocalInitialContextFactory");
  prop.setProperty("openejb.embedded.remotable", "true");
  ctx = new InitialContext(prop);
 }

 @After
 public void tearDown() throws Exception {
 }

 @Test
 public void testWebService() throws Exception {
  Service service = Service.create(
    new URL("http://127.0.0.1:4204/HelloServiceBean?wsdl"), 
    new QName("http://www.msc.se/examples/jbossws/wsdl", "HelloService"));
  assertNotNull(service);
  HelloService hello = service.getPort(HelloService.class);
  assertEquals("Hello World.", hello.sayHello());
 }
}


Before running the testcase we need to update our pom.xml with a concrete web service implementation.

  <dependency>
   <groupid>org.apache.openejb</groupId>
   <artifactid>openejb-cxf</artifactId>
   <version>3.1.2</version>
   <scope>test</scope>
  </dependency>


After running the testcase from withing Eclipse, we can now be confident that we our is executing as expected. Now lets deploy our EJB to the JBoss container.

$ mvn clean install jboss:harddeploy


If you have stopped the JBoss, then restarted and verify that everything is looking healthy in the server log. Verify that the web service is working by firing up a web browser and go to http://localhost:8080/jbossws-example/HelloServiceBean?wsdl, to verify that you see the wsdl file.

Instead of writing a web service client, we are going to use a good test tool for testing web service – eviware soapUI. Start the soapUI and then select new project.

 

  

 

February 17, 2010

Viewing/Monitoring your Log4j Generated Log File with Chainsaw

Chainsaw is a open source tool for viewing and/or monitoring Log4j generating system. But the documentation on the homepage lack some explanation how to get started. To begin with maybe the simplest scenario, to view a log4j generated log file. The first thing one might misunderstand is that you need to defines a new configuration file for Chainsaw, so just pointing to your log4j.xm configuration file is not enough. Lets start with a example.

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

 <appender name="FILE_APPENDER" class="org.apache.log4j.RollingFileAppender">
  <param name="File" value="/tmp/server.log" />


  <param name="Append" value="true" />


  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n" />


  </layout>
 </appender>

 <logger name="se.msc.example.log4j.ChainsawTest">
  <level value="DEBUG" />
 </logger>

 <root>
  <level value="ERROR" />
  <appender-ref ref="FILE_APPENDER" />
 </root>

</log4j:configuration>


And the configuration file for Chainsaw.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd"> 
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">

   <plugin name="logFileReceiver" class="org.apache.log4j.varia.LogFilePatternReceiver">
     <param name="fileURL" value="file:///tmp/server.log" />
     <param name="timestampFormat" value="yyyy-MM-d HH:mm:ss,SSS"/>
     <param name="logFormat" value="TIMESTAMP LEVEL [THREAD] CLASS (FILE:LINE) - MESSAGE"/>
     <param name="name" value="Reciever-name-in-Chainsaw" />
     <param name="tailing" value="true" />
   </plugin>
   <root>
      <level value="debug"/>
   </root>
</log4j:configuration>


Before we open Chainsaw lets write a small test program, that generates some log post, so we have something to view.

package se.msc.example.log4j;

import org.apache.log4j.Logger;
import org.junit.Test;

public class ChainsawTest {
 private static final Logger log = Logger.getLogger(ChainsawTest.class);
 
 @Test
 public void test() throws Exception {
  log.debug("DEBUG text");
  log.info("INFO text");
  log.warn("WARN text");
  log.error("ERROR text");
 }
}


Now lets open Chainsaw. When first starting Chainsaw you are prompted to define a Receiver. Here we select our configuration file.



After selecting our Chainsaw configuration file, Chainsaw opens our log file in a new tab.



You might have already noticed the different formatting of logFormat attribute, compared with the Log4j and it is a question to me why they have done that. You can read more about the format in the LogFilePatternReceiver Javadoc.

February 14, 2010

Sending Log Errors with Log4j and SMTPAppender

Log4j comes with several Appenders and if you like to send mail notification if severe errors occur the you will be pleased to see, that Log4j comes with a SMTPAppender, but there are some pitfalls when using the SMTP appender:
  • The SMTP apppender does not out of the box support a different SMTP port.
  • Using secure connection, such as SSL or TLS.
  • The derived standardized method setThreshold is ignored, and replaced with TriggeringEventEvaluator class.
Configure SMTP appender to use a different port, than the default 25
If your mailserver is configured to answer on a different port than the default 25 for SMTP, you need to configure the underlying javax.mail.Session property "mail.smtp.port". But when looking at the API for SMTPAppender you see no set method for that. What to do? Writing you own extended log4j class? No, that is not neccessary. If you look at the source code of SMTPAppender, you see the following in the createSession():

Properties props = new Properties (System.getProperties());


These means that SMTPAppender is reading system properties, which means you can add the following argument when starting you application.

$ -Dmail.smtp.port=587


This is a not gracefefully way, and sometimes also not applicable, because you are not in charge of the deployment environment. And what happens when you have two different application hosted on the same server, that wants to use different ports?
There is also the oppurtunity to do it programmatically:

System.setProperty("mail.smtp.port", "587");


This has also drawbacks. For examaple if your application is a J2EE application or a web application your code is not the main start class. You can of course always write a boot strap class, but what happens when you have several bootstrap classes, then things starts to get more hard to overlook for a more junior programmer.

Another way if you have problems settings the System Property is to create a class that implements the interface org.apache.log4j.spi.TriggeringEventEvaluator and there set the system properties and then in your log4j properties or xml file override the default EvaluatorClass for SMTPAppender. This is a little hacky, but it will get the work done and it keeps your code clean from log4j configuration code that should in the first place be placed in the log4j configration file.

Also what is lacking is, if you are deploying to a container you might want to define your java.mail.Session properties in the container and then bind them to JNDI, then it should be nice if Log4j could read these property from JNDI, but that is not possible.

Using Secure Connection
The next problem comes when your mailserver uses secure connection as TLS or SSL, then you need to add the following javax.mail.Session properties:

System.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
System.setProperty("mail.smtp.socketFactory.port", "465");
System.setProperty("mail.smtp.socketFactory.fallback", "false");


Bellow follows the source code for the example.
# configure the root logger
log4j.rootLogger=INFO, STDOUT

# configure the console appender
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.Target=System.out
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] %c:%L - %m%n

log4j.logger.se.msc.examples.log4j.Log4jNoSecureConnectionTest=ERROR, SMTP_NO_SECURE_CONNECTION

log4j.appender.SMTP_NO_SECURE_CONNECTION.layout=org.apache.log4j.SimpleLayout
log4j.appender.SMTP_NO_SECURE_CONNECTION=org.apache.log4j.net.SMTPAppender
#log4j.appender.SMTP_NO_SECURE_CONNECTION.Bcc=
# the maximum number of logging events to collect in a cyclic buffer
log4j.appender.SMTP_NO_SECURE_CONNECTION.BufferSize=1
#log4j.appender.SMTP_NO_SECURE_CONNECTION.Cc=
log4j.appender.SMTP_NO_SECURE_CONNECTION.From=system.alert@examples.msc.se
log4j.appender.SMTP_NO_SECURE_CONNECTION.LocationInfo=true
log4j.appender.SMTP_NO_SECURE_CONNECTION.SMTPDebug=true
log4j.appender.SMTP_NO_SECURE_CONNECTION.SMTPHost=smtp.XXX.se
log4j.appender.SMTP_NO_SECURE_CONNECTION.SMTPPassword=YYY
log4j.appender.SMTP_NO_SECURE_CONNECTION.SMTPUsername=ZZZ
log4j.appender.SMTP_NO_SECURE_CONNECTION.Subject=System Alert NO SECURE CONNECTION
log4j.appender.SMTP_NO_SECURE_CONNECTION.To=DDD

log4j.logger.se.msc.examples.log4j.Log4jTLSTest=ERROR, SMTP_TLS

log4j.appender.SMTP_TLS.layout=org.apache.log4j.SimpleLayout
log4j.appender.SMTP_TLS=org.apache.log4j.net.SMTPAppender
#log4j.appender.SMTP_TLS.Bcc=
# the maximum number of logging events to collect in a cyclic buffer
log4j.appender.SMTP_TLS.BufferSize=1
#log4j.appender.SMTP_TLS.Cc=
log4j.appender.SMTP_TLS.From=system.alert@examples.msc.se
log4j.appender.SMTP_TLS.LocationInfo=true
log4j.appender.SMTP_TLS.SMTPDebug=true
log4j.appender.SMTP_TLS.SMTPHost=smtp.gmail.com
log4j.appender.SMTP_TLS.SMTPPassword=FOO
log4j.appender.SMTP_TLS.SMTPUsername=foo.bar@gmail.com
log4j.appender.SMTP_TLS.Subject=System Alert TLS
log4j.appender.SMTP_TLS.To=foo.bar@gmail.com



package se.msc.example.log4j;

import org.apache.log4j.Logger;
import org.junit.Test;

public class Log4jNoSecureConnectionTest {
 private static final Logger log = Logger.getLogger(Log4jNoSecureConnectionTest.class);
 
 @Test
 public void testFoo() throws Exception {
  // Either set smtp properties programmatically or via JVM argument -D
  System.setProperty("mail.smtp.port", "587");
  log.error("Fatal log message.", new NullPointerException("Null pointer exceptopn."));
 }

}



package se.msc.example.log4j;

import org.apache.log4j.Logger;
import org.junit.Test;

public class Log4jTLSTest {
 private static final Logger log = Logger.getLogger(Log4jTLSTest.class);
 
 @Test
 public void testFoo() throws Exception {
  // Either set smtp properties programmatically or via JVM argument -D
  System.setProperty("mail.smtp.port", "465");
  System.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
  System.setProperty("mail.smtp.socketFactory.port", "465");
  System.setProperty("mail.smtp.socketFactory.fallback", "false");
  log.error("Fatal log message.", new NullPointerException("Null pointer exceptopn."));
 }

}



<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

 <modelVersion>4.0.0</modelVersion>
 <groupId>se.msc.example</groupId>
 <artifactId>log4j</artifactId>
 <packaging>jar</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>Log4J Test</name>
 <url>http://www.msc.se/example/log4j</url>

 <developers>
  <developer>
   <id>magnus.k.karlsson</id>
   <name>Magnus K Karlsson</name>
   <email>magnus.k.karlsson@msc.se</email>
   <organization>MSC</organization>
  </developer>
 </developers>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <dependencies>
  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.15</version>
  </dependency>
  <!-- sun java mail -->
  <dependency>
   <groupId>javax.mail</groupId>
   <artifactId>mail</artifactId>
   <version>1.4.1</version>
  </dependency>  
  <!-- unit testing -->  
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.7</version>
   <scope>test</scope>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <!-- to compile with JDK 1.6 -->
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
     <source>1.6</source>
     <target>1.6</target>
    </configuration>
   </plugin>
  </plugins>
 </build>

</project>

February 1, 2010

Java Generics Example Strategy Pattern

With Java Generics Java has continued its path to make it's language more strong typed, with comparison to all new dynamic language where they have thrown out strong typing. But Java Generics can also be hard to understand and one of the best example to show the main benefit with it is the strategy pattern. Lets start to look of a example.


If we were using Java JDK 1.4 we have to do down-casting in the concrete strategy classes, but with Generics that is not necessary.

The Strategy Context/Client
package se.msc.examples.generics;

public abstract class Data<D extends Data<D>> {
 public static final Strategy<FooData> FOO_STRATEGY = new FooStrategy();
 public static final Strategy<BarData> BAR_STRATEGY = new BarStrategy(); 
}


The Strategy itself
package se.msc.examples.generics;

public abstract class Strategy<D extends Data<?>> {
 public abstract String exec(D data); 
}



And the extended Data classes
package se.msc.examples.generics;

public class FooData extends Data<FooData> {
 public final double value; 
 
 public FooData(double value) {
  this.value = value;
 }

 public double getValue() {
  return value;
 }
}


And the extended Strategy
package se.msc.examples.generics;

public class FooStrategy extends Strategy<FooData> {

 public String exec(FooData data) {
  return "Hi " + data.getValue();
 }
}


And our test class.
package se.msc.examples.generics;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class StrategyTest {

 @BeforeClass
 public static void oneTimeSetUp() throws Exception {
 }

 @AfterClass
 public static void oneTimeTearDown() {
 }

 @Before
 public void setUp() throws Exception {
 }

 @After
 public void tearDown() throws Exception {
 }

 @Test
 public void testFooStrategy() throws Exception {
  assertEquals("Hi 3.0", Data.FOO_STRATEGY.exec(new FooData(3)));
 }
}

January 30, 2010

Maven Reporting with Cobertura, Dashboard, Change Report, FindBugs and PMD

I have been using maven coberture plugin before but it has one unimplemented function, aggregate cobertura report from multiple module. This can be solved by sonar and dashboard maven plugin, but Sonar requires that is run on a server, i.e. that you have a continuous integration server, but in some cases you have not got there and still is building your application locally than you can use the maven Dashboard plugin.


The parent pom.xml

<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

 <modelVersion>4.0.0</modelVersion>
 <groupId>se.msc.examples</groupId>
 <artifactId>reporting-parent</artifactId>
 <version>0.1-SNAPSHOT</version>
 <packaging>pom</packaging>
 <url>http://www.msc.se/examples</url>
    <organization>
        <name>Msc.se</name>
    </organization>
    <developers>
     <developer>
      <name>Magnus K Karlsson</name>
      <email>magnus.k.karlsson@msc.se</email>
     </developer>
    </developers>
    
 <modules>
  <module>reporting-demo</module>
  <module>reporting-core</module>
 </modules>
 
 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.2</version>
   <scope>test</scope>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.0.2</version>
    <configuration>
     <source>1.5</source>
     <target>1.5</target>
     <encoding>UTF-8</encoding>
    </configuration>
   </plugin>
  </plugins>
 </build>

 <reporting>
  <plugins>
   <!-- Generate 'Changes Report' from src/changes/changes.xml -->
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-changes-plugin</artifactId>
    <version>2.3</version>
    <reportSets>
     <reportSet>
      <reports>
       <report>changes-report</report>
      </reports>
     </reportSet>
    </reportSets>
   </plugin>

   <!-- JXR - Source code as HTML --> 
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jxr-plugin</artifactId>
    <version>2.1</version>
    <configuration>
     <!-- Enable aggregation for multimodule projects. -->
     <aggregate>true</aggregate>
     <inputEncoding>utf-8</inputEncoding>
     <outputEncoding>utf-8</outputEncoding>
    </configuration>
   </plugin>

   <!-- JavaDoc - API-documentation -->
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.6.1</version> 
    <configuration>
     <!-- Enable aggregation for multimodule projects. -->
     <aggregate>true</aggregate>
                    <show>public</show>
                    <charset>utf-8</charset>
                    <docencoding>utf-8</docencoding>
                    <encoding>utf-8</encoding>     
    </configuration>
   </plugin>

   <!-- Surefire - JUnit testing-->
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-report-plugin</artifactId>
    <version>2.5</version>
    <configuration>
     <!-- Required to properly link JXR -->
     <xrefLocation>${project.reporting.outputDirectory}/../xref-test</xrefLocation>
    </configuration>
   </plugin>

   <!-- JDepend - Package dependencies -->
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jdepend-maven-plugin</artifactId>
    <version>2.0-beta-2</version>
   </plugin>

   <!-- Cobertura - Test code coverage report. -->
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>cobertura-maven-plugin</artifactId>
    <version>2.3</version>
   </plugin>
   
   <!-- PMD - Generate PMD and CPD reports using the PMD code analysis tool. -->
            <plugin>
             <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-pmd-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                 <linkXref>true</linkXref>
                 <!-- Required to properly link JXR -->
     <xrefLocation>${project.reporting.outputDirectory}/../xref-test</xrefLocation>
                 <sourceEncoding>utf-8</sourceEncoding>
                    <aggregate>true</aggregate>
                    <targetJdk>1.5</targetJdk>
                </configuration>
            </plugin>
            
   <!-- FindBugs - Finds potential bugs in your source code -->
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>findbugs-maven-plugin</artifactId>
    <version>2.3</version>
    <configuration>
     <xmlOutput>true</xmlOutput>
     <effort>Max</effort>
    </configuration>
   </plugin>

   <!-- JavaNCSS - Source code metrics -->
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>javancss-maven-plugin</artifactId>
    <version>2.0</version>
   </plugin>

   <!-- TagList - Creates a list with TODO:s etc -->
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>taglist-maven-plugin</artifactId>
    <version>2.4</version>
                <configuration>
                    <aggregate>true</aggregate>
                    <tags>
                        <tag>TODO</tag>
                        <tag>FIXME</tag>
                        <tag>@todo</tag>
                    </tags>
                </configuration>    
   </plugin>

   <!-- The dashboard plugin should be specified as the last report. -->
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>dashboard-maven-plugin</artifactId>
    <version>1.0.0-beta-1</version>
   </plugin>

  </plugins>
 </reporting>

</project>



The jar module pom.xml

<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

 <parent>
  <groupid>se.msc.examples</groupId>
  <artifactid>reporting-parent</artifactId>
  <version>0.1-SNAPSHOT</version>
 </parent>
 <modelversion>4.0.0</modelVersion>
 <artifactid>reporting-demo</artifactId>
 <packaging>jar</packaging>
 <name>Demo Reporting</name>

 <reporting>
  <!-- Needed in order to generate the dashboard report properly. -->
  <outputdirectory>
            ${basedir}/../target/site/${project.artifactId}
        </outputDirectory>
 </reporting>

</project>