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();
}
}
}