Showing posts with label bndtools. Show all posts
Showing posts with label bndtools. Show all posts

Friday, April 04, 2014

Java 8, bnd and references to compile-time constants

Java 8 was recently released and I wanted to test it out with the OSGi build. I installed JDK 8 on my Mac, pointed JAVA_HOME at it and started a clean build of OSGi. After the build completed, I ran the Core Compliance Tests to verify the build. Unfortunately several of the tests were now failing.

In order to diagnose the issue, I compared it to the same build built with JDK 7. The JDK 7 build passed all the tests running under JDK 7 or JDK 8. The JDK 8 build failed the same tests running under JDK 7 or JDK 8. So the issue was in the building with JDK 8 not the running under JDK 8. The failure was that one of the test bundles was failing to resolve. This was caused by an import for a  package that was not exported by any bundle. When building with JDK 8, bnd added a package to the test bundle's Import-Package statement that is not present in the Import-Package statement when building with JDK 7.

Digging further into the test bundle, the only reference to that package was to a static final String constant. During compilation, javac must copy the referenced string into the compiled class since the final String is a compile-time constant and thus the referenced field is not referenced at runtime.

So in the example code:
public class Referencer {
    public static void main(String[] args) {
        System.out.println(Constant.hello);
    }
}
class Constant {
    static final String    hello = "Hello, World!";
}
the class file for Referencer has its own copy of the string "Hello, World!" and does not access Constant at runtime to obtain the string to print it out. In fact, the Referencer class file compiled by JDK 7 has no references to Constant.

But when compiling with JDK 8, javac adds a constant pool entry for the class holding the referenced constant even though this class it not reference at runtime by the compiled class. So for the example above, the Referencer class file now has a constant pool entry for the Constant class.

During the building of a bundle, bnd analyzes the class files in the bundle to find class references to generate the necessary Import-Package statement.  So the presence of this new constant pool entry for the constant holding class caused bnd to add the package of that class to the Import-Package statement. bnd assumed that all class entries in the constant pool were runtime references.

An email conversation with Alex Buckley, JLS spec lead, confirmed that this new behavior for javac in JDK 8 is intentional. javac is now adding compile-time dependencies to the constant pool to support compile-time dependency analysis using class files.

This means that bnd's assumption that all class entries in the constant pool were runtime references is no longer valid for classes compiled by JDK 8. So Peter Kriens is making fixes to bnd for the 2.3 release to do deeper analysis so only runtime references to classes will result in their packages being added to the Import-Package statement. Compile-time only dependencies wont result in their packages being added to the Import-Package statement. So stay tuned for bnd 2.3 if you plan on using JDK 8 to build your bundles.

This also means that anyone doing bytecode analysis for runtime dependencies of class files needs to be aware that the constant pool can now also contain compile-time only dependencies.

Friday, December 09, 2011

Bndtools at the OSGi Alliance

The OSGi Alliance has been using bnd for a long time in the OSGi build. bnd is used by the ant build to create the bundles and execute the compliance tests as part of our continuous builds. It is also installed in Eclipse as an IDE plugin to provide IDE support for compilation classpath and test execution by OSGi members working in the Expert Groups.

Recently Bndtools development has been underway to create a better integration of bnd with the Eclipse IDE for bundle development. Bndtools 1.0 was just released and is available for installation into the Eclipse IDE as a replacement for bnd's Eclipse IDE support.

Since the OSGi Alliance has long used bnd, we already had the bnd infrastructure in place for our build. All that we needed to do to start using Bndtools was to update each project's .project file (using the Add Bndtools Project Nature menu item). This simple change then enabled Bndtools to manage the project within the Eclipse IDE. The OSGi Alliance will continue to use bnd in the ant build, but for our Eclipse IDE use we have moved to Bndtools.

Thanks to Neil Bartlett, Peter Kriens and the other bnd and Bndtools contributors for their hard work in making bnd and Bndtools the premier tooling for OSGi development.