Building OpenJDK and submitting a solution on a feature request with the Bulgarian Java User Group

So yesterday was a memorable day.

We gathered the Bulgarian Java User Group and, as a hands-on-lab, in 3 hours we created a pretty complex patch on a open issue in the JDK Bug System. We plan to submit a webrev patch after we polish the code and supply better tests.

We've been playing with the OpenJDK code for quite some time. We have setup an easily distributable virtual machine (actually two virtual machines - fedora and ubuntu) that can be found here:
http://bgjug.sty.bz
They have everything in there with clear instructions on how to build the code and start IntelliJ IDEA as the IDE.

The issue is this one:
https://bugs.openjdk.java.net/browse/JDK-5050783
That has been a request for quite some time. Apache Commons Lang even has an utility method.

Here are the slides of the hackaton:
http://www.slideshare.net/IvanIvanov138/first-adoption-hackathon
And here are the instructions:
http://bgjug.sty.bz/bgjug/OpenJDK-hol.pdf

We even had some beer:
IMG_20141211_203819

The patch included a pretty heated discussion on whether we should use the Apache's Commons Lang approach:

public static String getStackTrace(Throwable throwable) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw, true);
    throwable.printStackTrace(pw);
    return sw.getBuffer().toString();
}

or we should rewrite some private classes inside java.lang.Throwable.

Here's the updated Throwable code:
First we added a method:

/**
 * Returns string representation of this throwable and it's backtrace.
 *
 * @return string representation of this {@code Throwable} and it's backtrace
 */
public String getStackTraceString() {
    final StringBuilder sb = new StringBuilder();
    printStackTrace(new WrappedStringBuilder(sb));
 
    return sb.toString();
}

We renamed the ill-named PrintStreamOrWriter to StackTraceFacade and added another implementation:

private static class WrappedStringBuilder extends  StackTraceFacade {
    private static final String NEW_LINE = System.getProperty("line.separator");
    private final StringBuilder builder;
 
    WrappedStringBuilder(StringBuilder builder) {
        this.builder = builder;
    }
 
    @Override
    Object lock() {
        return builder;
    }
 
    @Override
    void println(Object o) {
        builder.append(o).append(NEW_LINE);
    }
}

We decided to reimplement and change the private inner class, because the Commons Lang uses StringWriter that internally uses the StringBuffer which is synchronized and we don't want that, since we sync on an upper level.
Here's a small JTREG test we created:

import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
import java.lang.Throwable;
/*
 * @test
 * @bug 5050783
 * @summary Basic test of serialization of stack trace information
 * @author Bulgarian JUG
 * @run testng java.lang.Throwable.GetStackTraceString
 */
public class GetStackTraceString {
    @Test
    public void doTest() {
        try{
            double a =100/0;
        }catch (Throwable t){
            assertTrue(t.getStackTraceString().length()>0);
        }
    }
}

2 thoughts on “Building OpenJDK and submitting a solution on a feature request with the Bulgarian Java User Group”

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.