Monthly Archives: July 2016

Java 9: Convenience Factory Methods for Collections

If you are following the feature set to be included in Java 9, you may have noticed JEP 269: Convenience Factory Methods for Collections. According to the proposal, this feature is to “provide static factory methods on the collection interfaces that will create compact, unmodifiable collection instances. The API is deliberately kept minimal.”

The expert group discusses alternatives, and explains in particular : “The Google Guava libraries have a rich set of utilities for creating immutable collections, including a builder pattern, and for creating a wide variety of mutable collections. The Guava libraries are very useful and general but are perhaps overkill for inclusion into the Java SE Platform.” However, I would argue that if Guava is “very useful” and “general”, that makes it completely appropriate for inclusion in Java SE proper. But that’s just my opinion!

If you look at the Java 9 API for Set, one thing that may jump out at you is the plethora of “.of()” methods, such as this .of() method with 10 arguments. The argument for this (!) is that “While this introduces some clutter in the API, it avoids array allocation, initialization, and garbage collection overhead that is incurred by varargs calls.” So here is a real-world instance where there was an evaluation between clarity of API design vs performance considerations, and in this case, the performance considerations won.

Without any further ado, here is an example of the new API:

Set strings = Set.of("a", "b");

Reading the Set javadocs with all the .of() methods is a little confusing at first (as to why they did that) but the nice part is that the code as used reads quite nicely.

Enjoy your tidy new Sets!

Leave a comment

Filed under Java 9

Drawbacks of Sprint Zero, or, How To Do Just Enough Design Up Front

I read this article recently about drawbacks of sprint zero and thought it was highly relevant to us as Software Engineers. Please read this article then come back here and we can talk 🙂

There is a balance to be had between doing ALL design up front, NO design up front, and (as this article suggests) SOME design up front. I have seen all of these approaches, and it is admittedly tricky at times to pick the right balance. For new product development a design phase does seem to work well in my experience. And for existing product development I would say a healthy dose of “big picture thinking” is appropriate when designing the feature (perhaps at story grooming time) and an entire design phase might be a bit much at that point. Again, as with most things, I think the answer to the question of how much design to do up front is “It depends.”

How do you design your products? How much time do you spend designing your features and how do you know it’s the right amount of time? Let me know what you think!

Leave a comment

Filed under Software Engineering

Java 9 Migration

So Java 9 is coming out, and you are probably excited to try building and running your own software on it. As you start planning your migration, there are some things to consider. Here are some steps to migrating your code.

Find your inappropriate dependencies

If you are relying on Sun internal packages (like sun.misc.*), your code will break running on Java 9 because of new restrictions that effectively hide these classes. In theory  even updates to Java 6 or Java 7 could remove these classes because they are not part of the Java spec. Unlikely, yes, but possible. Even if you don’t depend on Sun internal packages yourself, if you have transitive dependencies on libraries that do, then they will break and you will break! You can review the compatibility of popular FOSS libraries (or add your own) on OpenJDK’s quality outreach page.

Later versions of 7 or 8 will give compiler warnings:

[WARNING] /path/to/some/UnsafeUsingClass.java:[79,15] sun.misc.Unsafe is internal proprietary API and may be removed in a future release

Also, Java 8 provides a program called “jdeps” to find these dependencies explicitly. To run the JDeps tool, just direct it towards your build artifacts with “jdeps -cp . -jdkinternals *.jar” It even helpfully tells you where to go to find replacements for your Unsafe reference!

Here I direct it towards one of my own open source projects with an artificially introduced reference to sun.misc.Unsafe:

jdeps -cp . -jdkinternals *.jar
zee-0.9.4-SNAPSHOT.jar -> /home/jay/opt/jdk1.8.0_92/jre/lib/rt.jar
   zee.engine.EquationProcessor (zee-0.9.4-SNAPSHOT.jar)
      -> sun.misc.Unsafe                                    JDK internal API (rt.jar)
. -> /home/jay/opt/jdk1.8.0_92/jre/lib/rt.jar
      -> sun.misc.Unsafe                                    JDK internal API (rt.jar)

Warning: JDK internal APIs are unsupported and private to JDK implementation that are
subject to be removed or changed incompatibly and could break your application.
Please modify your code to eliminate dependency on any JDK internal APIs.
For the most recent update on JDK internal API replacements, please check:
https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool

There’s also a JDEPS Maven Plugin (which does the same thing as jdeps)

Fix inappropriate dependencies where you can

If you find you do have a dependency on these internal classes, you can find the recommended replacements on the JDeps website. Each instance needs to be reviewed and handled on a case-by-case basis to ensure that the recommended fix works for your specific use case. This is really what you need to do long term.

Isolate inappropriate dependencies

If you are pressed for time (and aren’t we all?!) you can choose to manage the dependency by isolating it to ease a future transition. If you REALLY need to depend on an internal API, break it out into a library to enable you to evolve your code independently and make it clear where to change your dependencies.

Leverage Multi-Release Jar Files

Multi-Release Jar Files, a new feature in Java 9, lets you include multiple versions of a  class to be loaded depending on the version of the JVM loading the jar. Older JVM’s will just ignore the later versions of a class, but Java 9 and later JVM’s will recognize the format and use the later version of the class. You can use this to your advantage when migrating: leave your references to sun.misc.* in your existing code, fix them with new versions of your classes, and distribute your old classes and fixed classes together in the same JAR. This way Java 7 or 8  JVM’s can use your existing code as-is, and Java 9 JVM’s can use your fixed classes which are using Java 9 language features to replace the inappropriate dependencies which are now missing in Java 9. This approach eases the transition, especially for public libraries or distributable software where you don’t necessarily control the version of JVM running your code.

Conclusion

If you only remember one thing: JDEPS!

Leave a comment

Filed under Java 9

Java’s Anonymous Inner Classes: Proceed With Caution

Java’s anonymous inner classes can be useful, but you must take care when using them. In particular: A memory leak will occur if an instance of an inner class survives longer than its containing outer class because the inner class maintains a reference to its outer class.

This is not a merely academic concern, this comes up in Android development when we use inner classes to encapsulate and pass around some code, and instances of an outer class (Activities) can be constantly created and destroyed.

Concrete Example

Sometimes we want a quick Set with some elements, and can accomplish this with a one-liner:

Set<String> strings = new HashSet<String>() {{   add("a"); add("b");  }};

Admittedly there are better ways to accomplish this, but this construct is possible and is used from time to time. What is not obvious is that this is actually an instantiation of an anonymous inner class that maintains a reference to its enclosing class, and so is subject to the potential memory leak situation described above.

In full context, here is some code that may look innocent enough (contrived though it may be)

public class Application {

    public static void main(String[] args) throws IOException {

        List<Set<String>> stringList = new ArrayList<>();
        for(int i=0; i < 100; i++) {
            Generator gen = new Generator();
            stringList.add(gen.createStringsInnerClass());
        }
        
        System.out.print("press Enter to continue:");
        System.in.read();
    }

    public static class Generator {
        
        private byte[] lotsOfHiddenStuff = new byte[5_000_000];
        
        public Set<String> createStringsInnerClass() {
            Set<String> strings = new HashSet<String>() {{
                add("a"); add("b");
            }};
            return strings;
        }

        public Set<String> createStringsNormally() {
            Set<String> strings = new HashSet<String>();
            strings.add("a");
            strings.add("b");
            return strings;
        }
    }
}

Analyze This

If we run the above application and monitor it with jconsole, this is what we see:

inner class after gc

It is using over 500MB of memory! This is because the Sets maintain references to their outer classes (which themselves take up a lot of memory) and it is not obvious that the outer class instances are not being properly disposed of.

After switching to use Generator.createStringsNormally(), jconsole looks like this:

non inner class after gc

It is using just over 5MB, as we would hope!

Conclusion

Remember that a memory leak will occur if an instance of an inner class survives longer than its containing outer class. And maybe avoid the “{{ }}” construct because it kind of masks the anonymous-inner-class-ness of your code.

Leave a comment

Filed under Uncategorized