Category Archives: Services

News visible on Services landingpage.

Some notes on Tomcat connector performance

MyTimetable, Software development0 comments

In my last blog post, I mentioned that there is a performance difference between Tomcat's APR and BIO / default connector. Tomcat ships with 3 HTTP(s) connectors:

  • Blocking IO (org.apache.coyote.Http11Protocol): this is the default and most stable connector.
  • Non-blocking IO (org.apache.coyote.Http11NioProtocol): this is a non-blocking IO connector, which you will need for Comet/WebSockets and should offer slightly better performance in most cases.
  • APR (org.apache.coyote.Http11AprProtocol): this connector uses Apache Portable Runtime and OpenSSL instead of their Java counterparts. Because of this, performance is generally better, especially when using SSL.

To do a quick comparison of these connectors, I used ApacheBench and ran some simulated load tests (100k requests, 100 concurrent requests) on the various connectors. The page requested was a simple JSP that displayed the current date. Tomcat 7.0.26 ran on Windows (yeah, really, it can run on Windows), and to compare with the Apache HTTPD and PHP I also did a run on a simple PHP page displaying the current date on Apache 2.2.16 (on Linux). Tests were done using HTTP and HTTPS, with and without keep-alive. The results are by no means scientifically significant, but give a general idea on the performance differences. YMMV, so please run your own benchmarks on your own applications (and create a more intelligent test scenario, using for instance Apache JMeter).

ConnectorHTTPHTTP keep-aliveHTTPSHTTPS keep-alive
BIO7341148091424036
NIO381610257--
APR82141506224011121
Apache HTTPD8780158802364056

Numbers are in request per second, higher is better. Due to some ApacheBench bug I could not test NIO over HTTPS. Some conclusions we can draw from these results:

  • Apache Tomcat performs on a level comparable to Apache HTTPD. This is at least the case for dynamic requests, but I have seen similar results for static requests.
  • When using SSL: use keep-alive, unless you have a specific reason not to.
  • When using SSL on Tomcat: use APR.
  • Don't expect NIO to give a better performance than BIO out of the box. Benchmark, benchmark, benchmark.

SSL certificates and Apache Tomcat

MyTimetable, Software development0 comments

Apache Tomcat offers two options for SSL: Java (JSSE) and APR (OpenSSL). Both options require their own set of keys and certificates, and have their own advantages and disadvantages. JSSE generally uses a JKS (Java) keystore (although a PKCS11 or PKCS12 keystore is also possible), whereas the OpenSSL option uses a PEM encoded key and certificate. Performance of the OpenSSL/APR connector is better (more on that later in another post), but the default Java connector is easier to setup (since it is enabled out of the box).

Since I always seem to forgot the exact command lines to create a key, CSR and self-signed certificate, I thought it would be nice to make a blog post summing up all the options. In this post, keytool refers to the keytool program available in your Java JRE or JDK in the bin directory. The other option, openssl, is available either from the binary compile of the Tomcat Native connector (Windows), or from your usual OpenSSL install (Linux, BSD, etc.).

To create a key and certificate in JKS format, by default self-signed:

keytool -genkey -keysize 2048 -keyalg RSA -alias tomcat -keystore keystore.jks

Note the 'first and last name' asked by keytool refers to the Common Name and should be your domain name (FQDN).

To create a signing request (CSR) for the generated certificate:

keytool -certreq -alias tomcat -file signing_req.csr -keystore keystore.jks

Give this to your SSL provider to get a signed, browser-trusted key.

To import the signed key into the keychain, including the keychain of intermediate certificates (if required), put all the certificates in 1 file (first the chain, then your certicate), and import them into the keychain:

keytool -import -alias tomcat -file certificate.pem -keystore keystore.jks

Now you should be able to use the keystore in your Tomcat install with the default connector.

To generate a PEM encoded private key, for use with the APR/OpenSSL connector:

openssl genrsa -des3 -out key.pem 2048

To generate a self-signed certificate for a key:

openssl req -new -x509 -key key.pem -out cert.pem -days 3650

To generate a certificate signing request (CSR):

openssl req -new -key key.pem -out cert.csr

The resulting certificate and chain you get from your SSL provider is usually already in PEM format, and can be used directly without extra imports.

What if we want to switch from JSSE to OpenSSL (from JKS to PEM)? We have to convert the keystore to PKCS12 format using keytool, and then extract the key, certificate and chain in PEM format using OpenSSL:

keytool -importkeystore -srckeystore keystore.jks -destkeystore intermediate.p12 -deststoretype PKCS12
openssl pkcs12 -in intermediate.p12 -nocerts -out  key.pem
openssl pkcs12 -in intermediate.p12 -clcerts -out cert.pem
openssl pkcs12 -in intermediate.p12 -cacerts -out chain.pem

I did not include any -nodes option in any of the commands, because usually it doesn't hurt to have your private key encrypted (you just have to enter the same password in the Tomcat config). About that Tomcat config, here are the required Connector elements for JSSE and OpenSSL/APR based config:

<Connector
           port="443" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           keystoreFile="path to keystore file" keystorePass="my keystore password" />

<Connector
           port="443" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           SSLCertificateFile="cert.pem"
           SSLCertificateKeyFile="key.pem"
           SSLCertificateChainFile="chain.pem"
           SSLPassword="certificate password" />

Querying Active Directory from Java using ADSI

Software development0 comments

In order to query a user's Active Directory properties from a Java application, we have a couple of possibilities. The most obvious option is to directly query using an LDAP connection through JNDI. Since Active Directory, by default, does not support anonymous binds, this requires a user account in the AD domain, storing/maintaining the user account in the application configuration, and a simple or Kerberos bind on the LDAP connection. All doable, but why not use the computer's domain credentials (assuming the computer is part of the AD domain)?

To use the computer's domain credentials (and not require any configuration of credentials in the application itself), we can use the Active Directory Service Interface (ADSI), which is a set of COM interfaces, accessible using ActiveX Data Objects (ADO). For this, we need to use JNI and Jacob (Java - Com bridge), for which the documentation is quite poor. To help you out, here is some code and the right dependencies.

First of all, include the following dependencies in your project (Gradle style syntax):

dependencies {
    // Jacob and accompanying wrappers (from own at http://www.eveoh.nl/files/maven2/)
    compile 'net.sf.jacob-project:jacob:1.15-M4'
    compile 'net.sf.jacob-project:jacob-ado-wrappers:1.0' // ADO wrappers, available from the Jacob source package, under GPLv3, repacked to nl.eveoh.jacob.ado namespace
}

A small example to retrieve the employeeNumber attribute from the current AD domain:

import nl.eveoh.jacob.ado.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class MyClass {

    private String getEmployeeNumber(String username) {
        try {
            ComThread.InitMTA(); // Init a multithread environment for COM, and close it afterwards to release all COM objects

            Connection conn = new Connection(); // Create an ADO connection to an ADSI object
            conn.setProvider("ADsDSOObject");
            conn.Open();

            Command command = new Command();
            command.setActiveConnection(conn);
            command.setCommandType(CommandTypeEnum.adCmdText);

            ActiveXComponent ax = new ActiveXComponent("LDAP://RootDSE"); // Get the default naming context for the LDAP query
            Variant v = Dispatch.call(ax, "Get", "defaultNamingContext");
            String dnc = v.toString();

            // Create the LDAP query and retrieve the result
            String ldapStr = "<LDAP://" + dnc + ">;(&(objectClass=user)(samAccountName=" + username
                    + "));employeeNumber;subtree";
            command.setCommandText(ldapStr);

            Recordset rs = command.Execute();
            Fields fs = rs.getFields();

            if (rs.getEOF()) {
                return null;
            }

            rs.MoveFirst();
            return fs.getItem(0).getValue().toString();
        }
        finally {
            ComThread.Release();
        }
    }

}
Drop me a mail if you have any questions or remarks!

Using Google Web Toolkit with Gradle

MyTimetable, Software development0 comments

Recently, we switched to Gradle as build tool of MyTimetable. Previously, we have been using Ant. While Ant certainly is a good build tool (Gradle uses Ant internally), it lacks declarative dependency management. To introduce declarative dependency management we have considered a couple of options: Ivy (with Ant), Maven or Gradle. In the end we went with Gradle, because it offers the most flexibility with the least amount of work involved. Maven leads to an XML/plugin hell for certain custom scenarios, and Ivy/Ant lacks good multi-project support (sure you can have multiple projects with Ivy/Ant, but you have to do all the hard work yourself).

We are currently using a custom build of Gradle 1.0-milestone-7 (with a fix for GRADLE-1881, available at GitHub or as binary compile). Together with STS's quite cool Gradle support, this gives us everything we need.

In the MyTimetable project we make extensive use of the Google Web Toolkit (GWT) for the client-side interface. When deploying to production, GWT requires a compile, where the client-side Java code is compiled to Javascript. Gradle does not provide out-of-the-box support for this compile, but it's as simple as calling the right Java program with the right arguments. There is also a complete Gradle GWT plugin available, but it's still work-in-progress and supports more than we need (like the GWT dev mode), so we decided to do it ourselves in Gradle. The following dependencies are necessary for GWT, include them in your gradle.build:

dependencies {
    // Compile GWT libs, needed for gwtCompile and the javaCompile
    // Also includes the servlet-api
    providedCompile 'com.google.gwt:gwt-user:2.4.0'
    providedCompile 'com.google.gwt:gwt-dev:2.4.0'
    
    // Needed for GWT compile and at runtime for RequestBuilder
    // Specify two artifacts as workaround for GRADLE-1934
    compile('javax.validation:validation-api:1.0.0.GA') { 
        artifact {
            name = 'validation-api'
            type = 'jar'
        }
        artifact {
            name = 'validation-api'
            type = 'jar'
            classifier = 'sources'
        }
    }
    
    // Runtime GWT libraries, should be included in WAR
    runtime 'com.google.gwt:gwt-servlet:2.4.0'
    runtime 'org.json:json:20090211'
}

In order to compile the GWT code to Javascript, we introduce an compileGwt Gradle task and let the war task depend on this task:

task compileGwt (dependsOn: classes, type: JavaExec) {
    buildDir = "${project.buildDir}/gwt"
    extraDir = "${project.buildDir}/extra"
    
    inputs.source sourceSets.main.java.srcDirs
    inputs.dir sourceSets.main.output.resourcesDir
    outputs.dir buildDir
    
    // Workaround for incremental build (GRADLE-1483)
    outputs.upToDateSpec = new org.gradle.api.specs.AndSpec()
    
    doFirst {
        file(buildDir).mkdirs()
    }
    
    main = 'com.google.gwt.dev.Compiler'
    
    classpath {
        [
            sourceSets.main.java.srcDirs,           // Java source
            sourceSets.main.output.resourcesDir,    // Generated resources
            sourceSets.main.output.classesDir,      // Generated classes
            sourceSets.main.compileClasspath,       // Deps
        ]   
    }
    
    args =
        [
            'nl.eveoh.scheduleviewer.Scheduleviewer', // Your GWT module
            '-war', buildDir,
            '-logLevel', 'INFO',
            '-localWorkers', '2',
            '-compileReport', 
            '-extra', extraDir,
            // '-draftCompile' // Speeds up compile with 25%
        ]
        
    maxHeapSize = '256M'
}

war.dependsOn compileGwt
war {
    from compileGwt.buildDir
}

The compileGwt task will be called automatically and the contents will be included in the generated war file. Also the GWT compile we only be run if the contents of the class or resource files have changed. And in case you use the Eclipse plugin, the right nature, buildcommand and classpath can be added automatically by the Eclipse task:

eclipse {
    project {
        natures 'com.google.gwt.eclipse.core.gwtNature'
        buildCommand 'com.google.gdt.eclipse.core.webAppProjectValidator'
        buildCommand 'com.google.gwt.eclipse.core.gwtProjectValidator'        
    }
    classpath {
        containers 'com.google.gwt.eclipse.core.GWT_CONTAINER'
    }
}

I hope this info is helpful, let us know if you have any suggestions, remarks or problems. Happy Gradling!

MyTimetable usability study

Featured, Frontpage, MyTimetable, News, Software development0 comments

Eveoh is looking for (upcoming) students and teachers of Delft University of Technology to participate in a usability study of timetable interface MyTimetable. The purpose of this study is to improve MyTimetable to fit the end-user requirements.

Continue Reading

XCal output with iCal4j

MyTimetable, Software development0 comments

One of our customers asked us to implement an xCal export in MyTimetable to link their upcoming mobile platform to students' schedules. xCal is basically iCalender, but in an XML format.

For the iCalendar export of MyTimetable we use the great open source Java library iCal4j. This library provides a complete iCalendar object model and the ability to verify and write iCalendar files. Unfortunately, the iCalendar export is hard coded into the model, but it is possible to create your own outputter.

We took the liberty to implement an XmlOutputter, using StAX to generate the XML. Since we wanted to keep the code simple and easily distributable, we chose to keep all the logic in the XmlOutputter, without depending on any Java-to-XML mapping frameworks. Software engineering wise nicer solutions may be possible. Another problem is that the iCalendar data value type of components cannot be easily retrieved from the iCal4j object model (since it is not necessary for the usual iCalendar export), so that information is hard coded into the XmlOutputter.

Source of the XmlOutputter is available at http://www.eveoh.nl/files/XmlOutputter.java and can be freely used (public domain). Since we do not use every component type, we cannot guarantee all possible options work correctly. Let us know if you have any suggestions.

Eveoh introduces new website

Services, Featured, News, Products0 comments

After several weeks of development Eveoh introduces its new website. The new website should give a clearer overview of our products and services.

Continue Reading