Java remote debugging JVM options

Java 5, 6, 7 and newer

The Java™ Platform Debugger Architecture (JPDA) supports certain JVM invocation options.

Usually this boils down to:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=y

This will cause your JVM process to execute but wait (suspend=y) and listen for a socket connection from a remote debugging client on a free port (which it will write to stdout. The suspend=y option is especially useful if you need to debug code that runs during the start-up phase of your application.

If you don’t want the process to do the initial waiting, then use suspend=n.

Java 1.4

If you are for some terrible reason stuck on Java 1.4, then you must use the older approach like this:

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n

Tomcat

To enabled remote debugging for a Apache Tomcat on Windows, create bin\setenv.bat in your Tomcat installation, with this content:

set "CATALINA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n"

Network port

If you use the settings above, i.e. server=y and no “address” option, JPDA will pick a free port and write a message about this to stdout. Look for something like this:

Listening for transport dt_socket at address: [PORT]

Intellij configuration

Add a debug configuration via Run menu:

Open Source games using libgdx

There are these demos.

And I found a list at the bottom of the main libgdx documentation page and used it as a startting point for the list below. I haven’t verified yet whether their respective licensing is covered by the OSI Open source definition.

I am actively maintaining this list, so feel free to send me additions or corrections:

I have also asked for a more comprehensive list on the libgdx forum and on libgdx lead developer Mario Zechner’s blog.

Create single copyright holder, GPL licensed source code repository

I sometimes want to create a source code repository and build process for a GPL licensed software project, where the sole copyright holder (“owner”) is a single legal entity, like a company or a foundation.

This is how I do it:

  • Link to the license from README.md (e.g. the Free Software Foundation’s GPL, version 2)
  • At top of each source file: Copyright notice, license statement, warranty disclaimer
  • Include a plain-text copy of the full license in the root of your distributable package(s)
  • In the README.md, indicate that the project mandates copyright assignment
  • Define the legal agreement process between code contributors and the project owner

The GPL was chosen for its strong copyleft nature and combined with the sole copyright holder approach to enable dual licensing business models.

On sites like github, the code contribution itself is usually done by pull request. The legal agreement process between code contributor and project owner should be complete before the pull request is accepted.

I am not yet sure how to best automate updating the year range in the copyright notice, probably at commit time.

Using libgdx for cross-platform app development

I am looking for a framework that allows me to develop modern apps (mobile, web, desktop) all from one Java codebase. I prefer Java because I know it very well, it is already cross-platform and a statically typed language that allows IntelliJ, Eclipse and Netbeans to be better than any dynamically typed scripting language editor could ever be.

Currently my favorite is libgdx. I am planning to use it with IntelliJ Community Edition and with Maven.

By using RoboVM, libgdx even supports iOS.

For user input (forms) libgdx provides the scene2d.ui widgets. I hope that will be sufficient for most of my UIs. Now I just have to get OpenGL to work on my Linux box …

Java map comparison with detailed error messages using Guava

When you compare two Java maps that are supposed to be equal, i.e. contain the same name/value pairs, you might want to give some details about potential mismatches, for example in your log output.

The Guava library from Google provides a convenient tool for that, namely the class com.google.common.collect.MapDifference.

In the sample code below I have implemented a simple utitily method that compares two maps and logs detailed error messages if they are not equal.

This code is also the first item in my guava-based github project.

Maven dependencies

Put this into pom.xml :

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>16.0</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.5</version>
</dependency>

You will also need an slf4j implementation, like logback. For testing, we can use this :

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.5</version>
</dependency>

And for the JUnit tests further below you will need this :

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.10</version>
    <scope>test</scope>
</dependency>

Java class

Save this as src/main/java/net/doepner/util/MapDiffUtil.java :

package net.doepner.util;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;

import static com.google.common.collect.MapDifference.ValueDifference;

/**
 * Map comparison with detailed log messages
 */
public class MapDiffUtil {

    private static final Logger log =
        LoggerFactory.getLogger(MapDiffUtil.class);

    public static <K, V> boolean validateEqual(
               Map<K, V> map1, Map<K, V> map2,
               String map1Name, String map2Name) {

        final MapDifference<K, V> diff = Maps.difference(map1, map2);

        if (diff.areEqual()) {
            log.info("Maps '{}' and '{}' contain exactly the same "
                   + "name/value pairs", map1Name, map2Name);
            return true;

        } else {
            logKeys(diff.entriesOnlyOnLeft(), map1Name, map2Name);
            logKeys(diff.entriesOnlyOnRight(), map2Name, map1Name);
            logEntries(diff.entriesDiffering(), map1Name, map2Name);
            return false;
        }
    }

    private static <K, V> void logKeys(
                Map<K, V> mapSubset, String n1, String n2) {
        if (not(mapSubset.isEmpty())) {
            log.error("Keys found in {} but not in {}: {}",
                n1, n2, mapSubset.keySet());
        }
    }

    private static <K, V> void logEntries(
                Map<K, ValueDifference<V>> differing, 
                String n1, String n2) {
        if (not(differing.isEmpty())) {
            log.error("Differing values found {key={}-value,{}-value}: {}",
                        n1, n2, differing);
        }
    }

    private static boolean not(boolean b) {
        return !b;
    }
}

Unit tests

Save this as src/main/java/net/doepner/util/MapDiffUtilTest.java :

package net.doepner.util;

import java.util.HashMap;
import java.util.Map;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * Tests MapDiffUtil
 */
public class MapDiffUtilTest {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Rule
    public TestName testName = new TestName();

    @Before
    public void logTestName() {
        log.info("Executing {}", testName.getMethodName());
    }

    @Test
    public void testEqual() {
        final Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("A", 1);
        map1.put("B", 2);

        final Map<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("B", 2);
        map2.put("A", 1);

        assertTrue("Maps should be equal", MapDiffUtil.validateEqual(
            map1, map2, "map1", "map2"));
    }

    @Test
    public void testSubset() {
        final Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("A", 1);

        final Map<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("B", 2);
        map2.put("A", 1);

        assertFalse("Maps should be unequal", MapDiffUtil.validateEqual(
            map1, map2, "map1", "map2"));

    }

    @Test
    public void testSeparate() {
        final Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("A", 1);

        final Map<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("B", 2);

        assertFalse("Maps should be unequal", MapDiffUtil.validateEqual(
            map1, map2, "map1", "map2"));
    }

    @Test
    public void testMismatches() {
        final Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("A", 1);
        map1.put("B", 2);

        final Map<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("B", 20);
        map2.put("C", 3);

        assertFalse("Maps should be unequal", MapDiffUtil.validateEqual(
            map1, map2, "map1", "map2"));

    }
}

Minimal Debian VM upgraded to wheezy / Jenkins with OpenJDK 7

I have upgraded my minimal Debian VM to current Debian stable (“wheezy”). It comes in OVA format which is deployable to Virtualbox or VMware.

The Debian system JDK, i.e. the location of java, javac, etc. commands in the PATH, is still OpenJDK 6 because that is the default-jdk on wheezy and the Jenkins deb packages from jenkins-ci.org depend on it. In particular this means that the Tomcat / Jenkins process itself is executed by OpenJDK 6.

But my Jenkins installer now also installs OpenJDK 7 and pre-configures it as the default JDK for Jenkins jobs. That means you can now use this Jenkins instance to build your Java 7 projects, as well as older Java projects.

Please follow the step-by-step installation instructions if you want to use the VM. It consists completely of Free / Open Source software. I provide it for download “as is” without any warranty of any kind.

Lazy logging of Java collections content

Sometimes you might want to include Java collections content in a log message. But standard Java collections do not provide a useful toString() implementation. So developers often use a helper method like this:

    /** 
     * @param collection A collection 
     * @return A string listing all collection items 
     */ 
    public static String toContentString(Collection<?> collection) { 
        return Arrays.toString(collection.toArray()); 
    } 

Then in typical slf4j log output code you might have something like this:

log.debug("Processing list: {}", toContentString(list));

But if list is long, then this code will cause unnecessary overhead in your application whenever it runs at a log level that does not actually log debug messages.

A simple solution for this is to use a wrapper object instead:

log.debug("Processing list: {}", toStringWrapper(list));

A simple toStringWrapper(..) implementation could be this:

/** 
     * Provides a wrapper object that can be used for logging of 
     * collection content 
     * 
     * @param collection A collection 
     * @return A wrapper toString() implementation listing all 
     *         collection items 
     */ 
    public static Object toStringWrapper(Collection<?> collection) { 
        return new Object() { 
            @Override 
            public String toString() { 
                return toContentString(collection); 
            } 
        }; 
    } 

This postpones the String generation until slf4j actually calls toString() on the log message parameter to substitute it for the ‘{}’ placeholder. And this substitution only happens if the log level actually requires it, i.e. less cpu cycles wasted on unused log message parameters.

My current IntelliJ code inspections profile for Java projects

I recently exported my IntelliJ code inspections profile for Java projects from IntelliJ Community Edition to share it with whoever might be interested.

These highly customized code inspections are based on industry standards like the official Java code conventions, various best practices from the Java community and my experience over many years as Java developer and team lead, trying to ensure code quality and maintainability.

Feel free to download and save it as a local XML file. Then you can import it into any of your IntelliJ projects via Analyze – Inspect Code – Inspection profile – […] button – Import:

Transparently improve Java 7 mime-type recognition with Apache Tika

Java 7 comes with the method java.nio.file.Files#probeContentType(path) to determine the content type of a file at the given path. It returns a mime type identifier. The implementation actually looks at the file content and inspects so-called “magic” byte sequences, which is more reliable than just trusting filename extensions.

However, the default implementation included in Java 7 seems to be platform dependent and not very complete. For example, for me it did not even recognize an mp3 file as audio/mpeg. Fortunately, the Open Source library Apache Tika provides more comprehensive mime type detection and seems to be platform independent.

As shown below, you can register a simple Tika based FileTypeDetector implementation with the Java Service Provider Interface (SPI) to transparently enhance the behaviour of java.nio.file.Files#probeContentType(path). As soon as the resulting jar is in your classpath, the SPI mechanism wil pick up our implementation class and Files.probeContentType(..) will automatically use it behind the scenes.

Maven dependency

        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-core</artifactId>
            <version>1.4</version>
        </dependency>

FileTypeDetector.java

package net.doepner.file;

import java.io.IOException;
import java.nio.file.Path;

import org.apache.tika.Tika;

/**
 * Detects the mime type of files (ideally based on marker in file content)
 */
public class FileTypeDetector extends java.nio.file.spi.FileTypeDetector {

    private final Tika tika = new Tika();

    @Override
    public String probeContentType(Path path) throws IOException {
        return tika.detect(path.toFile());
    }
}

Service Provider registration

To register the implementation with the Java Service Provider Interface (SPI), you need to have a plaintext file /META-INF/services/java.nio.file.spi.FileTypeDetector in the same jar that contains the class net.doepner.file.FileTypeDetector. The text file contains just one line with the fully qualified name of the implementing class:

net.doepner.file.FileTypeDetector

With Maven, you simply create the file src/main/resources/META-INF/services/java.nio.file.spi.FileTypeDetector containing the line shown above.

See the ServiceLoader documentation for details about Java SPI.