Wednesday, 30 January 2013

JUnit: Automated testing in Java

Automated testing in Java

The 1 minute guide to JUnit

1 minute. We will get you using JUnit and automated testing in 1 minute.

This is not a JUnit manual. It is not a tutorial. This post is simply a starting point. We assume that you are using Eclipse as an IDE.

What is JUnit?

  • Automated testing that's 100% Java.
  • No cost, part of Java technology
  • It calls tests that you write yourself in Java. JUnit is a way of running tests that you have written.
  • It saves huge amounts of time and effort keeping your software tested with each change that you make.
  • Get the best benefit using JUnit in an IDE such as Eclipse.

JUnit structure 

Your JUnit should match your application. For each class in your application, you create a corresponding JUnit class. For each method in your applicaiton class, created one or more test methods in your JUnit class:

In the Application, for each: Create in JUnit:
Class Associated test class
Class method One or more test methods

For example, your application has a class HexEncode.java that contains a method:
public static String encodeString(String inp)
You would create a JUnit class as follows:

In the Application: Create in JUnit:
HexEncode.java HexEncodeTest.java
Method: encodeString public void testEncodeString()

Note
  • JUnit methods are of type public void with no parameters.
  • Put the word "Test" at the end of your JUnit class name.
  • put the word "test" in front of each method. If you don't JUnit will not run that method.
 You can create the methods setUp and tearDown. These JUnit calls before processing (setUp) and after processing (tearDown) the test methods in your JUnit class. For example, these are where you may want to connect to a database and close the database connection.

You can create other methods in your JUnit and use them internally. If they don't start with test they won't be called.

JUnit class definitions

A JUnit class imports junit.framework.TestCase and the class extends TestCase:
import junit.framework.TestCase;

public class MyAppClassTest extends TestCase {

Specifying success and failure

JUnit provides assert* methods, the most widely used being assertEquals. This is how the tests are implemented. You do whatever setup you need in your JUnit method first, then you assertEquals the expected result with the variable (or method return) that contains the real world result.

For example, to test encodeString above, we create the method testEncodeString in our HexEncodeTest class:

import junit.framework.TestCase;
public class HexEncodeTest extends TestCase {
    public void testhexEncodeTest() {        String enc=  ":42:72:61:64:20:A3:31:32:33:30";        String orig= "Brad £1230"; 
        assertEquals(enc, HexEncode.encodeString(orig));
               
    }

}
This then calls our application class's encodeString method and tests against the expected result (held in variable enc). If the two match, the test passes. If they are different, the test fails.

You can write as many test* methods as you want, JUnit will call them all. You can put as much Java coding into your methods as you want, sufficient to test all the expected actions and results from your application method.

Note: assertEquals is the essence of JUnit and takes any Java parameter type.

Common setup methods

The order of JUnits running cannot be guaranteed. You should always write your JUnit classes so that they are completely stand-alone. By this we mean that they set up all the data that they need from scratch. They do not depend on other tests having run (or not run) and if the test data is in a mess, it shouldn't matter, because the class must set up the data that it needs.
Likewise your test methods within those classes should also be stand-alone and able to be run in any order. They should not depend on other methods having run first and they should always set up the test data that they need completely within the method.
For this reason, you will almost certainly benefit from writing common "set up" and "clean up" methods, either within the JUnit class itself, or as a separate class the each JUnit class can use. This is especially useful for setting up test data in a database.

Creating JUnits in Eclipse

In Eclipse, open your project then click on File->New->JUnit Test Case.

Running JUnits in Eclipse

  • All tests: In Eclipse, open your project then right-click on the "test" folder. Then choose Run As->JUnit Test
  • One test class: Right-click the test class then choose: Run As->JUnit Test

Failed tests

Eclipse will show you the tests that fail in the Failure Trace pane. It displays the expected results and the real results. You can click on the line to jump to the test that failed.

JUnit as you develop

JUnit is there to save you time and effort. If you write your JUnits for the code that you are developing, as you develop the code:
  • The JUnits will test your code
  • Writing JUnits ensures that you understand the code requirements
  • Because testing seeks to find boundary, logical and exceptions errors, writing JUnits as you develop ensure that you develop complete code that handles errors and exceptions as well as being correct
The dividends in your efforts quickly stack up if you develop JUnits alongside your application code development.

Software releases

Never release software unless you have run the entire JUnit test suite successfully (see All tests above).

Real world bugs

If a bug in your code is discovered in the real world, you didn't put that test in your JUnits! You should immediately update your JUnits to test for that bug:
  • It will test your fix
  • It will protect you against that same bug re-appearing later

Wednesday, 20 January 2010

Azureus/Vuze fails to start - java.lang.NoClassDefFoundError: org/apache/log4j/Layout

Think bit torrent and most people think illegal file downloads. However, many OpenSource products and vendors use bit torrent distribution and it is part of the backbone of the OpenSource movement.

Azureus or Vuze is one of the best bit torrent clients out there. Written in Java, it is cross platform and the developers are Java gurus who have brought the best of Java to the best of OpenSource in a truly fanstastic bit of software.

However, as with most things Java, when an installation or upgrade fails, most users are left out there in the cold. And one of the most common ways for an Azureus upgrade or installation to fail is with this error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Layout

Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Layout

at java.net.URLClassLoader$1.run(URLClassLoader.java:217)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:205)

at java.lang.ClassLoader.loadClass(ClassLoader.java:323)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)

at java.lang.ClassLoader.loadClass(ClassLoader.java:268)

at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)

Could not find the main class: org.gudy.azureus2.ui.common.Main. Program will exit.


It looks nasty, but actually the problem is very simple. What this is telling you is that the Azureus startup cannot find the jar file that has log4j in it. For example, log4j-1.2.15.jar. The solution is to tell the JVM where to find this on your system when Azureus starts up.

In kubuntu, which we prefer to use at Kieser.net, the azureus startup command is a shell script located here:

/usr/bin/azureus

The contents of this script look like something this (it will differ slightly in each installation depending on the Java that you have installed):

#!/bin/sh

JAVA='/usr/lib/jvm/java-6-openjdk/jre/bin/java -Xmx1024M'

/usr/share/java-config/libswt-3.4-java

if [ -z $VUZE ]; then

UI=-Dforce.ui=az2

fi

exec $JAVA -Djava.library.path=/usr/lib/jni:/usr/lib \

-classpath /usr/share/java/Azureus2.jar:$JARS \

-Dazureus.install.path="$HOME/.azureus" \

$UI \

org.gudy.azureus2.ui.common.Main "$@"


Note the line

./usr/share/java-config/libswt-3.4-java


This sets the variable $JARS which is passed as the classpath to the Java command. We need to add out log4j.jar path to that variable. This is what the file /usr/share/java-config/libswt-3.4-java looks like on our desktops:

JARS=/usr/share/java/swt-gtk-3.4.jar

So, locate where your log4j jar file is, then add it to this list. Here is what ours looks like:

JARS=/usr/share/java/swt-gtk-3.4.jar:/usr/share/java/log4j-1.2.15.jar

Now you can start up Azureus and all will be well!

If you haven't got log4j installed on your system, then you need to install it first. Most linux distributions have packages for log4j and you simply need to install that package using the package manager. But don't expect that installation to then add the jar file to the Azureus startup! It doesn't know to do that, so you need to manually edit the script that runs Azureus and sets the classpath as we have shown above.

Please note that Kieser.net is strictly against illegal file sharing. We support only legal and legitimate use of this technology, preferably use that promotes and helps OpenSource software adoption.

Honeypot: spam@kieser.net

JBuilder fails to find row to update during save


Making Jbuilder resolve using table keys only

Jbuilder is a fantastic rapid application development tool. It offers drag and drop database application building backed by a powerful set of libraries that you can free redistribute with your application. Jbuilder, combined with the awesome power of Postgres is an application infrastructure that is difficult to beat. In fact, there are no similar platforms that offer the same enterprise capabilities but without the need for a license when it comes to distributing your work. Jbuilder and Postgres also work extremely well together, straight out the box. Deploying an application based on these two technologies is cheap, easy and usually trouble-free.

Jbuilder's weakness is its poor documentation and lack of third party books. Many Jbuilder tricks and techniques implemented in this powerful RAD are either tucked away in difficult-to-find parts of the online documentation or are simply not documented at all. Even when you know that a feature exists within Jbuilder, finding the right search clause to use to elicit this knowledge from the help system can be tricky, if not impossible without the knowledge that you are seeking.

One such problem is using Jbuilder's database express and dbSwing components with a Postgres schema based views. As we have seen, views, rules and triggers are the backbone of a good security implementation and are essential to segmenting a dataset into user-specific or user-group-specific virtual datasets. One of the many powerful facilities in Postgres is the rules system that allows views, even complex view formed from many joins across many data sources, to become updatable. A well written set of rules applied to a Postgres view can implement security, audit trails, change tracking as well as the business logic to update correctly the inbound changes from the application back into the underlying data source that the view draws upon. Not only does Postgres support this design, but a careful use of updatable views, especially when constructed from other views as well as tables, can result in extremely efficient queries and good performance thanks to the ordering of processing implicit in the use of other views in joins and the logic implemented within the update rules, procedures and triggers.

In addition to the runtime and security considerations for implementing this logic within Postgres there is the development overhead and Jbuilder capabilities to consider when attempting to implement the same logic within the Jbuilder application. Jbuilder's resolvers and RAD facilities quickly break down if you attempt to chain long and complex queries into database applications. By far the simplest and most reliable way to develop a complex database application with Jbuilder is to use Postgres to implement the database logic and Jbuilder to present this logic to the user for updating. So if your application uses a 3rd normal, secure and segmented data set, make Postgres do all the work.

But before you go away happily to database application nirvana, there is, as always, a nasty catch.

The most useful (as was a rapid) part of Jbuilder's data express and dbSwing routines undoubtly are the powerful resolvers that are built into Jbuilder. Data express and dbSwing components take a query and place the resultant dataset into a Jbuilder dataset component. If updates are made to that Jbuilder databaset component's data, Jbuilder's resolvers understand the query and can create suitable SQL statements on the fly to save those data amendments back it into the Postgres tables. Note the word tables. Because when it comes to using views per our discussion above, Jbuilder's default resolvers mysteriously break down.

If your tables have unique row identifiers (as most good database designs would implement), then you can tell Jbuilder which column(s) in the dataset form a unique identifier for each row by the following:

  1. Click on the query dataset in the structure panel. This will change the inspector panel's contents so that they query information for that dataset is displayed.
  2. Click on the update meta data option. This will pop up a dialog panel with the metadata that can be automatically detected from the query by Jbuilder. Unselect the rowid option if this is selected then press ok.
  3. In the structure panel, expand the query dataset and select the row(s) that you wish to mark as a rowid.
  4. In the inspector panel, set rowid to true.
  5. Now select the columns that do not form a rowid an in the structure panel and ensure that they have rowid set to false in the inspector panel.

The above will ensure that Jbuilder, when it attempts to resolve changes back to the database, will use only those columns that you specify as rowids to address each row during the updating. The only problem is that this doesn't work. You get an error message that looks like this:

See com.borland.dx.dataset.DataSetException error code: BASE+51

com.borland.dx.dataset.DataSetException: The row specified by the resolution query was not found.

Typical reasons are:

Somebody deleted or changed this row.

A floating point comparison failed to match.

A CHAR field needs space padding (see Database.setUseSpacePadding).

Query:

Query:

Row values used for finding existing row:



The reason for this is that Jbuilder has ignored your rowid settings. The default behaviour of the resolvers is to use all the columns in the dataset to find data in the underlying tables and if you have automatically updated columns (such as a timestamp column recording when the row was last updated or a username column recording who made the change), then your query will fail.

Now you would have thought that this was emblazoned across a hyperlink universe in the Jbuilder documentation but it is not. In fact, you cannot find this information anywhere in the Jbuilder documentation using the normal or logical searches that you would normally use to find out why your updates are failing. Even the error message itself helpfully points out all the reasons why this update could have failed, except the real reason: The resolvers are not working properly.

All is not lost, though. There is an annoyingly simple solution to this otherwise unsolvable problem. You simply add a query resolver to your application and set a property element on the resolver to tell it to use the column keys that you have specified in order to make the updates. This is how you do it:

  1. Click on the data express tab.

  2. Click on the QueryResolver button (com.borland.dx.sql.dataset.QueryResolver).

  3. Add this to your application.

  4. Select this query resolver in the structure pane.

  5. Give it a meaningful name in the inspector.

  6. Also in the inspector, change updateMode to be key columns only.

  7. Now, in each of your query datasets (click on them in the structure pane), simply click on the resolver option and your new QueryResolver will appear in the dropdown! Select your QueryResolver.

HINT: To make bulk changes,hold down the ctrl key and click each of the components that you wish to make the change to, they all become selected and you can make the change once in the inspector panel saving time and effort.

Hey presto! Suddenly your updates will work as you expect them to!

Maybe one day, someone from Borland will read this page and implement a fix, if not to the designer itself, at least to the error message generated when the updates fail pointing us to the information we need to not fall into this trap!


Honeypot: spam@kieser.net

How to import a CA certificate into java

How to
import a private and public key for jarsigning


The Sun keytool command does not support importing a private key. This is a very serious problem if you have bought a CA-signed certificate for your site and need to sign JAR files. Unless a CA-signed certificate is used, then JNLP (Java WebStart) applicatioins that require permissions to run (which they will nearly always do) will always prompt the user to grant access to run. The message tells that user that this is strongly not recommended. Not useful for JNLP-deplayed applications!

Keytool assumes that you will use the -genkey option to generate a new public/private key pair which is not useful for established ISPs and software houses! Almost without exception a SSL-using, CA-signed certificated owning organisation would have used openssl to generate the public/private keys and the CSR sent to the CA for signing. This allows the certificate to be used by Apache and other applications.

So the answer is to import the private key into the java keystore or cacerts file. Unfortunately, as keytool doesn't support this, you are at a dead end. However, a little known trick is that .p12 files can be used as keystore files. So if you export your private and public keys into a .p12 file, you can then import your CA-signed certificate and Bob's your Uncle.

First of all, make certain that your existing pem file contains the CA certificate. I.e. That it's the complete keyring with both the private and public keys contained ready for use with code signing.

This is how to export your existing pem files into a p12 format:

openssl pkcs12 -export -in -out .p12-name ""

You can verify that the Java utlities can read this by doing a list in keytool. This is how:

keytool -keystore -list -storetype pkcs12 ""

Now you are ready to code sign! Just make sure that you put the keystore type in the front part of the command and also that you give the path to the p12 file. Here is an example:

$JAVA_HOME/bin/jarsigner -keystore < path to p12 file> -storetype pkcs12 myfile.jar ""






Honeypot: spam@kieser.net

The JDBC XOPEN SQL type codes

You're programming a Java application that uses JDBC. You need to specify the data type for a column coming back from the database and you need to supply the integer code for this column's data type. So you search online and cannot find them. You search in Sun's reference and all that you find is a dumb entry saying "these are based on the XOPEN data type codes". Brilliant, NOT!

Yes, folk, there is a GLARING omission in the official Java and JDBC documentation: THEY DO NOT GIVE YOU THE ACTUAL NUMERIC CODES FOR THE JDBC DATA TYPES!

Well, here they are. Bookmark this page because you will keep coming back to it!


Honeypot: spam@kieser.net


BIT-7
BOOLEAN16
TINYINT-6
SMALLINT5
INTEGER4
BIGINT-5
FLOAT6
REAL7
DOUBLE8
NUMERIC2
DECIMAL3
CHAR1
VARCHAR12
LONGVARCHAR-1
DATE91
TIME92
TIMESTAMP93
BINARY-2
VARBINARY-3
LONGVARBINARY-4
NULL0
DATALINK70
JAVA_OBJECT2000
DISTINCT2001
STRUCT2002
ARRAY2003
REF2006
OTHER1111

A multi-threaded socket-based server

The problem is old - How to implement a multi-threaded, socket-based server that will let you read and write to the client (for example a telnet terminal.There are several problems with constructing such a server:


1.You have to use threads because otherwise clients will be queued up waiting for a connection.

2.Many of the publically available examples (even some in some books) do not work for I/O servers. They are mostly developed around reading from a socket not writing to the socket as well. In our example we give a working read/write code example.

3.You need to avoid race conditions when starting up a thread at times when connections are coming through thick and fast.

The code below will implement just such a server. It is intended for a head start, so is a template rather than a tutorial on how to write a server in Java. We have decided on port 4444 to listen on in the example, but you need to decide on a suitable port yourself.

The server will run, establishing connections from the port and echoing input received until it receives a line of input that is a full stop only ".".

Have fun!

The Kieser.net team.
Honeypot: spam@kieser.net


package sample_server;

import java.io.*;
import java.net.*;
import java.security.*;

/**
* Title: Sample Server
* Description: This utility will accept input from a socket, posting back to the socket before closing the link.
* It is intended as a template for coders to base servers on. Please report bugs to brad at kieser.net
* Copyright: Copyright (c) 2002
* Company: Kieser.net
* @author B. Kieser
* @version 1.0
*/

public class sample_server {

private static int port=4444, maxConnections=0;
// Listen for incoming connections and handle them
public static void main(String[] args) {
int i=0;

try{
ServerSocket listener = new ServerSocket(port);
Socket server;

while((i++ < maxConnections) || (maxConnections == 0)){
doComms connection;

server = listener.accept();
doComms conn_c= new doComms(server);
Thread t = new Thread(conn_c);
t.start();
}
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}

}

class doComms implements Runnable {
private Socket server;
private String line,input;

doComms(Socket server) {
this.server=server;
}

public void run () {

input="";

try {
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
PrintStream out = new PrintStream(server.getOutputStream());

while((line = in.readLine()) != null && !line.equals(".")) {
input=input + line;
out.println("I got:" + line);
}

// Now write to the client

System.out.println("Overall message is:" + input);
out.println("Overall message is:" + input);

server.close();
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}