2009/11/28

Image Analysis

Today, I needed to compute an average value of a function. The problem was that the function was a chart in a .gif image.

I run across a great application called ImageJ. It has a pluggable interface, many powerful functions, it is open-source and written in Java. The platform independent distribution has only 3MB.

I opened my image in the application, cropped the unnecessary parts, and used the magic wand to selected the area under the function line. Then I just clicked on measure and got the area of 69035 pixels (btw. this is the value of the integral). I divided the number by the width of the image and got 226. Now I subtracted 226 from the image height and looked at the y-axis for the average value - 8.7...

Disclaimer: ImageJ is being developed at the National Institutes of Health by an employee of the Federal Government in the course of his official duties. Pursuant to Title 17, Section 105 of the United States Code, this software is not subject to copyright protection and is in the public domain. So long and thanks for ImageJ!

2009/09/07

Performance testing: Load generator

Introduction

Performance testing is a wide term, so let me be more specific please: performance testing of a message oriented middleware from the client's point of view. A message oriented middleware can be an Enterprise Service Bus for instance. We tried several implementations - JBoss ESB, WSO2 ESB, and Mule ESB.

What does the "testing from the client's point of view" mean? It means that we don't care about internal processes of the ESB. We just care how long it takes to process our request. It reminds of integration testing in the classical V-Model.

Problem Definition

We were working in a team on the problem and after trying several load generators, we found out that there is none that is generic enough. We wanted to send various types of messages (e.g. JMS, SOAP, files...) in different ways (send all messages at once, find the maximum sustainable speed, run a long-term test...). Apache JMeter approaches the ideal but is still missing some features. Moreover, we experienced high results jitter over time. So we decided to write our own lightweight, easy-to-use load generator. Here are some basic requirements:

  • Stable results.
  • There must be a constant message inflow while received messages are being processed.
  • Messages must be generated by many concurrent clients.
  • Clients must run on remote machines not to influence results.
  • Speed should be measured on the client side for us not to affect the server.

Solution

Message Sender

First, there are different types of messages. So let's have an interface of a component that just sends a particular message.

public interface MessageSender {
  public void setProperty(String prop, String value);
  public void init(String address) throws Exception;
  public void close();
  public Serializable send(Serializable message, 
    Map properties) throws Exception;
  public MessageSender clone();
}

The component should be able to get configured with standard property/value pairs, initialize a connection to a given address, send a serializable message (e.g. a String), and close the connection. Moreover, it can clone itself for us not to have to configure each instance.

There are two important decision points. First, do you want MessageSender to be reusable - to be able to send more than one message? When you are careful enough, you should be able to achieve this. At least, we did not experience any problems with that.

Second, do you want your senders to be thread safe? This is a completely different situation, which is really hard to achieve and keep high performance. An example is sending of JMS messages. JMS session is not thread safe but it takes relatively long time to initialize. You might want to extend the interface and create a ThreadSafeMessageSender.

An example of an HTTPSender is shown below.

public class HTTPSender implements MessageSender {
  private URL url;
  private String method = "POST";

  public void setProperty(String prop, String value) {
    if ("method".equals(prop)) {
      method = value;
    }
  }

  public void init(String address) throws Exception {
    url = new URL(address);
  }

  public void close() {
  }

  public Serializable send(Serializable message, Map properties) throws Exception {
    HttpURLConnection rc = (HttpURLConnection) url.openConnection();
    
    // ... standard HttpUrlConnection usage ...

    return response;
  }

  @Override
  public MessageSender clone() {
    ...
  }
}

Message Generator

Next, there must be a message generator that uses message senders to generate messages in a given way.

public abstract class MessageGenerator {
  protected MessageSender sender;
  protected int threads = 1;

  public void setProperty(String property, String value) {
    if ("threads".equals(property)) {
      threads = Integer.valueOf(value);
    }
  }

  public void init(String address, MessageSender sender) throws Exception {
    this.sender = sender;
    this.sender.init(address);
  }

  public void close() {
    sender.close();
  }

  public abstract void generate(Serializable message, int count) throws Exception;
}

As you can see, an already configured instance of MessageSender must be passed to the MessageGenerator in the init() method. It is not a constructor because some configuration of the generator might be performed first in its descendants. This abstract generator supposes that the message sender is thread safe, because it uses just a single instance to pass all the messages through. Descendants might want to clone this instance in case it were not thread safe.

We used several new features of Java 6 to create a message generator that just sends all the messages to the server in a given number of threads. Let's first examine a sender task that is created per each thread. It uses shared AtomicInteger to keep track of actually sent messages.

public class SenderTask implements Runnable {
  private MessageSender sender; // shared sender
  private Serializable message; // message to send
  private AtomicInteger counter; // shared message counter
  private int count; //  number of messages for this thread

  public SenderTask(AtomicInteger counter, MessageSender sender, 
      String address, Serializable message, int count) 
      throws Exception {
    this.count = count;
    this.sender = sender;
    this.message = message;
    this.counter = counter;

    // expect sender's uninitialized clone
    this.sender.init(address);
  }

  @Override
  public void run() {
    try {
      for (int i = 0; i < count; i++) {
        sender.send(message, null);
        counter.incrementAndGet();
      }
    } catch (Exception e) {
      log.error(e);
    } finally {
      sender.close();
    }
  }
}

In the next listing, there is an implementation of the generate() method. No speed measurement code is included but the main goal here was to show the ExecutorService's usage.

@Override
public void generate(Serializable message, int count) 
    throws Exception {
  List<SenderTask> taskList = 
    new ArrayList<SenderTask>(threads);

  // Let tasks to initialize senders
  for (int i = 0; i < threads; i++) {
    taskList.add(new SenderTask(counter, sender.clone(), 
      address, message, perThreadMessageCount);
  }

  // Submit all tasks for completion
  ExecutorService es = Executors.newFixedThreadPool(threads);
  for (int i = 0; i < threads; i++) {
    es.submit(taskList.get(i));
  }

  // Wait for termination
  es.shutdown();
  boolean terminated = false;
  while (!terminated) {
    // output current state
    // take some sleep
    // updated 'terminated' variable
  }
}

As you can see, clones of the original sender are created for us not to have to take care of the thread safeness. Individual SenderTask instances are created in advance for all sender clones to get initialized. Then the instances are put in an ExecutorService and executed. While we are waiting for all threads to finish, we can periodically output current and overall throughput for instance.

Conclusion

This concept already demonstrated its value in real world scenarios. We were able to write various message senders and generators easily and quickly. Even though it may look simple, there are some factors you must take into consideration.

First is the warm up period of the server. You could either run the test several times and ignore a couple of first runs, or extend the generator to throw in some more messages and do not count them.

Second, always make sure that the client is able to generate messages several times faster than the server is able to process. Otherwise, you measure the client's performance, which is something you do not want probably.

WSDL 2.0: Quick reference

I wrote this blog entry mainly for me - to beat WSDL structure in my mind in a clean and nice way. Hopefully, it will help some others as well.

I would like to introduce changes between WSDL 1.1 and 2.0, and to go through the individual parts of the new WSDL version. This blog entry is based on several other on-line resources as well as books.

Introduction

WSDL stands for Web Services Description Language. It is a document written in XML. The document describes a Web service, specifies the location of the service, and the operations (or methods) the service exposes.

WSDL 2.0 was first developed as WSDL 1.2 but was renamed because of its substantial differences. Some major changes are:

  • Adding further semantics to the description language.
  • Removal of message constructs. These are specified using the XML schema type system in the types element.
  • No support for operator overloading.
  • PortTypes renamed to interfaces. Support for interface inheritance is achieved by using the extends attribute in the interface element.
  • Ports renamed to endpoints.

Conceptual Model

The description consists of two parts. In the abstract part, WSDL describes a web service in:

  • Messages it sends and receives using a type system (typically W3C XML Schema).
  • Message exchange patterns that define the sequence and cardinality of messages.
  • Operations that associates message exchange patterns with one or more messages.
  • Interfaces group these operations in a transport and wire independent manner.

In the concrete part of the description:

  • Bindings specify the transport and wire format for interfaces.
  • A service endpoint associates network address with a binding.
  • A service groups the endpoints that implement a common interface.

Structure

Following is a basic WSDL structure

<definitions targetNamespace="xs:anyURI">
<documentation /> ?
[<import /> | <include /> ] *
<types /> ?
[<interface /> | <binding /> | <service /> ] *
</definitions>

Definitions

The definitions element serves as a container.

<definitions name="StockQuote"
  targetNamespace="http://example.com/stockquote/definitions"
  xmlns:tns="http://example.com/stockquote/definitions"
  xmlns:xsd1="http://example.com/stockquote/schemas"
  xmlns:soap="http://www.w3.org/2003/11/wsdl/soap12"
  xmlns="http://www.w3.org/2003/11/wsdl">

Include

The include element helps to modularize the web service descriptions. Included documents must have the same target namespace.

Import

The concept behind the import element is very similar to that of include element, except that the imported WSDL can be in different target namespaces.

<import namespace="http://example.com/stockquote/schemas"
  location="http://example.com/stockquote/stockquoteV20.xsd"/>

Types

The types element defines the data types used by the exchanged messages. WSDL uses W3C XML Schema as its preferred schema language.

The following example refers to an imported XSD.

<types>
  <schema 
    targetNamespace="http://example.com/stockquote/definitions">
    <element name="GetLastTradePriceInput" 
      type="xsd1:TradePriceRequest"/>
    <element name="GetLastTradePriceOutput" 
      type="xsd1:TradePrice"/>
  </schema>
</types>

Interface

An interface element encloses a named set of abstract operations and the abstract messages. It can extend one or more other interfaces. Interfaces are referred to by QName in other components.

<interface name="StockQuoteInterface">
  <operation name="GetLastTradePrice" pattern="http://www.w3.org/2003/11/wsdl/in-out">
    <input message="tns:GetLastTradePriceInput"/>
    <output message="tns:GetLastTradePriceOutput"/>
  </operation>
</interface>

Binding

The binding element defines the underlying transport and wire format for messages. Each binding references to an interface.

<binding name="StockQuoteSoapBinding" 
  interface="defs:StockQuoteInterface">
  <soap:binding protocol="http://www.w3.org/2003/11/wsdl/http"/>
  <operation name="GetLastTradePrice">
    <soap:operation 
      soapAction="http://example.com/GetLastTradePrice"/>
    <input>
      <soap:body/>
    </input>
    <output>
      <soap:body/>
    </output>
  </operation>
</binding>

Service

A service element describes a set of endpoints which refer to a single network address for a binding. All other protocol specific information is contained in the binding.

<service name="StockQuoteService">
  <documentation>My stock quote service</documentation>
  <endpoint name="StockQuoteEndPoint" 
    binding="tns:StockQuoteSoapBinding">
    <soap:address location="http://example.com/stockquote"/>
  </endpoint>
</service>

Conclusion

Despite of the fact that the WSDL format might seem over-engineered to you (because it probably is), you should now be aware of its content and the meaning of individual elements.

References

[1] Article on WSDL at www.xml.com
[2] W3C School WSDL Tutorial
[3] Web Service Platform Architecture on InformIT.com

2009/05/13

EJB3: Conscious Session Bean

Last week, I wanted to demonstrate @TransactionAttribute in a session bean using JBoss AS 5.1.0 GA and EJB3. Everything seemed pretty simple...

@Stateless
public class OmnipotentBean implements Omnipotent {
    @TransactionAttribute(REQUIRED)
    public String transactionRequired() throws SystemException {
        try {
            transactionNever();
            System.err.println("No exception occured - ERROR");
        } catch (EJBException e) {
            System.out.println("Expected exception - OK");
        }
    }

   @TransactionAttribute(NEVER)
    public String transactionNever() throws SystemException {
        ...
    }
}

As you can see, I wanted to show that calling a method with a transaction attribute set to NEVER from a method that already runs in a transaction throws an exception. But the exception was not thrown. How come?

Let's start from the client. What kind of object do we get from JNDI when we looked up OmnipotentBean/remote? It was neither OmnipotentBean or its interface. It was a dynamically generated class based on java.lang.reflect.Proxy, which handles all method calls and passes them to the server. You can call its method because it implements Omnipotent interface. Moreover, the call passes through a set of interceptors, which can perform additional work and setup the environment, inlcuding security and transactional interceptors.

The same applies at the server side. What is this inside transactionRequired() method? It is just a OmnipotentBean class instance, thus a simple POJO. We must lookup the EJB through JNDI to get a proxy object for transactional attributes to start working.

Another uncomfortable thing is that we cannot use dependency injection in our session bean to inject its proxy. Not having the bean initialized at the time of its initialization when dependencies are being injected, this is the cause.

So, are all the problems just JBoss AS's whims? What does the specification say? EJB3 - JSR-220 (file EJB Core, page 343):

The following subsections define the responsibilities of the container for managing the invocation of an enterprise bean business method when the method is invoked via the enterprise bean’s business interface (and/or home or component interface), or web service endpoint. The container’s responsibilities depend on the value of the transaction attribute.

Everything is all right. EJB container (i.e., the application server) must manage the invocations of bean's methods only when they are called via the business interface, which is the proxy object.

Maybe this is not suprising to you and you are right. It is very logical. Just bear in mind that a session bean must be conscious of its own business interface when invoking methods of its own.

2009/04/18

RichFaces and Background Gradient

I do not know whose idea it was. Maybe it is there just to demonstrate some advanced RichFaces' abilities but I (in all the humbleness) hate it. I am talking about the background gradient which is by default present at table headers and toolbars. The background is a dynamically generated image and its presence in a web page is caused by XML snippets like the following one (part of richfaces-ui.jar:/org/richfaces/skin.xcss).

<u:style name="background-image">
  <f:resource xmlns:f="http:/jsf.exadel.com/template" f:key="org.richfaces.renderkit.html.GradientA"/>
</u:style>

A friend of mine would call such a beatiful thing a funfair or a fly-by. Apart from the hardcoded gradient background I miss only one thing in RichFaces.

A scrolling text that blinks in Firefox and Opera.

It took me couple of hours to get over the problem, yet I'm not satisfied with either solution I found.

Solution no. 1: Override the default behavior

Your CSS style can be loaded later and override the background you are not satisfied with. This is even "oficially" recommended. The linked page speaks about rich:dataTable so I am adding my part for rich:Toolbar.

.rich-toolbar, .rich-toolbar-item {
    background-image:none;
    background-color:transparent;
}     

You can of course set more convenient background color. The big issue here is that you still have the gradient style configured and loaded by your browser, and the background image generated at the server.

Solution no. 2: Update richfaces-ui.jar

You can grep through all .xcss files inside richfaces-ui.jar and remove the gradient from whatever place you want. You get tinier CSS and less work on the server side. But you have to repeate the procedure every time you want to upgrade RichFaces version. And you also must be careful about your richfaces-ui-without-gradient.jar.

I like neither of the solutions. For my project I went with no. 1 and I hope that there will be a new gradient style to configure in my skin.properties: gradientStyle=NONE.

2009/04/09

TestNG and Group Filters

Recently I solved an interesting problem with test groups in TestNG. To describe the problem, let me describe a sample test class with three methods, which are included into two groups.

public class SampleTest {
  @Test(groups = { "groupA" })
  public void testMethod1() {
    System.out.println("1 in A");
  }

  @Test(groups = { "groupA", "groupB" })
  public void testMethod2() {
    System.out.println("2 in A, B");
  }

  @Test(groups = { "groupB" })
  public void testMethod3() {
    System.out.println("3 in B");
  }
}

Usually, TestNG is called using an Ant task like the following one.

<testng excludedGroups="..." groups="..." ... />

What methods can be executed with various groups and excludedGroups setting presents this table:

MethodsgroupsexcludedGroups
1groupAgroupB
1, 2groupA--
2, 3groupB--
3groupBgroupA
1, 2, 3----

This is pretty logical. But wait, there is a combination missing from that table. What about just the method 2, which is in groupA and groupB? To be honest, I did not find an easy way to achieve this. But there is a workaround. First, you must use an external configuration file for TestNG.

<testng classpathref="...">
  <xmlfileset dir="." includes="testng.xml"/>
</testng>

In this file, you can use Beanshell to enable/disable individual methods.

<suite name="TestSuite">
  <test name="SampleTest">
    <method-selectors>
      <method-selector>
        <script language="beanshell"><![CDATA[
          groups.containsKey("groupA") && groups.containsKey("groupB")
        ]]></script>
      </method-selector>
    </method-selectors>
    <classes>
      <class name="com.blogspot.qecafe.tests.SampleTest" />
    </classes>
  </test>
</suite>

The magic line in Beanshell will cause only methods in both groups to be executed.

There is yet another item missing - 1, 3 combination. You can run it in a similar way just like 2.

2009/04/07

Temptations of Software Engineers

Have you ever been tempted to use a technology just because of the technology itself? Was the technology such a fancy thing that you could not resist? Please do not do that! A result of your work would be barely usable in the real life. Do you know the superior Swiss knife with all the stuff inside? I am in doubt you could ever carve a little wooden ship for your son with it.
Let me tell you a true story of a software engineer and an application he developed.

Once upon a time, there was a guy who decided to learn Java and all its bright features, which brought the light on every programmer's possible problem. He chose a set of features that were most interesting to him including serialization, and multi threading. To be not all alone and to verify his code, he decided to take a community as a hostage. Let's inspect a couple of his mistakes.

First, serialization is good for remote method invocation, for sending objects over network, and even for storing small project configurations into a file. It should not be used as a primary data storage, since there are relational databases for such a purpose. If you wanted to be thread safe in a serialize-everything environment, you must keep all the objects in the memory and (de)serialize them only on an application start/shutdown. It is slow, complicated and inefficient way.

Second, multi threading is a powerful thing but it is like the fire - it can be very dangerous. Threads are not independent processes. You should be careful about them, especially if they are running third party code. Apart of that issue, the biggest problem was that Thread.stop() does not stop a waiting thread on all JVM implementations. It is not good idea to stick to an implementation detail. Later, Thread's methods stop(), suspend(), and resume() have become deprecated because it showed up that they are unsafe.

I could have continue here with similar cases but that should be enough to show what I meant by temptations. If the project were now buried deep in the binary scarp, everything was fine. Unfortunately, the community around it become large and the project is massively used nowadays. And the users must fight with those design issues hidden deep inside of it.

2009/04/01

Guts of Programming Languages

What makes it difficult to master a new programming language when you already know one or two? Is it a fancy syntax? Is it an API? I do not think so.

A syntactic sugar is not the real matter of the programming art. It should be only a hammer for your nails. Usually, a new syntax is not so much different. I mean how often do you meet a brand new paradigm? There is imperative, functional, logic and whatever programming, but you have probably chosen your way already.

Modern IDEs can help you with the API of the new language. Again, API should not be an obstacle. But there is still a thing that you must be aware of...

I do not know of any real programming language that isolates a programmer from its inside behavior (by a real programming language I mean a language that is commonly used for developing long running applications). You always need to be aware of a memory model, of a garbage collection mechanism, of a just in time compilation, of a target system architecture, of registers size, of a class inner representation, of a variable size in bytes...

There are too many "of". I wonder when there is a language that allows developers to concentrate completely on the main problem. A friend of mine suggested that PHP is such a language but I do not agree with that. It is a language which leaves a field of corpses behind itself and must finish processing sooner than anybody reveals this fact.

I have a favorite programming language, which isolates me at most. It is in the functional languages family, and it is called Haskell. You can even write a GUI application in Haskell, but an application server would be a death match.

So good luck in those hard times and do your best for you not to forget any single language implementation detail...

. .