tag:blogger.com,1999:blog-32370925292993075042024-03-19T08:28:40.580+01:00My daily JavaThis blog is concerned with the Java platform, its languages and application frameworks.Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.comBlogger21125tag:blogger.com,1999:blog-3237092529299307504.post-66899594201378905402022-02-18T10:39:00.004+01:002022-02-18T14:38:15.694+01:00Using Byte Buddy for proxy creationWith the increasing adoption of Java 17 and its strict encapsulation, several unmaintained libraries that rely on internal JVM APIs have stopped working. One of these libraries is cglib, the <i>code generation library</i>, which allows to create and load proxy classes during the runtime of a JVM process. And while there are alternatives to cglib that support Java 17, migration is not always straight-forward. To ease such migration, this article discusses how <a href="https://bytebuddy.net">Byte Buddy</a> can be used for proxy creation and what concept changes need to be considered during a migration.<br/>
<br/>
<h4>General concept</h4>
<br/>
Other than cglib, Byte Buddy does not offer an API that is dedicated to the creation of proxies. Instead, Byte Buddy offers a generic API for defining classes. While this might feel less convenient at first, it typically aids the evolution of existing code over time since the proxy class generation can be adjusted without constraints.<br/>
<br/>
With Byte Buddy’s general API, a proxy is therefore created by defining a subclass of the targeted class, where all methods are overridden. Since Java methods are dispatched virtually, these overridden methods will be invoked instead of the original methods. In essence, cglib defines a proxy just like that.<br/>
<br/>
As an example, consider creating a proxy of the following Sample class:<br/>
<br/>
<pre class="brush: java">public class Sample {
public String hello() {
return "Hello World!";
}
}</pre>
<br/>
This Sample class can be proxied with Byte Buddy by overriding the <i>hello</i> method. A simple way of implementing this override is by using a <code>MethodDelegation</code>. A method delegation requires a delegation target, typically a class that defines a single static method. To interact with the overridden method, the method declares parameters which are annotated with the expected behavior. As an example, consider the following delegation target which mimics the parameters of cglib’s <code>MethodInterceptor</code>:<br/>
<br/>
<pre class="brush: java">public class Interceptor {
@RuntimeType
public static Object intercept(@This Object self,
@Origin Method method,
@AllArguments Object[] args,
@SuperMethod Method superMethod) throws Throwable {
return superMethod.invoke(self, args);
}
}</pre>
<br/>
As the annotations’ names suggest, the method accepts the intercepted <code>This</code> instance, a description of the <code>Origin</code> method, <code>AllArguments</code> to the methods in form of an array, and a proxy to conduct a <code>SuperCall</code> to the original method implementation. With the above implementation, the interception simply invokes the original code which replicates the unproxied behavior. The method itself returns a <code>RuntimeType</code> as the returned value is cast to the actual return type which must be a <code>String</code>. If any other instance was returned, a <code>ClassCastException</code> would occur, just as with cglib.<br/>
<br/>
With this <code>Interceptor</code> in place, Byte Buddy can create the proxy with only a few lines of code:<br/>
<br/>
<pre class="brush: java">Class<?> type = new ByteBuddy()
.subclass(Sample.class)
.method(ElementMatchers.any()).intercept(MethodDelegation.to(Interceptor.class))
.make()
.load(Sample.class.getClassLoader())
.getLoaded();</pre>
<br>
The resulting class can now be instantiated using the reflection API. By default, Byte Buddy mimics all constructors that the super class is declaring. In the above case, a default constructor will be made available as <code>Sample</code> also declares one.<br/>
<br/>
Note that Byte Buddy always requires a specification of the methods to intercept. If multiple matchers are specified, each their delegation target would be considered in the reverse order of their specification. If all methods should be intercepted, the any-matcher captures all methods. By default, Byte Buddy does however ignore the <code>Object::finalize</code> method. All other <code>Object</code> methods like <code>hashCode</code>, <code>equals</code> or <code>toString</code> are proxied.<br/>
<br/>
<h4>Caching proxied classes</h4>
<br/>
With class creation and loading being expensive operations, cglib offers a built-in cache for its proxy classes. As key for this cache, cglib considers the shape of the proxy class and recognizes if it created a class with a compatible shape previously.<br/>
<br/>
While this is convenient, this cache can quickly turn into a leaky abstraction that is sensitive to minor changes. Also, the caching mechanism is performing rather poorly due to its ambitious implementation of recognizing shapes. For this reason, Byte Buddy rather offers an explicit TypeCache and requires its user to specify a mechanism for identifying a cache key. When proxying a single class, the proxied <code>Class</code> typically suffices as a key:<br/>
<br/>
<pre class="brush: java">TypeCache<Class<?>> cache = new TypeCache<>();
Class<?> type = cache.findOrInsert(Sample.class.getClassLoader(), Sample.class, () -> {
return new ByteBuddy()
.subclass(Sample.class)
.method(ElementMatchers.any()).intercept(MethodDelegation.to(Interceptor.class))
.make()
.load(Sample.class.getClassLoader())
.getLoaded();
});</pre>
<br/>
With this cache a new proxy class is only created if no proxy class was previously stored for <code>Sample</code>. As an optional, additional argument, a monitor object can be provided. This monitor is then locked during class creation to avoid that the same proxy is created concurrently by different threads. This can increase contention but avoids unnecessary class generation.<br/>
<br/>
If more complex caching is required, a dedicated library should of course be used instead of the cache that Byte Buddy offers.<br/>
<br/>
<h4>Abstract methods and default values</h4>
<br/>
Until now, we assumed that all proxied methods are implemented by the proxied class. But Byte Buddy - just as cglib - also intercepts abstract methods that do not offer a super method implementation. To support intercepting such methods, the previous interceptor must be adjusted, as it currently requires a super method proxy via its parameters. By setting a property for the SuperMethod annotation, the parameter can be considered as optional.<br/>
<br>
<pre class="brush: java">public class Interceptor {
@RuntimeType
public static Object intercept(@This Object self,
@Origin Method method,
@AllArguments Object[] args,
@SuperMethod(nullIfImpossible = true) Method superMethod,
@Empty Object defaultValue) throws Throwable {
if (superMethod == null) {
return defaultValue;
}
return superMethod.invoke(self, args);
}
}</pre>
In case of intercepting an abstract method, the proxy for the super method is set to null. Additionally, <code>Empty</code> injects a suitable null value for the intercepted method’s return type. For methods that return a reference type, this value will be <code>null</code>. For a primitive return type, the correct primitive zero is injected.<br/>
<br/>
<h4>Managing instance-specific interceptor state</h4>
<br/>
In the previous example, the interceptor method is static. In principle, method delegation can also delegate to an instance with a non-static method, but this would likely defeat the caching mechanism if the state would be specific for each created proxy.<br/>
<br/>
cglib’s cache works around this limitation, but cannot handle several corner cases where the cache might start failing after minor changes. Byte Buddy, on the other hand, relies on the user to manage the state explicitly, typically by adding a field via the <code>defineField</code> step, which can then be read by the interceptor:<br/>
<br/>
<pre class="brush: java">TypeCache<Class<?>> cache = new TypeCache<>();
Class<?> type = cache.findOrInsert(Sample.class.getClassLoader(), Sample.class, () -> {
return new ByteBuddy()
.subclass(Sample.class)
.defineField(InterceptorState.class, "state", Visibility.PUBLIC)
.method(ElementMatchers.any()).intercept(MethodDelegation.to(Interceptor.class))
.make()
.load(Sample.class.getClassLoader())
.getLoaded();
});</pre>
<br/>
With this changed definition, any proxy instance can contain a designated instance of <code>InterceptorState</code>. The value can then be set via reflection or via a method handle.<br/>
<br/>
Within the interceptor, this <code>InterceptorState</code> is accessible via an additional parameter with the <code>FieldValue</code> annotation which accepts the field’s name as its property. Doing so, the generated class itself remains stateless and can remain cached.<br/>
<br/>
<h4>Handling non-default constructors</h4>
<br/>
Byte Buddy creates valid, verifiable Java classes. As such, any class must invoke a constructor of its super class in its own constructors. For proxies, this can be inconvenient as a class without a default constructor might not be easily constructible. Some libraries like objenesis work around this limitation, but those libraries rely on JVM-internal API and their usage should be avoided.<br/>
<br/>
As mentioned before, Byte Buddy replicates all visible constructors of a proxied class by default. But this behavior can be adjusted by specifying a <code>ConstructorStrategy</code> as a second argument to <code>ByteBuddy::subclass</code>. For example, it is possible to use <code>ConstructorStrategy.ForDefaultConstructor</code> which creates a default constructor by invoking a super constructor with default arguments for all parameters. As an example, considering the below <code>ConstructorSample</code>, Byte Buddy can define a default constructor for the proxy which provides null as an argument to the proxied super class:<br/>
<br/>
<pre class="brush: java">public class ConstructorSample {
private final String value;
public ConstructorSample(String value) {
this.value = value;
}
public String hello() {
return "Hello " + value;
}
}</pre>
<br/>
The dynamic type builder is now created by:<br/>
<br/>
<pre class="brush: java">new ByteBuddy().subclass(
ConstructorSample.class,
new ConstructorStrategy.ForDefaultConstructor(ElementMatchers.takesArguments(String.class)));</pre>
<br/>
Note that this approach would result in the proxied method returning <code>Hello null</code> as a result and that this might cause an exception during a constructor’s invocation if null is not considered a valid argument.<br/>
<br/>
<h4>Class loading and modules</h4>
<br/>
When Byte Buddy defines a class, it does not yet consider how this class will be loaded. Without any specification, Byte Buddy loads a proxy in a dedicated class loader that is a child of the class loader that is provided to the load method. While this is often convenient, creating a class loader is however an expensive operation which should be avoided, if possible. As a cheaper alternative, proxy classes should be injected into existing class loaders; normally into the one that loaded the class that is being proxied.<br/>
<br/>
With Java 9, the JVM introduced an official API for class injection via <code>MethodHandles.Lookup</code>, and of course Byte Buddy supports this API. If Byte Buddy is however used on Java 8 or earlier, this strategy is not yet available. Typically, users fall back to using <code>sun.misc.Unsafe</code>, a JVM-internal API. As Java 8 does not yet encapsulate internal API and since <code>sun.misc.Unsafe</code> is available on most JVM implementations, this fallback does not normally render a problem.<br/>
<br/>
A caveat of using <code>MethodHandles.Lookup</code> is its call site sensitivity. If Java modules are used, the instance must be created and provided by the module that owns the package of the proxied class. Therefore, the instance of <code>MethodHandles.Lookup</code> must be provided to Byte Buddy and cannot be created from within the library which represents a module of its own.<br/>
<br/>
Byte Buddy configures class loading behavior by instances of <code>ClassLoadingStrategy</code> which can be passed as a second argument to the load method. To support most JVMs, Byte Buddy already offers a convenience method that resolves the best available injection strategy for a given JVM via:<br/>
<br/>
<pre class="brush: java">ClassLoadingStrategy.UsingLookup.withFallback(() -> MethodHandles.lookup());</pre>
<br/>
With the above strategy, a method handle lookup is used if possible and internal API is only used as a fallback. Since the method handles lookup is resolved within a lambda, it also represents the context of the module that is using Byte Buddy, assuming that this is the right module to define the proxy class. Alternatively, this <code>Callable</code> has to be passed from the right place. If the module system is not used, however, the above approach is normally sufficient as all classes are likely located within the unnamed module of the same class loader.<br/>
<br/>
<h4>Avoiding runtime proxies with build-time instrumentation</h4>
<br/>
With a rising interest for Graal and AOT compilation of Java programs in general, the creation of runtime proxies has fallen somewhat out of fashion. Of course, when running a native program without a byte code-processing JVM, classes cannot be created during runtime. Fortunately, proxies can often be created during build time instead.<br/>
<br/>
For build-time code generation, Byte Buddy offers a Maven and a Gradle plugin which allow for the application of Plugin instances that manipulate and create classes before runtime. For other build tools, Byte Buddy also offers a <code>Plugin.Engine</code> as part of Byte Buddy which can be invoked directly. As a matter of fact, the byte-buddy artifact even contains a manifest that allows for using the jar file as an invokable of the plugin engine.<br/>
<br/>
To implement a plugin for creating proxies, the proxy creator needs to implement Byte Buddy’s <code>Plugin</code> and <code>Plugin.Factory</code> interfaces. A plugin specifies what classes to instrument and how the instrumentation should be applied. For an easy example, the following plugin creates a proxy for the <code>Sample</code> class and adds the name of this proxy as an assumed annotation <code>ProxyType</code> onto the <code>Sample</code> class:<br/>
<br/>
<pre class="brush: java">public class SamplePlugin implements Plugin, Plugin.Factory {
@Override
public boolean matches(TypeDescription type) {
return type.getName().equals("pkg.Simple");
}
@Override
public DynamicType.Builder<?> apply(DynamicType.Builder<?> builder,
TypeDescription typeDescription,
ClassFileLocator classFileLocator) {
DynamicType helper = new ByteBuddy()
.subclass(typeDescription)
.defineField(InterceptorState.class, "state", Visibility.PUBLIC)
.method(ElementMatchers.any()).intercept(MethodDelegation.to(Interceptor.class))
.make();
return builder
.require(helper)
.annotateType(AnnotationDescription.Builder.ofType(ProxyType.class)
.define("value", helper.getTypeDescription().getName())
.build());
}
@Override
public void close() { }
@Override
public Plugin make() { return this; }
}</pre>
<br/>
With the annotation in place, the runtime can now check for the existence of a build-time proxy and avoid code generation altogether in such a case:<br/>
<br/>
<pre class="brush: java">TypeCache<Class<?>> cache = new TypeCache<>();
Class<?> type = cache.findOrInsert(Sample.class.getClassLoader(), Sample.class, () -> {
ProxyType proxy = Sample.class.getAnnotation(ProxyType.class);
if (proxy != null) {
return proxy.value();
}
return new ByteBuddy()
.subclass(Sample.class)
.defineField(InterceptorState.class, "state", Visibility.PUBLIC)
.method(ElementMatchers.any()).intercept(MethodDelegation.to(Interceptor.class))
.make()
.load(Sample.class.getClassLoader())
.getLoaded();
});</pre>
<br/>
An advantage of this approach is that the usage of the build-time plugin remains entirely optional. This allows for faster builds that only execute tests but do not create artifacts, and allows users that do not intend to AOT-compile their code to run their applications without an explicit build setup.<br/>
<br/>
Note that a future version of Byte Buddy will likely make the use of Graal even easier by discovering and preparing runtime-generated classes when the Graal configuration agent is used. For performance reasons, using an explicit build tool is however expected to remain the most performant option. Do however note that this approach is somewhat restricted to classes of the compiled project since external dependencies are not processed by a build tool.<br/>
<br/>
<h4>Inline proxy code without subclasses</h4>
<br/>
With the above approach, the created proxies still require the use of reflection to create instances of the proxy. For an even more ambitious setup, Byte Buddy offers the <code>Advice</code> mechanism to change the code of classes directly. Advice is normally often used for the decoration of methods and a popular choice when developing Java agents. But it can also be used to emulate proxy behavior without creating a subclass.<br/>
<br/>
As an example, the following advice class records the execution time of a method by declaring actions that are to be performed prior to invoking a method as well as after it. <code>Advice</code> offers similar annotations to MethodDelegation, be careful to not confuse those annotations as they are declared by different packages.<br/>
<br/>
To emulate the previous behavior of the Interceptor, the following <code>Decorator</code> functions similarly to it. Note that the <code>Decorator</code> declares a set of proxies to recognize what instances are to be treated as proxies and which instances should function as if they were not proxied. Within the <code>OnMethodEnter</code> annotation, it is specified that the original code is skipped if a non-null value is returned.<br/>
<br/>
<pre class="brush: java">public class Decorator {
static final Set<Object> PROXIES = new HashSet<>();
@Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
public static Object enter(
@Advice.This Object self,
@Advice.Origin Method method,
@Advice.AllArguments Object[] arguments) throws Throwable {
if (PROXIES.contains(self)) {
return ProxyHandler.handle(self, method, arguments);
} else {
return null;
}
}
@Advice.OnMethodExit
public static void exit(
@Advice.Enter Object enter,
@Advice.Exit(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object returned) {
if (enter != null) {
returned = enter;
}
}
}</pre>
<br/>
With this code, the original method can be invoked by temporarily removing the instance from the proxy set within the <code>ProxyHandler</code>.<br/>
<br/>
<pre class="brush: java">Object returned;
Decorator.PROXIES.remove(self);
try {
returned = method.invoke(self, arguments);
} finally {
Decorator.PROXIES.add(self);
}</pre>
<br/>
Note that this is a naive approach which will fail if the proxy is used concurrently. If a proxy needs to be thread-safe, it is normally required to define a thread-local set that contains temporarily disabled proxies.<br/>
<br/>
Of course, it is not normally possible to apply this decoration during a JVMs runtime, but only at build-time, unless a Java agent is used. To still allow for a fallback-implementation, Byte Buddy does however allow for <code>Advice</code> being used as both decorator:<br/>
<br/>
<pre class="brush: java">new ByteBuddy().redefine(Sample.class)
.visit(Advice.to(Decorator.class).on(ElementMatchers.isMethod()))
.make();</pre>
<br/>
and as an interceptor for creating a subclass proxy:<br/>
<br/>
<pre class="brush: java">new ByteBuddy().subclass(Sample.class)
.method(ElementMatchers.isMethod())
.intercept(Advice.to(Decorator.class))
.make();</pre>
<br/>
In this case, a build-time plugin can avoid a subclass creation where this is necessary. For example, it allows for proxying final classes or methods, if this should be supported. At the same time, inline proxies cannot proxy native methods.<br/>
<br/>
<h4>Replacing other cglib utilities</h4>
<br/>
cglib contains a row of other class generation utilities besides the Enhancer. I have previously written <a href="http://mydailyjava.blogspot.com/2013/11/cglib-missing-manual.html">a summary of all of the library's capabilities</a> where those are described.<br/>
<br/>
The good news is that most of this functionality has become obsolete. Immutable beans are less useful today as it has become much more common to model immutable objects by for example records. And similarly other bean utilities have found better equivalents in today’s Java, especially since method and var handles have entered the stage. Especially cglib's <code>FastMethod</code> and <code>FastClass</code> utilities are no longer useful as reflection and method handles have passed the performance that is offered by these code generation tools.Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-86940969414746174612019-05-27T16:06:00.001+02:002019-05-27T16:06:36.736+02:00Jakarta EE without javax: the world won't end this time either<div dir="ltr" style="text-align: left;" trbidi="on">
If you missed the news, <a href="https://blogs.oracle.com/theaquarium/opening-up-java-ee">Oracle is donating the Java EE specification to the Eclipse foundation</a>. This decisions has followed a rather long period of hibernation in the specification process where people rightfully suspected a loss of strategic interest in Java EE by Oracle. At first, the decision to donate the specification was well-met by the Java EE and broader Java community. Without Oracle slowing down the process, those involved in Java EE could once again attempt to close up to non-standardized APIs. Until today, the donation process is however incomplete due to Oracle and the Eclipse foundation being in disagreement about several details of the donation being made.<br />
<br />
While overturning all intellectual property, Oracle was less generous when it comes to the use of its Java brand within the specification’s new home. Java EE does of course contain the name of the open-source, yet trademark-protected platform that is owned by Oracle. And this renders a problem in a legal context: if you grant a third party the use of your brand's name, you have yielded rights to restrict it in the future. To make things worse, you are potentially weakening your position in court when it comes to lawsuits regarding your brand. With the history of Oracle and Google arguing about Java licensing for years, one could therefore have anticipated that branding would be a difficult discussion point. And without pretending to know much about international trademark law, I was told by people more involved that "use it or lose it" is a good enough approximation for understanding the general motto of such disagreements. As a first result, the specification was therefore renamed from Java EE into Jakarta EE to avoid a clash of interests.<br />
<br />
The real shocker for the newly formed Jakarta EE community was however yet to come. After months of discussing formalities of the donation, the Eclipse foundation learned that it could neither assume ownership of the current javax namespace that hosts the APIs that are defined within Java EE. Instead, this namespace is now planned to be hibernated for all donated APIs. Any new API that will be created within the specification process of Jakarta EE is therefore supposed to be hosted within a new namespace to avoid infringing Oracle's trademark.<br />
<br />
At this point, it is important to clarify what this means. Jakarta EE and the Eclipse foundation are not prohibited of using the javax namespace or implementing its API. Neither will APIs that currently exist be deleted. But any API that is created or updated within the newly formed Jakarta EE specification process will need to live in a new namespace that is most likely imitating the one in existence but with jakarta as its prefix instead of javax. As an example, if a new method was to be added to the <code>javax.servlet.Servlet</code> interface, the next version of the servlet specification would need to publish a new interface named <code>jakarta.servlet.Servlet</code> instead of adding this method to the existing API.<br />
<br />
<h4>
I am not a Java EE user, why would I care?</h4>
<br />
Formally, the Java platform as most people know it is split into two parts. The first part being Java SE where all API is defined within packages that are prefixed with java. In addition to that, Java EE specifies e<b>x</b>tending APIs within the java<b>x</b> namespace. Those APIs do not imply a particular implementation but only define behavior that is implemented by different vendors of Java EE-compliant components.<br />
<br />
In this context, Java EE is a blanket term for several API specifications that are not dependent on one another. As an example, the Java messaging specification (JMS) defines an API for interacting with message queues whereas the Java servlet specification defines an API for dispatching calls to a web server. In practice, no Java EE application runtime that I know of implements the entirety of APIs that are defined within the Java EE specification process. And some Java frameworks even focus on only implementing a single specification. As an example, the Jetty web server only implements the Java servlet specification. Therefore, if you are using Jetty via Spring Boot, you are formally a user of Java EE even if you are not interacting with the specification directly or consider yourself a Java EE user.<br />
<br />
Despite this formal distinction, you have probably encountered Java EE and its javax namespace even if you only ever programmed vanilla Java without including any external dependencies. This is because of selected Java EE APIs being bundled with the standard image of the JVM. In addition to the API, the JVM also ships a default implementation of this API, to offer users the convenience of solving common tasks without any additional efforts. As an example, JAXP is a Java EE specification that defines an API for processing XML in Java. With XML-processing being such a common task, especially on the enterprise-oriented Java platform, its inclusion it was a reasonable choice. For JAXP, its assumed common usage is still factual today but other JVM-bundled Java EE specifications did not age equally well. As an example, SOAP messaging is no longer the first choice for most Java developers such that the JVM-bundled JAX-WS implementation has become dead weight for the majority of users. In order to cut down on the JVM footprint and with introducing the Java module system in Java 9, several Java EE APIs were moved to deprecated modules that are scheduled for removal in a future release. Of course, this does not imply that a module's API itself is deprecated. JAX-WS is still alive and actively used by many. But as a result of this module deprecation, JAX-WS needs to be added as an explicit dependency by those that want to continue using it in a future Java release.<br />
<br />
In our age of running microservices on virtualized hardware, a reduced JVM footprint has become an obvious goal of evolving the JVM. But removing Java EE API from the base JVM image has another advantage. By asking users to include an explicit dependency on Java EE API, upgrading the Java runtime and Java EE are no longer tied together. Until Java 8, managing such version interdependencies has always been tedious. This is especially true if you do not control the exact version of the JVM that you are deploying your applications to. Until Java 8, the JVM only allowed you to override an implicit Java EE dependency by placing a jar file into the JVM's extension folder. But this is of course problematic when you are sharing a JVM installation with other Java processes that would also be affected. Also, you are still required to have some control over the JVM installation being used. To remedy this problem, the Java module system does no longer resolve the deprecated Java EE modules by default what makes it possible to include an explicit version with the JVM despite the continued on-demand bundling while also offering a simple way of activating legacy compatibility.<br />
<br />
To make things even more complicated, a small subset of Java EE APIs grew into Java SE in a way that does not allow their simple separation. As an example, the JDBC specification is split into "client-side" and "server-side" requirements where the former bit formally belongs to Java SE whereas the latter is part of Java EE. This distinction comes from the original Java philosophy where one would use Java SE for user-facing desktop applications but Java EE for server applications that are used by multiple concurrent users. In this spirit, the JDBC Connection interface is for example defined in the java.sql package. After all, a desktop user might of course want to connect to a database. On the other side, the JDBC DataSource interface is defined in the javax.sql package as connection pooling was considered a requirement only for multi-threaded server applications. From today's perspective, this separation does of course no longer make much sense but the namespace and formal distinction remains even today.<br />
<br />
Of course, it would not be meaningful to have the JDBC API evolve separately within both Java SE that is managed by the OpenJDK project and by Jakarta EE that is now managed by the Eclipse foundation. Therefore, not all parts of the Java EE specification were donated to Eclipse such that the <code>javax.sql</code> namespace will be retained for the JDBC API that is now considered to be a part of only Java SE. <a href="https://github.com/eclipse-ee4j/jakartaee-platform/blob/master/namespace/unaffected-packages.adoc">Other examples of such API retention</a> are the JMX API which relies heavily on native JVM-support. And of course all other APIs that were always considered to be part of Java SE such as the Swing API that also ended up in the Java extension namespace will remain in their original packages.<br />
<br />
<h4>
What about backwards compatibility?</h4>
<br />
The important thing to keep in mind is that no currently existing javax API will disappear, neither today or in the future. Personally, I also expect the specifications that are now part of Jakarta EE to support the javax namespace for many years to come. As a matter of fact, dealing with multiple namespaces is nothing new to most Java EE implementations but has always been an important topic to deal with. The Hibernate library for example has already successfully completed a similar migration when gradually replacing its own annotations with those defined by the JPA specification. In another example, the Spring framework supports the Java EE CDI specification in parallel to its native annotations. Doing so, it is for example possible to request a bean injection by using either the <code>javax.inject.Inject</code> annotation or Spring's native <code>Autowired</code> annotation. Once the Inject annotation is transferred to the jakarta package, I would therefore expect the Spring framework to support both the Java EE and Jakarta EE namespace as I also expect it from other implementers of Java enterprise APIs.<br />
<br />
With Jakarta EE being the successor of Java EE, I would neither expect this support to be overly costly to implement or maintain as application server vendors can simply implement Jakarta EE wrapper classes that delegate to the now outdated Java EE API. For example, a Java EE servlet can internally be treated as a Jakarta EE servlet by defining a wrapper class similar to the following:<br />
<br />
<pre class="brush: java">public class LegacyServlet implements jakarta.servlet.Servlet {
private final javax.servlet.Servlet delegate;
public LegacyServlet(javax.servlet.Servlet delegate) {
this.delegate = delegate;
}
@Override
public void service(jakarta.servlet.ServletRequest req, jakarta.servlet.ServletResponse resp) {
delegate.service(new LegacyServletRequest(req), new LegacyServletResponse(resp));
}
}</pre>
<br />
This should be fairly simple if Jakarta EE targets (logical) backwards compatibility to the current specification and API. If this principle is adhered, this would also require users of the API to only update to the Jakarta namespace in case that they want to take new features into use what already requires code changes. I would therefore expect the changed namespace not to affect future Jakarta EE users too much but to mainly be the concern of those implementing its APIs. Looking back to other more fundamental changes to the Java platform in the past, this was also true when for example the Java module system was introduced which mostly concerned library and framework developers but rarely end users of Java.<br />
<br />
Of course, support for both namespaces will never be universal, especially not in the long run and therefore users of Java EE APIs will need to react to the transition eventually. Given that the specification retains binary compatibility of its API with the exclusion of the change in namespace prefix, I do however believe that porting software should be easy to overcome and should even be automatable. Any Java class references its imported types in each class file's constant pool. It would be trivial for a tool to patch all relevant type references in all constant pools of an artifact with the new jakarta prefix. Doing so, legacy users of Java EE could avoid source code changes for their applications under passive maintenance and only apply such changes after compilation, or even patch an artifact during deployment.<br />
<br />
<h4>What drives Oracle?</h4>
<br />
I am of course a software consultant and not an expert of international trademark jurisdiction. Neither do I have any insights into Oracle's decision making process. Therefore, please take this last section as an educated speculation mixed with my personal opinion rather than a summary of facts.<br />
<br />
Several voices in the Java community are currently accusing Oracle of acting against the interest of Java and its users by restricting the use of the javax namespace. There have also been <a href="https://www.eclipse.org/org/foundation/boardminutes/2019_03_26_Minutes.pdf">heated debates in the Eclipse foundation</a> to the point where it was suggested that the donation of Java EE in this way might be rejected due to its incompatibility with the goals and values of the organization.<br />
<br />
Given that this change does impose significant work on the users of Java, one can of course quickly arrive at this opinion. I can however not imagine that Oracle took this decision lightly. Oracle is and has been investing heavily in the Java platform – Java has rarely been as alive as it is today – but it has also changed its strategic orientation. To me, the idea that Oracle does “not care” about the Java community while making these investments simply does not fit.<br />
<br />
So what do I think motivated this decision? To me, the restriction has little to do with Java EE but is about Oracle protecting its interest in Java SE. At the end of the day, Oracle is investing in Java to turn a profit. And by allowing the use of its trademark, Oracle would be giving up a share of the control of its brand what sets this goal into jeopardy. Of course, Oracle is relying on Java for its own products and maintains it also for this reason. But at the same time the company attempts to create a strategic model that justifies the funding of the many hundred full-time and highly qualified employees that work on Java.<br />
<br />
Oracle is quite obviously pushing into selling cloud solutions and given the company's current dominance in runtimes and databases in addition to its deep pockets, I believe that their chances to gain significant market share in this field are better than many people anticipate. Another indication of Oracle planning with the success of the core platform are its investments into the <a href="https://www.graalvm.org">Graal VM</a> and its compiler which does of course also offer the Java language a much broader scope of application in resource-constrained environments as within containers.<br />
<br />
But while investing in certain areas, Oracle is surely also looking into ways of cutting costs and terminates ventures that are no longer of strategic interest or not sufficiently profitable. And while it saddens users – including myself – that a successful project team <a href="https://www.infoq.com/news/2018/06/open-source-jmc">like that of Java flight recorder is laid off</a>, it makes sense given that the vast majority of Java developers are not asking for such tooling. I believe that Java EE did neither fit into Oracle’s plans or cost profile for the platform and suffered a similar faith.<br />
<br />
In this light, Oracle probably considered a trade-off between giving up the specification versus donating it for other people to maintain. And while the choice to donate Java EE might seem to come without costs, Oracle is of course taking a risk by making this donation. By allowing competing organizations to continue their efforts in Java EE, these efforts might also strengthen their ability to compete against Oracle in the the Java SE segment. This is especially true with Red Head and IBM being among those organizations which are of course also competing in the market for cloud solutions. By protecting its branding rights, Oracle is simply aiming to reduce the risk that Java EE is weaponized by a competitor to fight for Java SE market share in the future. And to be fair, Oracle had offered a way for the Eclipse foundation to continue using the javax namespace. However, this would have required the foundation to restrict itsself to bundling its products with Java SE-certified implementations of the JVM rather than for example <a href="https://www.infoq.com/news/2018/03/OMR-OpenJ9">its own IBM-donated OpenJ9</a>. Doing so, Oracle would have retained sufficient control of its brand despite Eclipse's use of the javax namespace but at the same time, it is very understandable that signing such a broad agreement was not in the interest of the foundation either. It just was not meant to be and in this light one could even argue that Eclipse was the wrong choice for receiving the donation of Java EE in the first place.<br/>
<br/>
<h4>What comes next?</h4>
<br />
In the open source community, we discuss loud and often that our work is underfunded. And while the lacking profitability is a problem for individual developers hacking away their nights, it is of course also an issue for large corporations, be it Oracle or any other company involved in the current discussion. In my opinion, by Oracle donating the intellectual property of Java EE, the Java community was already handed over the most important value of the specification and we should focus on what we have and not get overly distracted by the strings attached. Personally, I’d worry more about the future of Java if Oracle had lost the interest in the Java brand instead of taking its stand.<br />
<br />
As for Jakarta EE, I do neither think that the coming namespace migration is the biggest problem the specification is facing. Many developers have been frustrated with the dustiness of Java EE even before the recent stagnation period. In my opinion, the problem is part of the process. In reality, a Java EE specification is often derived from a leading framework’s implementation. If another framework wanted to reinvent how the same problem can be solved with a better API, it needs to face the constant criticism that it does not adhere to the standard. This all despite the fact that this standard was typically nothing but a snapshot of a previous best practice. For this reason, I hope that Jakarta EE can rather focus on its evolution instead of holding too much onto its past. With a compelling offering of state of the art API, I would not worry much about adjusting my code if it saved me from implementing iterations of minimally altered <code>jakarta.servlet.Servlet</code> API.
</div>Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-74807528100179273982018-08-05T21:13:00.001+02:002018-08-05T21:56:13.747+02:00Hands on Java 11's constantdynamic<div dir="ltr" style="text-align: left;" trbidi="on">
With the intention of making the JVM more appealing to dynamic languages, the seventh version of the platform had introduced <i>invokedynamic</i> to its instruction set. Java developers do not normally take note of this feature as it is hidden in Java byte code. In short, by using <i>invokedynamic</i> it has become possible to delay the binding of a method call until its first invocation. This technique is for example used by the Java language to implement lambda expressions which are only manifested on demand upon their first use. Doing so, <i>invokedynamic</i> has evolved into an essential language feature which I have <a href="https://mydailyjava.blogspot.com/2015/03/dismantling-invokedynamic.html">described in detail in a previous blog posting</a>. With <i>constantdynamic</i> a similar mechanism was introduced to Java 11, only that it delays the creation of a constant value. This posting describes the purpose and the inner workings of this feature and shows how to generate code that makes use of this new instruction using the Byte Buddy library.<br />
<br />
<h4>
What are constant values in Java?</h4>
<br />
Before Java 5, constant values in a Java programs could only be strings or of a primitive type. Those constants were built into the language as literals and are even assumed by the <i>javac</i> compiler to reduce the size of a class file. For example, in the following code snippet the value of the only field is never actually read but instead copied to its use site during compilation:<br />
<br />
<pre class="brush: java">class ConstantSample {
final String field = “foo”;
void hello() {
System.out.print(field);
}
}</pre>
<br />
Instead of reading the field within the <code>hello</code> method, the generated byte code will contain a direct reference to the constant value <code>foo</code>. As a matter of fact, the above class will not ever attempt to read the field’s value what can be validated by altering it using Java reflection after which invoking hello would still print <code>foo</code>.<br />
<br />
To represent such constant values, any Java class file contains a constant pool which can be thought of as a table that writes out any constant values that exist within the scope of a class. This implies constants that are used within methods or as field values but also other immutable information that describes a class such as the class’s name or names of invoked methods and their declaring type names. Once a value is recorded in the class’s constant pool, values can be referenced by an offset pointing to a specific entry within the constant pool. Doing so, values that are repeated throughout a class only need to be stored once because an offset can of course be referenced multiple times.<br />
<br />
Therefore, when the field is read in the above source code, <i>javac</i> emits a byte code that refers to the offset of the value foo in the constant pool instead of emitting a read instruction for the field. This can be done as the field is declared final where <i>javac</i> ignores the edge-case of a reflective value change. By emitting an instruction to read a constant, <i>javac</i> also saves some bytes compared to an instruction for a field read. This is what makes this optimization lucrative, especially since string and numeric values are fairly commonly in any Java class. Smaller class files help the Java runtime to load classes quicker and an explicit notion of constantness helps the the JVM’s JIT and AOT compilers to apply further optimizations.<br />
<br />
The described reuse of offsets for the same constant also implies an identity of reused values. As a consequence of representing an equal string value by a single instance the following statement will assert true in Java:<br />
<br />
<pre class="brush: java">assert “foo” == “foo”;</pre>
<br />
Under the hood, both values of foo point to the same constant pool offset in the defining class’s constant pool. Additionally, the JVM even deduplicates constant strings across classes by interning strings that are found in constant pools.<br />
<br />
<h4>
Limitations of constant pool storage</h4>
<br />
Such tabular representation of values within a class file’s constant pool works well for simple values such as strings and numeric primitives. But at the same time, it can have non-intuitive consequences when <i>javac</i> is not discovering a value as being constant. For example, in the following class the only field’s value is not treated as a constant within the <code>hello</code> method:<br />
<br />
<pre class="brush: java">class NoConstantSample {
final String field = “foo”.toString();
void hello() {
System.out.print(field);
}
}</pre>
<br />
While the <code>toString</code> method is trivial for strings, this circumstance remains unknown to javac which does not evaluate Java methods. Therefore, the compiler can no longer emit a constant pool value as the input to the print statement. Instead, it must emit a field read instruction of the field which requires additional bytes as it was mentioned before. This time, if the field’s value was changed by using reflection, invoking <code>hello</code> would therefore also print the updated value.<br />
<br />
Of course, this example is contrived. But it is not difficult to imagine how limiting the classical approach to constants in Java plays out in practice. For example, imagine an integer value that is defined as <code>Math.max(CONST_A, CONST_B)</code>. Of course, the maximum of two compile-time constants would itself be constant. Yet, due to <i>javac</i>’s inability of evaluating Java methods, the derived value is not discovered as a constant but only computed at runtime.<br />
<br />
Another problem of declaring constant values in a class file’s constant pool, is its limitation to simple values. Strings and numerical values are of course trivial to represent, but more complex Java objects require more flexibility than the classical approach. To support additional constants, the Java class file format already added class literal constants in Java 5 where values such as <code>String.class</code> would no longer be compiled to a call to <code>Class.forName("java.lang.String")</code> but to a constant pool entry containing a class reference. And also the Java 7 release added new constant pool types to the class file specification to allow for a constant representation of <code>MethodType</code> and <code>MethodHandle</code> instances.<br />
<br />
In contrast to strings, classes and primitive values, the Java programming language does however not offer a literal for creating those latter constants. Rather, the possibility for such constants was added to better support <i>invokedynamic</i> instructions where <i>javac</i> required an efficient way of representation. In essence, a lambda expression is described by the lambda’s expressions type signature - a <code>MethodType</code> - and a reference to its implementation - a <code>MethodHandle</code>. If both values had to be created as explicit, non-constant arguments for each call to a lambda expression, the performance overhead of using such expressions would surely have outweighed their benefit.<br />
<br />
While this solution eased some intermediate pain, it implied a dissatisfying perspective onto Java’s future with regards of adding further constant types. A constant pool entry’s type is encoded by a single byte what severely limits the total number of possible constant types in a class file. As an additional hassle, changes to the class file format require a cascading adjustment of any tool that processes class files what makes a more generic approach for expressing constant values desirable. By introducing <i>constantdynamic</i>, such a mechanism is finally supported by the Java virtual machine with the upcoming release of Java 11.<br />
<br />
<h4>
Introducing dynamic constants</h4>
<br />
A dynamic constant is not created by processing a literal expression but by invoking a so-called bootstrap method that produces the constant value as its result. This is fairly similar to the <i>invokedynamic</i> instruction that binds method call sites by invoking a bootstrap method during runtime where a pointer to a target implementation for the dynamically bound call site is returned. As key difference, a bootstrapped constant is however immutable whereas dynamically bound method calls can be redirected to another implementation at a later point.<br />
<br />
In essence, bootstrap methods are nothing more but Java methods with some requirements to their signature. As a first argument, any bootstrapping method receives a <code>MethodHandles.Lookup</code> instance that is automatically provided by the JVM. Such lookups give access with the privileges of the class that a particular instance of the class represents. For example, when <code>MethodHandles.lookup()</code> is invoked from any class, the caller-sensitive method returns an instance that for example allows for reading private fields of the calling class what would not be possible for a lookup instance that was created from within another class. In the case of a bootstrap method, the lookup represents the class that defines the dynamic constant under creation rather then the class that is declaring the boostrap method. Doing so, the bootstrap methods can access the same information as if the constant was created from within the constant-defining class itself. As a second argument, the bootstrap method receives the constant’s name and as a third argument, it receives the constants expected type. A bootstrap method must be static or a constructor where the constructed value represents the constant.<br />
<br />
In many cases, none of these three arguments are required for implementing a bootstrap method but their existence allows for the implementation of more generic bootstrapping mechanisms to facilitate allow for the reuse of bootstrap methods for the creation of multiple constants. If desired, the last two arguments can also be omitted when declaring a bootstrap method. Declaring a <code>MethodHandles.Lookup</code> type as the first parameter is however required. This is done to allow potentially allowing further invocation modes in the future where the first parameter serves as a marker type. This is another difference to <i>invokedynamic</i> which allows allows for the omission of the first parameter.<br />
<br />
With this knowledge, we can now express the previous maximum of two constants that was previously mentioned as a derived constant. The value is computed trivially by the following bootstrap method:<br />
<br />
<pre class="brush: java">public class Bootstrapper {
public static int bootstrap(MethodHandles.Lookup lookup, String name, Class type) {
return Math.max(CONST_A, CONST_B);
}
}</pre>
<br />
Since the lookup instance that is the first argument comes with the privileges of the class that defines the constant, it would also be possible to acquire the values of <code>CONST_A</code> and <code>CONST_B</code> by using this lookup, even if they were not normally visible to the bootstrap method, for example because they were private. The <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandles.Lookup.html">class’s javadoc explains in detail</a> what API needs to be used for locating a field and to read their values.<br />
<br />
In order to create a dynamic constant, a bootstrap method must be referenced within a class’s constant pool as an entry of type dynamic constant. As of today, the Java language has no way of creating such an entry and to my knowledge no other language is currently making use of this mechanism either. For this reason, we will look into creating such classes using the code generation library Byte Buddy later in this article. In Java pseudo code which hints constant pool values in comments, a dynamic constant and its bootstrap method would however be referred to as follows:<br />
<br />
<pre class="brush: java">class DynamicConstant {
// constant pool #1 = 10
// constant pool #2 = 20
// constant pool #3 = constantdyamic:Bootstrapper.bootstrap/maximum/int.class
final int CONST_A = [constant #1], CONST_B = [constant #2];
void hello() {
System.out.print([constant #3]);
}
}</pre>
<br />
Once the <code>hello</code> method is executed for the first time, the JVM would resolve the specified constant by invoking the <code>Bootstrapper.bootstrap</code> method with maximum as the constant name and <code>int.class</code> as the requested type for the created constant. After receiving a result from the bootstrap method, the JVM would then substitute any reference to the constant with this result and never invoke the bootstrap method again. This would also be true if the dynamic constant was referenced at multiple sites.<br />
<br />
<h4>
Avoiding custom bootstrap methods</h4>
<br />
For most cases, creating a dynamic constant does not require the implementation of an individual bootstrap method. To cover the majority of use cases, the JVM-bundled class <code>java.lang.invoke.ConstantBootstraps</code> already implements several generic bootstrap methods that can be used for the creation of most constants. As center piece, the class’s <code>invoke</code> method allows to define a constant by providing a method reference as a factory for a constant value. To make such a generic approach work, bootstrap methods are capable of receiving any number of additional arguments which must themselves be constant values. Those arguments are then included as references to other constant pool entries while describing the entry of the dynamic constant.<br />
<br />
Doing so, the above maximum can rather be computed by providing a handle to the <code>Math.max</code> method and the two constant values of <code>CONST_A</code> and <code>CONST_B</code> as additional arguments. The implementation of the <code>invoke</code> method in <code>ConstantBootstraps</code> will then invoke <code>Math.max</code> using the two values and return the result where the bootstrap method is roughly implemented as follows:<br />
<br />
<pre class="brush: java">class ConstantBootstraps {
static Object invoke(MethodHandles.Lookup lookup, String name, Class type,
MethodHandle handle, Object[] arguments) throws Throwable {
return handle.invokeWithArguments(arguments);
}
}</pre>
<br />
When additional arguments are provided to a bootstrap method, they are assigned in their order to every additional method parameter. To allow for more flexible bootstrap methods such as the invoke method above, the last parameter can also be of an <code>Object</code> array type to receive any excess arguments, in this case the two integer values. If a bootstrap method does not accept a provided argument, the JVM will not invoke the bootstrap method but throw a <code>BootstrapMethodError</code> during the failed constant resolution.<br />
<br />
Using this approach, the pseudo code to using <code>ConstantBootstraps.invoke</code> would no longer required an individual bootstrap method and rather look as in the following pseudo code:<br />
<br />
<pre class="brush: java">class AlternativeDynamicConstant {
// constant pool #1 = 10
// constant pool #2 = 20
// constant pool #3 = MethodHandle:Math.max(int,int)
// constant pool #4 = constantdyamic:ConstantBootstraps.invoke/maximum/int.class/#3,#1,#2
final int CONST_A = [constant #1], CONST_B = [constant #2];
void hello() {
System.out.print([constant #4]);
}
}</pre>
<h4>
Nested dynamic constants</h4>
<br />
As mentioned, the arguments of a bootstrap method are required to be other constant pool entries. With dynamic constants being stored in the constant pool, this allows for nesting dynamic constants what makes this feature even more flexible. This comes with the intuitive limitation that the initialization of dynamic constants must not contain a circles. For example, the following bootstrap methods would be called from top to bottom if the <code>Qux</code> value was resolved:<br />
<br />
<pre class="brush: java">static Foo boostrapFoo(MethodHandles.Lookup lookup, String name, Class type) {
return new Foo();
}
static Bar boostrapBar(MethodHandles.Lookup lookup, String name, Class type, Foo foo) {
return new Bar(foo);
}
static Qux boostrapQux(MethodHandles.Lookup lookup, String name, Class type, Bar bar) {
return new Qux(bar);
}</pre>
<br />
When the JVM is required to resolve the dynamic constant for <code>Qux</code>, it would first resolve <code>Bar</code> what would again trigger a previous initialization of <code>Foo</code> as each value depends on the previous.<br />
<br />
Nesting dynamic constants can also be required when expressing values that are not supported by static constant pool entry types such as a null reference. Before Java 11, a null value could only be expressed as a byte code instruction but not as a constant pool value where the byte code neither implied a type for <code>null</code>. To overcome this limitation, <code>java.lang.invoke.ConstantBootstraps</code> offers several convenience methods such as <code>nullValue</code> that allows bootstrapping a typed <code>null</code> value as a dynamic constant instead. This <code>null</code> value can then be supplied as an argument to another bootstrap method this method expected <code>null</code> as an argument. Similarly, it is not possible to express a primitive type literal such as <code>int.class</code> in the constant pool which can only represent reference types. Instead, <i>javac</i> translates for example <code>int.class</code> to a read of the static <code>Integer.TYPE</code> field which resolves its value of <code>int.class</code> on startup by a native call into the JVM. Again, <code>ConstantBootstraps</code> offers the <code>primitiveType</code> bootstrap method to represent such values easily as dynamic constants instead.<br />
<br />
<h4>
Why should one care about constant values?</h4>
<br />
All of the above might sound like a technical finesse that does not add much to the Java platform beyond what static fields already provide. However, the potential of dynamic constants is large but still unexplored. As the most obvious use case, dynamic constants can be used to properly implement lazy values. Lazy values are typically used to represent expensive objects only on-demand when they are used. As of today, lazy values are often implemented by using so-called <a href="https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java">double checked locking</a>, a pattern that is for example implemented by the <i>scalac</i> compiler for its <code>lazy</code> keyword:<br />
<br />
<pre class="brush: java">class LazyValue {
volatile ExpensiveValue value;
void get() {
T value = this.value;
if (value == null) {
synchronized (this) {
value = this.value;
if (value == null) {
value = new ExpensiveValue();
}
}
}
return value;
}
}</pre>
<br />
The above construct requires a volatile read on every read despite the fact that the value never changes once it is initialized. This implies an unnecessary overhead which can be avoided by expressing the lazy value as a dynamic constant that is only bootstrapped if it is ever used. Especially in the Java core libraries this can be useful for delaying the initialization of many values that are never used, for example in the <code>Locale</code> class which initializes values for any supported language despite the fact that most JVMs only ever use the running machines standard language. By avoiding the initialization of such excess values, the JVM can boot up quicker and avoid using memory for dead values.<br />
<br />
Another important use case is the availability of constant expressions to optimizing compilers. It is easy to imagine why compilers prefer processing constant values over mutable values. For example, if a compiler can combine two constants, the result of this combination can permanently replace the previous values. This would of course not be possible if the original values could change over time. And while a just-in-time compiler might still assume that mutable values are factually constant at runtime, an ahead-of-time compiler is dependent on some explicit notion of constantness. By assuring that bootstrap methods are side-effect free, future Java version could for example allow for their compile-time evaluation where <i>constantdynamic</i> could serve as a light-weight macro mechanism to widen the scope of native images written in Java using <a href="https://www.graalvm.org/">Graal</a>.<br />
<br />
<h4>
Will I ever work with this feature?</h4>
<br />
When <i>invokedynamic</i> was introduced in Java 7, this new byte code feature was unused from the perspective of the Java language. However, as of Java 8 <i>invokedynamic</i> instructions can be found in most class files as an implementation of lambda expressions. Similarly, Java 11 does not yet use the <i>constantdynamic</i> feature but one can expect that this will change in the future.<br />
<br />
During the latest JVMLS several potential APIs for exposing <i>constantdynamic</i> were already discussed (which would also make <i>invokedynamic</i> accessible via an API). This would be especially useful for library authors to allows them to better resolve critical execution paths but could also unlock some potential to improve <i>javac</i>’s constant detection, for example to widen the scope of non-capturing lambda expressions where field or variable access could be substituted by reading a constant value if a constant value was discovered during compilation. Finally, this new mechanism offers potential for future language enhancements such as a lazy keyword that avoids the overhead of the current equivalents in alternative JVM languages.<br />
<br />
The <i>constantdynamic</i> feature can also be useful to Java agents that often need to enhance existing classes with additional information. Java agents cannot normally alter a classes by for example adding static fields as this can both interfere with reflection-based frameworks and since class format changes are forbidden on most JVMs when redefining an already loaded class. Neither restriction does however apply to dynamic constants that are added during runtime where a Java agent can now easily tag classes with additional information.<br />
<br />
<h4>
Creating dynamic constants using Byte Buddy</h4>
<br />
Despite the lack of language support for <i>constantdynamic</i>, JVMs of version 11 are already fully capable of processing class files that contain dynamic constants. Using the byte code generation library Byte Buddy, we can create such class files and load them into an <a href="http://jdk.java.net/11/">early access build of the JVM</a>.<br />
<br />
In Byte Buddy, dynamic constants are represented by instances of <code>JavaConstant.Dynamic</code>. For convenience, Byte Buddy offers factories for any bootstrap method that is declared by the <code>java.lang.invoke.ConstantBoostraps</code> class such as the <code>invoke</code> method that was discussed previously.<br />
<br />
For an easy example, the following code creates a subclass of <code>Callable</code> and defines the return value of the call method as a dynamic constant of the sample class. To bootstrap the constant, we are supplying the constructor of <code>Sample</code> to the mentioned <code>invoke</code> method:<br />
<br />
<pre class="brush: java">public class Sample {
public static void main(String[] args) throws Throwable {
Constructor<? extends Callabable<?>> loaded = new ByteBuddy()
.subclass(Callable.class)
.method(ElementMatchers.named("call"))
.intercept(FixedValue.value(JavaConstant.Dynamic.ofInvocation(Sample.class.getConstructor())))
.make()
.load(Sample.class.getClassLoader())
.getLoaded()
.getConstructor();
Callable<?> first = loaded.newInstance(), second = loaded.newInstance();
System.out.println("Callable instances created");
System.out.println(first.call() == second.call());
}
public Sample() {
System.out.println("Sample instance created");
}
}</pre>
<br />
If you run the code, note how only one instance of <code>Sample</code> is created as it was explained in this article. Also note how the instance is only created lazily upon the first invocation of the call method and after the creation of the <code>Callable</code> instances.<br />
<br />
To run the above code, you currently have to run Byte Buddy with <code>-Dnet.bytebuddy.experimental=true</code> to unlock support for this feature. This changes once Java 11 is finalized and ready for release where Byte Buddy 1.9.0 will be the first version to support Java 11 out of the box. Also, there are still some rough edges in the latest Byte Buddy release when dealing with dynamic constants. Therefore, it is best to build Byte Buddy from the master branch or to use <a href="https://jitpack.io/">JitPack</a>. To find more about Byte Buddy, visit <a href="http://bytebuddy.net/">bytebuddy.net</a>.
</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-53348271825137345002018-04-08T09:26:00.000+02:002018-04-08T09:26:06.825+02:00JDK 11 and proxies in a world past sun.misc.Unsafe<div dir="ltr" style="text-align: left;" trbidi="on">
With JDK 11 the first methods of <code>sun.misc.Unsafe</code> are retired. Among them, the <code>defineClass</code> method was removed. This method has been commonly used by code generation frameworks to define new classes in existing class loaders. While this method was convenient to use, its existence also rendered the JVM inherently unsafe, just as the name of its defining class suggests. By allowing a class to be defined in any class loader and package, it became possible to gain package-scoped access to any package by defining a class within it, thus breaching the boundaries of an otherwise encapsulated package or module.<br />
<br />
With the goal of removing <code>sun.misc.Unsafe</code>, the OpenJDK started offering an alternative for defining classes at runtime. Since version 9, the <code>MethodHandles.Lookup</code> class offers a method <code>defineClass</code> similar to the unsafe version. However, the class definition is only permitted for a class that resides in the same package as the lookup's hosting class. As a module can only resolve lookups for packages that are owned by a module or that are opened to it, classes can no longer be injected into packages that did not intend to give such access.<br />
<br />
Using method handle lookups, a class <code>foo.Qux</code> can be defined during runtime as follows:<br />
<pre class="brush: java">MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandles.Lookup privateLookup = MethodHandles.privateLookupIn(foo.Bar.class, lookup);
byte[] fooQuxClassFile = createClassFileForFooQuxClass();
privateLookup.defineClass(fooQuxClassFile);
</pre>
<br />
In order to perform a class definition, an instance of <code>MethodHandles.Lookup</code> is required which can be retrieved by invoking the <code>MethodHandles::lookup</code> method. Invoking the latter method is call site sensitive; the returned instance will therefore represent the privileges of the class and package from within the method is invoked. To define a class in another package then the current one, a class from this package is required to resolve against it using <code>MethodHandles::privateLookupIn</code>. This will only be possible if this target class's package resides in the same module as the original lookup class or if this package is explicitly opened to the lookup class's module. If those requirements are not met, attempting to resolving the private lookup throws an <code>IllegalAccessException</code>, protecting the boundaries that are implied by the JPMS.<br />
<br />
Of course, code generation libraries are also constrained by this limitation. Otherwise they could be used to create and inject malicious code. And since the creation of method handles is call-site sensitive, it is not possible to incorporate the new class definition mechanism without requiring users to do some additional work by providing an appropriate lookup instance that represents the privileges of their module.<br />
<br />
When using Byte Buddy, the required changes are fortunately minimal. The library defines classes using a <code>ClassDefinitionStrategy</code> which is responsible for the loading a class from its binary format. Prior to Java 11, a class could be defined using reflection or <code>sun.misc.Unsafe</code> using <code>ClassDefinitionStrategy.Default.INJECTION</code>. To support Java 11, this strategy needs to be replaced by <code>ClassDefinitionStrategy.UsingLookup.of(lookup)</code> where the provided lookup must have access to the package in which a classes would reside. <br />
<h4 style="text-align: left;">
</h4>
<h4 style="text-align: left;">
Migrating cglib proxies to Byte Buddy</h4>
<br />
As of today, other code generation libraries do not provide such a mechanism and it is uncertain when and if such capabilities are added. Especially for cglib, API changes have proven problematic in the past due to the libraries old age and widespread use in legacy applications that are no longer updated and would not adopt modifications. For users that want to adopt Byte Buddy as a more modern and actively developed alternative, the following segment will therefore describe a possible migration.<br />
<br />
As an example, we generate a proxy for the following sample class with a single method:<br />
<pre class="brush: java">public class SampleClass {
public String test() {
return "foo";
}
}</pre>
<br />
To create a proxy, the proxied class is normally subclassed where all methods are overridden to dispatch the interception logic. Doing so, we append a value bar to the return value of the original implementation as an example.<br />
<br />
A cglib proxy is typically defined using the <code>Enhancer</code> class in combination with an <code>MethodInterceptor</code>. A method interceptor supplies the proxied instance, the proxied method and its arguments. Finally, it also provides an instance of <code>MethodProxy</code> which allows to invoke the original code.<br />
<pre class="brush: java">Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
return proxy.invokeSuper(obj, method, args) + "bar";
}
});
SampleClass proxy = (SampleClass) enhancer.create();
assertEquals("foobar", proxy.test());</pre>
<br />
Note that the above code will cause a problem if any other method such as <code>hashCode</code>, <code>equals</code> or <code>toString</code> was invoked on the proxy instance. The first two methods would also be dispatched by the interceptor and therefore cause a class cast exception when cglib attemted to return the string-typed return value. In contrast, the <code>toString</code> method would work but return an unexpected result as the original implementation was prefixed to bar as a return value.<br />
<br />
In Byte Buddy, proxies are not a dedicated concept but can be defined using the library’s generic code generation DSL. For an approach that is the most similar to cglib, using a <code>MethodDelegation</code> offers the easiest migration path. Such a delegation targets a user-defined interceptor class to which method calls are dispatched:<br />
<pre class="brush: java">public class SampleClassInterceptor {
public static String intercept(@SuperCall Callable<String> zuper) throws Exception {
return zuper.call() + "bar";
}
}</pre>
<br />
The above interceptor first invokes the original code via a helper instance that is provided by Byte Buddy on demand. A delegation to this interceptor is implemented using Byte Buddy’s code generation DSL as follows:<br />
<pre class="brush: java">SampleClass proxy = new ByteBuddy()
.subclass(SampleClass.class)
.method(ElementMatchers.named("test"))
.intercept(MethodDelegation.to(SampleClassInterceptor.class))
.make()
.load(someClassLoader, ClassLoadingStrategy.UsingLookup.of(MethodHandles
.privateLookupIn(SampleClass.class, MethodHandles.lookup()))
.getLoaded()
.getDeclaredConstructor()
.newInstance();
assertEquals("foobar", proxy.test());</pre>
<br />
Other than cglib, Byte Buddy requires to specify a method filter using an <code>ElementMatcher</code>. While filtering is perfectly possible in cglib, it is quite cumbersome and not explicitly required and therefore easily forgotten. In Byte Buddy, all methods can still be intercepted using the <code>ElementMatchers.any()</code> matcher but by requiring to specify such a matcher, users are hopefully reminded to make a meaningful choice.<br />
<br />
With the above matcher, any time a method named <i>test</i> is invoked, the call will be delegated to the specified interceptor using a method delegation as discussed.<br />
<br />
The interceptor that was introduced would however fail to dispatch methods that do not return a string instance. As a matter of fact, the proxy creation would yield an exception issued by Byte Buddy. It is however perfectly possible to define a more generic interceptor that can be applied to any method similar to the one offered by cglib's <code>MethodInterceptor</code>:<br />
<pre class="brush: java">public class SampleClassInterceptor {
@RuntimeType
public static Object intercept(
@Origin Method method,
@This Object self,
@AllArguments Object[] args,
@SuperCall Callable<String> zuper
) throws Exception {
return zuper.call() + "bar";
}
}</pre>
<br />
Of course, since the additional arguments of the interceptor are not used in this case, they can be omitted what renders the proxy more efficient. Byte Buddy will only provide arguments on demand and if they are actually required.<br />
<br />
As the above proxy is stateless, the interception method is defined to be static. Again, this is an easy optimization as Byte Buddy otherwise needs to define a field in the proxy class that holds a reference to the interceptor instance. If an instance is however required, a delegation can be directed to a member method of an instance using <code>MethodDelegation.to(new SampleClassInterceptor())</code>.<br />
<h4 style="text-align: left;">
</h4>
<h4 style="text-align: left;">
Caching proxy classes for performance</h4>
<br />
When using Byte Buddy, proxy classes are not automatically cached. This means that a new class is generated and loaded every time the above code is run. With code generation and class definition being expensive operations, this is of course inefficient and should be avoided if proxy classes can be reused. In cglib, a previously generated class is returned if the input is identical for two enhancements what is typically true when running the same code segment twice. This approach is however rather error prone and often inefficient since a cache key can normally be calculated much easier. With Byte Buddy, a dedicated caching library can be used instead, if such a library already is available. Alternatively, Byte Buddy also offers a <code>TypeCache</code> that implements a simple cache for classes by a user-defined cache key. For example, the above class generation can be cached using the base class as a key using the following code:<br />
<pre class="brush: java">TypeCache<Class<?>> typeCache = new TypeCache<>(TypeCache.Sort.SOFT);
Class<?> proxyType = typeCache.findOrInsert(classLoader, SampleClass.class, () -> new ByteBuddy()
.subclass(SampleClass.class)
.method(ElementMatchers.named("test"))
.intercept(MethodDelegation.to(SampleClassInterceptor.class))
.make()
.load(someClassLoader, ClassLoadingStrategy.UsingLookup.of(MethodHandles
.privateLookupIn(SampleClass.class, MethodHandles.lookup()))
.getLoaded()
});</pre>
<br />
Unfortunately, caching classes in Java brings some caveats. If a proxy is created, it does of course subclass the class it proxies what makes this base class ineligible for garbage collection. Therefore, if the proxy class was referenced strongly, the key would also be referenced strongly. This would render the cache useless and open for memory leaks. Therefore, the proxy class must be referenced softly or weakly what is specified by the constructor argument. In the future, this problem might be resolved if Java introduced ephemerons as a reference type. At the same time, if garbage collection of proxy classes is not an issue, a <code>ConcurrentMap</code> can be used to compute a value on absence.<br />
<h4 style="text-align: left;">
</h4>
<h4 style="text-align: left;">
Broaden the usability of proxy classes</h4>
<br />
To embrace reuse of proxy classes, it is often meaningful to refactor proxy classes to be stateless and to rather isolate state into an instance field. This field can then be accessed during the interception using the mentioned dependency injection mechanism, for example, to make the suffix value configurable per proxy instance:<br />
<pre class="brush: java">public class SampleClassInterceptor {
public static String intercept(@SuperCall Callable<String> zuper,
@FieldValue("qux") String suffix) throws Exception {
return zuper.call() + suffix;
}
}</pre>
<br />
The above interceptor now receives the value of a field <i>qux</i> as a second argument which can be declared using Byte Buddy’s type creation DSL:<br />
<pre class="brush: java">TypeCache<Class<?>> typeCache = new TypeCache<>(TypeCache.Sort.SOFT);
Class<?> proxyType = typeCache.findOrInsert(classLoader, SampleClass.class, () -> new ByteBuddy()
.subclass(SampleClass.class)
.defineField(“qux”, String.class, Visibility.PUBLIC)
.method(ElementMatchers.named("test"))
.intercept(MethodDelegation.to(SampleClassInterceptor.class))
.make()
.load(someClassLoader, ClassLoadingStrategy.UsingLookup.of(MethodHandles
.privateLookupIn(SampleClass.class, MethodHandles.lookup()))
.getLoaded()
});</pre>
<br />
The field value can now be set on an every instance after its creation using Java reflection. In order to avoid reflection, the DSL can also be used to implement some interface that declares a setter method for the mentioned field which can be implemented using Byte Buddy's <code>FieldAccessor</code> implementation.<br />
<h4 style="text-align: left;">
</h4>
<h4 style="text-align: left;">
Weighting Proxy runtime and creation performance </h4>
<br />
Finally, when creating proxies using Byte Buddy, some performance considerations need to be made. When generating code, there exists a trade-off between the performance of the code generation itself and the runtime performance of the generated code. Byte Buddy typically aims for creating code that runs as efficiently as possible what might require additional time for the creation of such code compared to cglib or other proxing libraries. This bases on the assumption that most applications run for a long time but only creates proxies a single time what does however not hold for all types of applications.<br />
<br />
As an important difference to cglib, Byte Buddy generates a dedicated super call delegate per method that is intercepted rather then a single <code>MethodProxy</code>. These additional classes take more time to create and load but having these classes available results in better runtime performance for each method execution. If a proxied method is invoked in a loop, this difference can quickly be crucial. If runtime performance is however not a primary goal and it is more important that the proxy classes are created in short time, the following approach avoids the creating of additional classes altogether:<br />
<pre class="brush: java">public class SampleClassInterceptor {
public static String intercept(@SuperMethod Method zuper,
@This Object target,
@AllArguments Object[] arguments) throws Exception {
return zuper.invoke(target, arguments) + "bar";
}
}</pre>
<h4 style="text-align: left;">
</h4>
<h4 style="text-align: left;">
Proxies in a modularized environment</h4>
<br />
Using the simple form of dependency-injection for interceptors rather then relying on a library-specific type such as cglib's <code>MethodInterceptor</code>, Byte Buddy facilitates another advantage in a modularized environment: since the generated proxy class will reference the interceptor class directly rather then referencing a library specific dispatcher type such as cglib's <code>MethodInterceptor</code>, the proxied class’s module does not need to read Byte Buddy’s module. With cglib, the proxied class module must read cglib's module which defines the <code>MethodInterceptor</code> interface rather then the module that implements such an interface. This will most likely be non-intuitive for users of a library that uses cglib as a transitive dependency, especially if the latter dependency is treated as an implementation detail that should not be exposed.<br />
<br />
In some cases, it might not even be possible or desirable that the proxied class's module reads the module of the framework which supplies the interceptor. For this case, Byte Buddy also offers a solution to avoid such a dependency altogether by using its <code>Advice</code> component. This component works on code templates such as that in the following example:<br />
<pre class="brush: java">public class SampleClassAdvice {
@Advice.OnMethodExit
public static void intercept(@Advice.Returned(readOnly = false) String returned) {
returned += "bar";
}
}</pre>
<br />
The above code might not appear to make much sense as it stands and as a matter of fact, it will never be executed. The class merely serves as a byte code template to Byte Buddy which reads the byte code of the annotated method which is then inlined into the generated proxy class. To do so, every parameter of the above method must be annotated to represent a value of the proxied method. In the above case, the annotation defines the parameter to define the method’s return value to which bar is appended as a suffix given the template. Given this advice class, a proxy class could be defined as follows:<br />
<pre class="brush: java">new ByteBuddy()
.subclass(SampleClass.class)
.defineField(“qux”, String.class, Visibility.PUBLIC)
.method(ElementMatchers.named(“test”))
.intercept(Advice.to(SampleClassAdvice.class).wrap(SuperMethodCall.INSTANCE))
.make()</pre>
<br />
By wrapping the advice around a <code>SuperMethodCall</code>, the above advice code will be inlined after the call to the overridden method has been made. To inline code before the original method call, the <code>OnMethodEnter</code> annotation can be used.<br />
<br />
<h4 style="text-align: left;">
Supporting proxies on Java versions prior to 9 and past 10 </h4>
<br />
When developing applications for the JVM, one can normally rely on applications that run on a particular version to also run on later versions. This has been true for a long time, even if internal API has been used. However, as a consequence of removing this internal API, this is no longer true as of Java 11 where code generation libraries that have relied on <code>sun.misc.Unsafe</code> will no longer work. At the same time, class definition via <code>MethodHandles.Lookup</code> is not available to JVMs prior to version 9.<br />
<br />
As for Byte Buddy, it is the responsibility of a user to use a class loading strategy that is compatible with the current JVM. To support all JVMs, the following selection needs to be made:<br />
<pre class="brush: java">ClassLoadingStrategy<ClassLoader> strategy;
if (ClassInjector.UsingLookup.isAvailable()) {
Class<?> methodHandles = Class.forName("java.lang.invoke.MethodHandles");
Object lookup = methodHandles.getMethod("lookup").invoke(null);
Method privateLookupIn = methodHandles.getMethod("privateLookupIn",
Class.class,
Class.forName("java.lang.invoke.MethodHandles$Lookup"));
Object privateLookup = privateLookupIn.invoke(null, targetClass, lookup);
strategy = ClassLoadingStrategy.UsingLookup.of(privateLookup);
} else if (ClassInjector.UsingReflection.isAvailable()) {
strategy = ClassLoadingStrateg.Default.INJECTION;
} else {
throw new IllegalStateException(“No code generation strategy available”);
}</pre>
<br />
The above code uses reflection to resolve a method handle lookup and to resolve it. Doing so, the code can be compiled and loaded on JDKs prior to Java 9. Unfortunately, Byte Buddy cannot implement this code as a convenience since <code>MethodHandles::lookup</code> is call site sensitive such that the above must be defined in a class that resides in the user’s module and not within Byte Buddy.<br />
<br />
Finally, it is worth considering to avoid class injection altogether. A proxy class can also be defined in a class loader of its own using the <code>ClassLoadingStrategy.Default.WRAPPER</code> strategy. This strategy is not using any internal API and will work on any JVM version. However, one must keep in mind the performance costs of creating a dedicated class loader. And finally, even if the package name of the proxy class is equal to the proxied class, by defining the proxy in a different class loaders, their runtime packages will no longer be considered as equal by the JVM thus not allowing to override any package-private methods.<br />
<br />
<h4 style="text-align: left;">
Final thoughts </h4>
<br />
On a final note I want to express my opinion that retiring sun.misc.Unsafe is an important step towards a safer, modularized JVM despite the costs of this migration. Until this very powerful class is removed, any boundaries set by the JPMS can be circumvented by using the privileged access that <code>sun.misc.Unsafe</code> still offers. Without this removal, the JPMS costs all the inconvenience of additional encapsulation without the benefit of being able to rely on it.<br />
<br />
Most developers on the JVM will most likely never experience any problems with these additional restrictions but as described, code generation and proxying libraries need to adapt these changes. For cglib, this does unfortunately mean that the end of the road is reached. Cglib was originally modeled as a more powerful version of Java's built-in proxying API where it requires its own dispatcher API to be referenced by the proxy class similar to how Java's API requires referencing of its types. However, these latter types reside in the java.base module which is always read by any module. For this reason, the Java proxying API still functions whereas the cglib model was broken irreparably. In the past, this has already made cglib a difficult candidate for OSGi enviornments but with the JPMS, cglib as a library does no longer function. A similar problem exists for the corresponding proxying API that is provided by Javassist.<br />
<br />
The upside of this change is that the JVM finally offers a stable API for defining classes during an application's runtime, a common operation that has relied on internal API for over twenty years. And with the exception of J<a href="http://mail.openjdk.java.net/pipermail/jigsaw-dev/2018-April/013720.html">avaagents that I think still require a more flexible approach</a>, this means that future Java releases are guaranteed to always work once all users of proxies completed this final migration. And given that the development of cglib has been dormant for years with the library suffering many limitations, an eventual migration by today's users of the library was inevitable in any case. The same might be true for Javassist proxies, as the latter library has not seen commits in almost a half year either.</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-26360307775421378312017-05-10T09:08:00.000+02:002017-05-10T14:13:47.532+02:00Yet another Jigsaw opinion piece<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" id="docs-internal-guid-4da38e49-efb1-8113-eb32-9a838138c59f" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">In the past weeks there has been a heated debate around the imminent release of Java 9 and its most famous feature: the Java platform module system – the JPMS </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">–</span> which is better known under its project umbrella‘s name Jigsaw. The module system is introduced into the Java ecosystem in form of a formal specification process </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">–</span> a JSR </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;"><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">–</span> which needs to be approved in its final form by its expert group. Among other members of this expert group, representatives of Red Hat and IBM have now voted to reject Java‘s module system in the first ballot which they believe is not yet ready for production. </span></div>
<div dir="ltr" id="docs-internal-guid-4da38e49-efb1-8113-eb32-9a838138c59f" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
</div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<h3 style="text-align: left;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline;">What‘s the fuzz all about?</span></h3>
</div>
<br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Even today, Java developers are widely familiar with modularity. Build systems like Maven organize code as modules that are compiled against a declared set of dependencies. Only at runtime, these modules are put together on the class path where these compile-time module boundaries vanish. With Jigsaw, the module path is offered as an alternative to this class path for which the JVM retains such compile-time boundaries at runtime. By not using this module path, applications should function just as before. But this comes with the exception of applications that rely on APIs internal to the JVM. The Java standard library is always loaded as a collection of modules, even if the class path is used exclusively such that internal Java APIs are no longer accessible.</span><br />
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">This latter limitation in compatibility has raised some concerns among the maintainers of both libraries and end-user applications. And in this context it can be a bit surprising that the recent objections do not relate too much to these concerns. While mentioning issues around compatibility, both Red Hat and IBM predominantly argue that the JPMS requires further extension to allow for a better integration with existing module systems such as JBoss modules and OSGi.</span></div>
<div style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: left;">
<br />
<h3>
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline;">What problem does still need solving?</span></h3>
</div>
<br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">By <i>jar hell</i>, developers typically describe a situation where a Java application would require two different versions of a library to satisfy different transitive dependencies. Using the class path, this is impossible as one version of a library shadows a second copy. If a class of a given name is loaded for the first time, the system class loader scans jar files in their command line order and loads the first class file it discovers. In the worst case, this can result in Frankenstein functionality if the shadowed jar file contains some exclusive classes that link with classes of the shadowing jar. But more typically, it results in a runtime failure once a feature dependent on a specific version is triggered.</span><br />
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">With OSGi and JBoss modules, this problem can be partially resolved. The latter module systems allow to load a library by each its own class loader, thus avoiding the system class loader that is responsible for the class path. With this approach, multiple versions of the same class can coexist by isolation within separate class loaders. Doing so, it is for example possible for two libraries to both depend on their specific version of the commonly breaking Guava API. With class loader isolation, any library would delegate calls to its required version when loading dependent classes.</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">When using the module path, the JPMS does not (currently) apply such class loader isolation. This means that <i>jar hell</i> is not solved by Java 9. In contrast to using the class path, the JVM does however detect the described version conflict and fails the application at startup, rather than speculating on accidental compatibility. To enforce this constraint, every Java package name is now exclusive to a specific module or the class path. Therefore, it is not possible for two modules to share a package. This restriction also holds if a private package is not meant to be exposed what is considered to be another flaw of the current module design by Jigsaw‘s critics.</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<br />
<h3 style="text-align: left;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline;">A missed chance to escape jar hell?</span></h3>
</div>
<br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">For class loader isolation to work, it is necessary that versions of the same module never interact. And while two such versions would of course never interact directly, it is unfortunately more than common that two versions are part of the public API of different modules. For example, if two libraries return instances of Guava‘s <code>Function</code> type, a version conflict between each module‘s Guava version can no longer be solved using class loader isolation, even if the <code>Function</code> type did not change between those versions. At runtime, any loaded class is described as a tuple of its name and class loader but since two class loaders do now offer the <code>Function</code> type, which one should be resolved?</span><br />
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">This described problem, as a matter of fact, cannot be solved by a module system. Instead, a module system can discover this conflict and inform the user of the need of an explicit resolution. This is accomplished by the current implementation of the JPMS and of course both OSGi and JBoss modules. At the end of the day, version conflicts can only be avoided by evolving APIs in a compatible manner.</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<br />
<h3 style="text-align: left;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline;">Is Jigsaw too simple?</span></h3>
</div>
<br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Despite the remaining limitations of a class loader-isolating module system, the current argument against Jigsaw is mainly revolving around this item. Additionally, the expert group members that reject Jigsaw point out the lacking support for circular module dependencies ("module A depends on B depends on C depends on A") and the inability to alter the module graph after its creation.</span><br />
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">From a technical perspective, it would of course be possible to add these features. As a matter of fact, Java 9 already ships with a module builder API that allows for loading modules with exclusive class loaders. There is no technical limitation in choosing to retain a single class loader for the module path; rather this decision is considered to be the responsible choice for the JVM by Oracle. And before diving deeper into the arguments, I want to state that I fully agree with the company’s reasoning.</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<br />
<h3 style="text-align: left;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline;">What is wrong with class loader isolation?</span></h3>
</div>
<br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">As mentioned before, even with class loader isolation, manual version management can often not be avoided. Also, library authors that rely on common APIs with version incompatibilities such as Guava do increasingly shade such dependencies. When shading, the code of a library is copied into a separate name space, thus allowing an application to refer to “its version“ by different names instead of by different class loaders. This approach has of course flaws of its own, especially when a shaded dependency uses JNI. On the other hand, this approach overcomes the just mentioned shortcoming of class loader isolation when using libraries with conflicting shared dependencies. Also, by shading a common dependency, a library author relieves its users from potential conflicts independently of a deployment method.</span><br />
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Allowing for circular dependencies would neither impose a big technical challenge. However, cyclic dependencies are rather uncommon and many build systems like Maven do neither support them. Typically, cyclic dependencies can be refactored to non-cyclic ones by splitting up at least one module into implementation and API. In this context, if a feature seems to be of such little common concern, I do not think corner cases justify its addition, especially when the class path still serves as a backup. And if this decision turns out to be wrong, cyclic dependencies can always be enabled in a future release. Taking this feature away would however not be possible.</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Finally, dynamic modules render a feature that could be useful to more than a few applications. When you require the dynamic redeployment of modules with an active life cycle, from my experience in my last project, OSGi is a very good choice. That said, most applications are static and do not have a good reason for its use. But by adding support for a dynamic module graph, the complexity of this feature would translate into the JPMS. Therefore, I think it is the right decision to leave this feature out for now and wait until its use is better understood. Naturally, an approachable module system increases adoption.</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<br />
<h3 style="text-align: left;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline;">Compatibility first.</span></h3>
</div>
<br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Does this incompatibility mean the end for OSGi and JBoss modules? Of course not. Quite to the contrary, the introduction of standardized module descriptors gives opportunity to existing module systems. Missing manifest headers to describe bundles is one of the major pain points when using OSGi due to a significant number of libraries that do not consider the proprietary module descriptor. With the introduction of a standardized module descriptor, existing module systems can ease this limitation by using the latter descriptor as a secondary source for a module’s description.</span><br />
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">I do not doubt for a second that Red Hat and IBM rejected the JSR with their best intentions. At the same time, I cannot agree with the criticism on the lacking reach of the module system. In my opinion, the existing changes are sufficiently challenging for the Java ecosystem to adopt and especially a last minute introduction of class loader isolation bears the potential of unwanted surprise. In this light, I find the arguments made against the current state of Jigsaw inconsistent as it criticizes the complexity of transition to modules but also demands its extension.</span></div>
<div style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: left;">
<br />
<h3>
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline;">There is no perfect module system</span></h3>
</div>
<br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Personally, I think that the current proposal for the JPMS bears two big challenges. Unfortunately enough, they got in the background due to the recent discussion.</span><br />
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Automatic modules</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Without a module descriptor, modular code can only refer to a non-modular jar file in form of a so-called automatic module. Automatic modules do not impose any restrictions and are named by their jar file. This works well for developers of end user applications which never release their code for use by another application. Library developers do however lack a stable module name to refer to their dependant automatic modules. If released, they would rely on stable file names for their dependencies which are difficult to assume.</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">For the adoption of Jigsaw, this would imply a bottom-up approach where any library author can only modularize their software after all dependant code was already modularized. To ease the transition, a manifest entry was added which allows to publish a jar with a stable automatic module name without the need to modularize code or even migrate to Java 9. This allows other libraries users that depend on this first library with a stable name to modularize their code, thus breaking through the bottom-up requirement.</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">I think it is essential to allow library maintainers to state an explicit module name before their code is migrated to fully use the JPMS and I consider this a more than adequate way to deal with this problem which does unlikely offer a better solution.</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Reflection and accessibility</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">With Jigsaw, it is no longer allowed to access non-public, non-exported members using reflection what is an opportunity that many frameworks currently assume. Of course, with a security manager being set, such access can be impossible even in today’s Java releases but since security managers are used so seldom, this is not thought of much. With Jigsaw, this default is reversed where one needs to explicitly open packages for such reflective access, therefore affecting many Java applications.</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Generally, I think that Jigsaw’s encapsulation is a better default than the current general openness. If I want to give Hibernate access to my beans, the JPMS allows me to open my beans to Hibernate only by a qualified export. With a security manager, controlling such fine grained access was difficult if not impossible to implement. However, this transition will induce a lot of growing pain and many libraries are not maintained actively enough to survive adopting these new requirements. Thus, adding this restriction will definitely kill off some libraries that would otherwise still provide a value.</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Also, there are use cases of reflection that are still uncovered. For the mocking library Mockito (that I help maintain) we do for example need a way of defining classes in any class loader. This was and still is only possible by the use of internal Java APIs for which no alternative is yet offered. As Mockito is only used in test environments, security should not be of concern in this context. But thanks to the retained openness of <code>sun.misc.Unsafe</code> on which we already rely for instantiating mock classes without constructor calls, we can simply open these APIs by changing their accessibility using its direct memory APIs.</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">This is of course no good enough solution for the years to come but I am convinced that those concerns can be addressed before removing the Unsafe class entirely. As one possibility, the JVM could be extended with a test module that needs to be resolved explicitly on the command line and which allows such extended access. Another option would be to require the attachment of a Java agent by any test runner because of their ability to break through module barriers. But as for now, any maintained software has an opportunity to resolve its non-standard Java use and continue the discussion on missing APIs in the upcoming years.</span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<br />
<h3 style="text-align: left;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline;">Finding consensus.</span></h3>
</div>
<br />
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Considering the stereotype of the socially anxious computer nerd, software development can be a rather emotional business. Oracle has always been a company that Java developers love to hate and the current discussion partly jumps on this bandwagon. Looking at the success of Java as a language and a platform, I do however think that Oracle deserves credit for its objectively good job in its stewardship. Breaking software today with future success in mind is a delicate and grateless task. Anybody who refactored correct but complex code should be sympathetic to this challenge. </span><br />
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Project Jigsaw has often been criticized for being an unnecessary effort and I admit that this thought had crossed my own mind. Yet, it is thanks to the module systems that dead weight like CORBA or RMI can finally be removed from the JVM. With the implied reduction in size of modular Java applications, the JVM has become more attractive for the use within containerized applications and cloud computing what is surely no coincidence given Oracle’s market strategy. And while it would of course be possible to further postpone this effort to a later Java release, the JVM must address the removal of functionality at some point. Now is as good a time as any.</span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">To ease the upcoming transition, it is important to keep the breaking changes down to a minimum. Therefore, I am convinced that extending the scope of Jigsaw is not in the best interest of the broader Java community. Many of the rejecting votes of the recent ballot asked for the involved parties to find consensus on the outstanding issues. Unfortunately, the features in question can either be implemented or discarded where consensus can only be reached by one party giving up their position. </span></div>
<br />
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">With the typical Java application in mind, I do hope that Oracle does not answer to the demands with a scope extension only to secure a successful vote on the Jigsaw JSR. Rather, I want to appeal to the expert group members who were voting against the JSR to reconsider their vote with the needs of the entire Java ecosystem in mind where the requirements of existing enterprise module solutions are only one factor among many. With the broad usage of Java, ranging from business applications to low-latency systems, it is only natural that different parties identify different priorities for the evolution of the platform. I am convinced that Oracle has found a common denominator for a module system that serves most users. </span></div>
</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com4tag:blogger.com,1999:blog-3237092529299307504.post-68408825075974022232016-10-27T15:17:00.000+02:002016-10-28T10:54:17.951+02:00Generational disparity in garbage collection<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
</div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">For the last year, I have been helping the startup <a href="https://www.instana.com/">Instana</a> to create a Java agent that traces executions within a Java application. This execution data is collected and jointed to generate traces of user requests as well as the resulting communication between services within the system owner’s hemisphere. This way, unstructured communication can be visualized what significantly simplifies the operation of a distributed system that is composed of multiple interacting services.</span></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">In order to generate these traces, the Java agent rewrites all code that reads an external request or initiates one. Obviously, these entries and exits into or out of a system need to be recorded and additionally, meta data is exchanged to identify a request uniquely across systems. For example, when tracing HTTP requests, the agent adds a header containing a unique id which is then recorded by the receiving server as a proof of a request’s origin. Broadly speaking, it is similar to <a href="http://zipkin.io/">what Zipkin is modeling</a>, but without requiring users to change their code.</span></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">In the most simple scenario, such tracing is straightforward to implement. Thanks to <a href="https://github.com/raphw/byte-buddy">my library Byte Buddy</a> which does the heavy lifting, all injected code <a href="https://www.instana.com/blog/how-instana-safely-instruments-applications-for-monitoring/">is written in plain old Java</a> and then copied to the relevant methods at runtime using the Java instrumentation API. For example, when instrumenting a servlet, we know that an entry to a JVM is made whenever the service method is invoked. We also know that the entry is completed when this very same method exits. Therefore, it suffices to add some code to the beginning and the end of the method to record any such entry into a VM process. And it has been the majority of my job to plow through the many Java libraries and frameworks to add support for their ways of communication. From Akka to Zookeeper, over the last year I have hello-worlded my way through the entire Java ecosystem; I even got to write EJBs for all the servers! And I had to make sense of Sun’s CORBA implementation. (Spoiler: There is no sense.)</span></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Things do however quickly become more difficult when tracing asynchronous executions. If a request is received by one thread but is answered from within another thread, it does no longer suffice to only trace entries and exits. Therefore, our agent needs to also track all context switches in concurrent systems made via thread pools, <a href="http://homes.cs.washington.edu/~djg/teachingMaterials/spac/grossmanSPAC_forkJoinFramework.html">fork join tasks</a> or custom concurrency frameworks. And the same way that debugging asynchronous execution is difficult, this is quite a bit of work for us too. I think that I spend as much time dealing with concurrency as I do recording entries and exits.</span></span><br />
<br /></div>
<h3 style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: left;">
</h3>
<h3 style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: left;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.6667px; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline;"><span style="font-family: inherit;">The impact on garbage collection</span></span></span></h3>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">But how does all this impact garbage collection? When implementing a performance monitor, one is facing a trade-off between interpreting the work of a Virtual Machine and causing work for this machine by doing so. While the majority of processing is done in the monitor back-end to which the agent reports its data, we have to do a minimum within the Java process that we share with the monitored application. And you can already guess it: by allocating objects, we inevitably have an impact on the VM’s garbage collection. Fortunately, modern garbage collection algorithms are doing excellent work and by mostly avoiding object allocation and by adaptively sampling our tracing efforts, the effect of our code changes is <span style="font-family: inherit;">negligible</span> for the vast majority of users. Ideally, we only burn a few unused processor cycles to do our work. As a matter of fact, very few applications do use their full processing potential and we are happy with grabbing a small portion of this excess.</span></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Writing a garbage collection-friendly application is typically not too difficult. It is obvious that the easiest way of avoiding garbage is to avoid object allocation altogether. However, object allocation in itself isn’t too bad either. Allocating memory is a rather cheap operation and as any processor owns its own allocation buffer - a <a href="https://blogs.oracle.com/jonthecollector/entry/the_real_thing">so-called TLAB</a> - we do not impose an unnecessary synchronization when allocating only a bit of memory from our threads. If an object only lives in the scope of a method, the JVM can even erase the object allocation altogether as if the fields of the objects were put onto the stack directly. But even without this <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html">escape-analysis</a>, short-lived objects are captured by a special garbage collection circle called the <a href="http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html">young generation collection</a> that is processed quite efficiently. To be honest, this is where most of my objects end up as I often value code readability over the small improvements that escape analysis offers. Currently, escape analysis quickly hits its boundary. Yet, I hope for future HotSpots to improve to get the best of both worlds even without changing my code. Fingers crossed! </span></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">When writing Java programs, I do not typically think about the impact on garbage collection but the above guidelines tend to manifest in my code. For the majority of our agent, this has been working very well. We are running a whole bunch of example applications and integration tests to assure a good behavior of our agent and I also keep an eye on the GC when running examples. In our modern times, using tools like <a href="https://docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-guide/run.htm#JFRUH164">flight recorder</a> and <a href="https://github.com/AdoptOpenJDK/jitwatch">JIT watch</a>, performance analysis has become quite approachable.</span></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<h3 style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-align: left;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.6667px; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline;"><span style="font-family: inherit;"><span style="font-family: inherit;">T<span style="font-family: inherit;">he relativity of <span style="font-family: inherit;">short-lived</span></span></span></span></span></span></h3>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">With an early version of our agent, I one day noticed an application to <a href="https://plumbr.eu/blog/garbage-collection/minor-gc-vs-major-gc-vs-full-gc">trigger tenured collection</a> cycles that it did not trigger without it. As a consequence, collection pauses increased by a multitude. The objects that ended up in the tenured collection were however only objects of the monitored application itself. But since our agent runs mostly isolated from the application threads and at first, this did at first not make sense to me.</span></span></div>
<div dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">When digging deeper, I found that our analysis of user objects triggered some additional escapes of objects but the impact was minimal. The application did already produce a fair amount of objects, mostly by using NIO and by using fork join pools. One thing that the latter frameworks have in common is that they rely on the allocation<a href="https://bugs.openjdk.java.net/browse/JDK-6924217"> of many short lived objects</a>. For example, a fork-join task often splits itself into multiple subtasks which repeat this procedure until each task’s payload is small enough to be computed directly. Every such task is represented by a single, stateful object. An active fork join pool can spawn millions of such objects every minute. But since the tasks compute fast, the representing object is eligible for collection quickly and therefore captured by the young collector. </span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">So how did these objects end up in the tenured collection all of a sudden? At this time, I was prototyping a new stitching instrumentation to track context switches between such fork join tasks. Following the path of a fork join tasks is not trivial. Each worker thread of a fork join pool <a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html">applies work stealing</a> and might grab tasks out of the queue of any other task. Also, tasks might provide a feedback to their parent task on completion. As a consequence, tracing the expansion and interaction of tasks is a rather complex process, also because of the existence of so-called continuation threads where a single task might bounce jobs to hundreds of threads within only a few milliseconds. I came up with a rather elegant solution which relied on the allocation of many short-lived objects which were allocated in bursts whenever backtracking a task to its origin. It turned out that these bursts triggered quite a few young collections themselves.</span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">And this is what I did not consider: each young generation collection increases the age of any object that is not eligible for garbage collection at this point. An object does not age by time but by the amount of young collections triggered. This is not true for all collection algorithms but for many of them such as for all <a href="http://www.oracle.com/technetwork/java/javase/overview/index-jsp-140228.html">default collectors of HotSpot</a>. And by triggering so many collections, the agent threads “prematurely matured” objects of the monitored application despite those objects being unrelated to the agent’s objects. In a way, running the agent “prematurely matured” the target application’s object.</span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<h3 style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: left;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.6667px; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline;">Getting around the problem</span></span></h3>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">I did at first not know how to solve this. In the end, there is no way of telling a garbage collector to treat “your objects” separately. As long as the agent threads were allocating shorter-lived objects at a faster rate than the host process, it would spoil the original objects into the tenured collection causing an increase of garbage collection pauses. In order to avoid this, I therefore started to pool the objects I was using. By pooling, I quickly matured my own objects into the tenured collection and the garbage collection behavior returned to its normal state. Traditionally, pooling was used to avoid the costs of allocation which became cheap in our days. I rediscovered it to erase the impact of our “foreign process” onto garbage collection for the cost of a few kilobytes of memory.</span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">Our tracer is already pooling objects in other places. For example, we represent entries and exits as thread local values that contain a bunch of primitive values that we mutate without allocating a single object. And while such mutable, often procedural and object pooling programming is no longer fashionable, it turns out to be very performance friendly. In the end, mutating bits is closer to what a processor is actually doing. And by using preallocated arrays of a fixed size instead of immutable collections, we save us quite a few round-trips to memory while also preserving our state to be contained in only a few cache lines.</span></span></div>
<div style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: left;">
<h3 style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: left;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.6667px; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline;"> </span></span></h3>
<h3 style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: left;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.6667px; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline;">Is this a “real world” problem?</span></span></h3>
</div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">You might think that this is a rather specific problem that most people do not need to worry about. But as a matter of fact, the problem that I describe applies to a large number of Java applications. For example, within application containers, we typically deploy multiple applications in a single Java process. Just as in the above case, the garbage collection algorithm does not group objects by application as it has no notion of this deployment model. Therefore, object allocations by two isolated applications that share a container do interfere with the anticipated collection patterns of one another. If each application relies on its objects to die young, the sharing of a heap causes a strong relativity on the duration of short-lived.</span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">I am not an advocate for microservices. As a matter of fact, I think they are a bad idea for most applications. In my opinion, routines that can only exist in interaction should ideally be deployed together unless there are good technical reasons not to. And even if isolated applications ease development, you quickly pay the price in operations. I am just mentioning this to avoid a misinterpretation of the moral of the above experience.</span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-size: 14.666666666666666px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline;">What this experience taught me was that deploying several applications in a single Java process can be a bad idea if those applications are heterogeneous. For example, when running a batch process parallel to a web server, you should consider running each in its own process rather than deploying both of them in the same container. Typically, a batch process is allocating objects at a very different rate than a web server. Yet, many enterprise frameworks still advertise all-in-one solutions for tackling such problems which should not share a process to begin with. In 2016, the overhead of an additional process is not typically a problem and since memory is cheap, rather upgrade your server instead of sharing a heap. Otherwise, you might end up with collection patterns that you did not anticipate when developing, running and testing your applications in isolation.</span></span></div>
</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-54637021223235237342015-12-17T13:49:00.000+01:002015-12-17T13:49:31.065+01:00I am elected Java Champion. Thank you!<div dir="ltr" style="text-align: left;" trbidi="on">
Today I was elected a Java Champion. I want to take this opportunity to say thank you to everybody who supported me and my work. Without you, I would not be the developer that I am today. I want to thank all of you and especially:
<br />
<br />
Rafał Świerzyńsk for his patience and contagious enthusiasm when teaching me many programming fundamentals during my first full-time programming job. Thank you for proving to me that writing quality code pays off both in terms of joy at work and value for a customer.
<br />
<br />
The team at <a href="https://zeroturnaround.com/rebellabs/">RebelLabs</a> who helped me to promote <a href="https://github.com/raphw/byte-buddy">Byte Buddy</a> to a broader audience before anybody even used my software. Especially, I want to thank <a href="https://twitter.com/sjmaple">Simon Maple</a> and <a href="https://twitter.com/shelajev">Oleg Šelajev</a> from <a href="http://zeroturnaround.com/">ZeroTurnaround </a>and <a href="https://twitter.com/TheOTown">Oliver White</a> who is now working at <a href="https://www.typesafe.com/">Typesafe</a>.
<br />
<br />
<a href="https://twitter.com/axelfontaine">Axel Fontaine</a> and <a href="https://twitter.com/lukaseder">Lukas Eder</a>, both developers of open-source libraries that often served me as specimen for how to promote Byte Buddy. I also want to thank you both for your advice and shared experiences.
<br />
<br />
Everybody at <a href="http://java.no/">javaBin</a>, the Norwegian Java user group. My first presentation at a JUG meeting bootstrapped my speaker career and speaking at <a href="http://javazone.no/">JavaZone</a> gave me a lot of confidence for the international stage. You are a great bunch and I would surely not be a Java Champion today if it were not for your hard work and dedication.
<br />
<br />
The Java community for its countless efforts of documenting insights into Java technology, for its free software and the many great discussions that I have had. Anything I know I have learned from others and I am endlessly grateful. Especially, I want to thank <a href="https://twitter.com/BriceDutheil">Brice Dutheil</a> who had the confidence to integrate Byte Buddy into the very popular <a href="http://mockito.org/">Mockito</a> library what motivated me tremendously.
<br />
<br />
Finally, my girlfriend Eiril who never complained when I was away for weeks of conferences, when I programmed away an entire weekend or was fed up with a problem that I had not yet figured out.
<br />
<br />
Thank you all, wholeheartedly!
</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-77016307608779430852015-12-02T22:24:00.000+01:002015-12-03T18:22:45.141+01:00Project Jigsaw: an incomplete puzzle<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://mreinhold.org/">Mark Reinhold</a> just recently <a href="http://mail.openjdk.java.net/pipermail/jdk9-dev/2015-December/003149.html">proposed a delay of Java 9</a> to buy more time for completing project Jigsaw as the major feature of the upcoming release. While this decision will surely bring <a href="https://www.reddit.com/r/learnprogramming/comments/35u5bv/is_java_dying_as_a_programming_language/">the doomsayers of Java</a> back onto stage, I am personally quite relieved and think this was a good and necessary decision. The milestone for feature completion of Java 9 is </div>
<a href="http://openjdk.java.net/projects/jdk9/">currently set to the 10th of December</a>, forbidding <a href="http://openjdk.java.net/projects/jdk8/milestones#Feature_Complete">the introduction of new functionality</a> after that date. But looking at <a href="https://jdk9.java.net/jigsaw/">early access builds</a> of project Jigsaw, Java’s module system does not seem to be ready for this development stage.<br />
<br />
Delays in project Jigsaw <a href="http://openjdk.java.net/projects/jigsaw/history">have become a habit</a> over the latest Java release cycles. This must not be misinterpreted as incompetence but rather as an indicator for how difficult it is to introduce modules to Java that is currently a stranger to true modularization. Initially, the module system for Java was proposed in 2008 for inclusion in Java 7. But until today, Jigsaw’s implementation always turned out to be more difficult than anticipated. And after several suspensions and even a temporary abandonment, the stewards of Java are surely under pressure to finally succeed. It is great to see that this pressure did not push the Java team to rush for a release.<br />
<br />
In this article, I try to summarize the state of project Jigsaw as I see it and as it is <a href="http://mail.openjdk.java.net/pipermail/jigsaw-dev/2015-December/005454.html">discussed publicly on the Jigsaw mailing list</a>. I am writing this article as a contribution to the current discussion and to hopefully involve more people into the ongoing development process. I do no intend to downplay the hard work done by Oracle. I am stating this explicitly to avoid misinterpretation after the <a href="http://blog.dripstat.com/removal-of-sun-misc-unsafe-a-disaster-in-the-making/">rather emotional discussions</a> about Jigsaw following the concealment of <code>sun.misc.Unsafe</code>.<br />
<br />
<h3>
Modularized reflection</h3>
<br />
What exactly is it that makes project Jigsaw such a difficult endeavor? Today, visibility modifiers are the closest approximation to encapsulating a class’s scope. Package-privacy can serve as an imperfect retainer of a type to its package. But for more complex applications that span internal APIs over multiple packages, visibility modifiers are insufficient and true modules become necessary. With project Jigsaw, classes can be truly encapsulated what makes them unavailable to some code even if those classes were declared to be public. However, Java programs that build on the assumption that all classes are always available at runtime might need to change fundamentally.<br />
<br />
This change is most likely less fundamental for developers of end-user applications than for the maintainers of Java libraries and frameworks. A library is typically not aware of its user’s code during its compilation. For overcoming this limitation, a library can fallback to using reflection. This way, a container for dependency-injection (such as Spring) can instantiate bean instances of an application without the bean types being known to the framework at compile-time. For instantiating such objects, the container simply delays its work until runtime when it scans the application’s classpath and discovers the bean types which are now visible. For any of these types, the framework then locates a constructor which is invoked reflectively after resolving all injected dependencies.<br />
<br />
Runtime discovery paired with reflection is used by a long list of Java frameworks. But in a modularized environment, running the previous runtime resolution is no longer possible without addressing module boundaries. With project Jigsaw, the Java runtime asserts that every module only accesses modules that are declared as a dependency in the accessing module’s descriptor. Additionally, the imported module must export the classes in question to its accessor. A modularized version of the dependency-injection container cannot declare any user module as a dependency and it is then forbidden reflective access. This would result in a runtime error when instantiating a non-imported class.<br />
<br />
To overcome this limitation, project Jigsaw adds a new API that allows to include additional module dependencies at runtime. After making use of this API and adding all user modules, the modularized dependency-injection container can now continue to instantiate bean types that it does not know at compile-time.<br />
<br />
But does this new API really solve the problem? From a purely functional point of view, this additional API allows for the migration of a library to retain its functionality even after being repackaged as a module. But unfortunately, the runtime enforcement of module boundaries creates a requirement for a ceremonial dance preceding the use of most reflection code. Before a method is invoked, the caller needs to always assure that the corresponding module is already a dependency of the caller. If a framework forgets to add this check, a runtime error is thrown without any chance of discovery during compilation.<br />
<br />
With reflection being used excessively by many libraries and frameworks, it is unlikely that this change in accessibility is going to improve runtime encapsulation. Even if a security manager would restrict frameworks from adding runtime module dependencies, enforcing such boundaries would probably break most existing applications. More realistically, most breaches of module boundaries will not indicate true errors but be caused by improperly migrated code. At the same time, the runtime restriction is neither likely to improve encapsulation if most frameworks preemptively attain access to most user modules.<br />
<br />
This requirement does of course not apply when a module uses reflection on its own types but such use of reflection is rather rare in practice and can be substituted by the use of polymorphism. In my eyes, enforcing module boundaries when using reflection contradicts its primary use case and makes the already non-trivial reflection API even more difficult to use.<br />
<br />
<h3>
Modularized resources</h3>
<br />
Beyond this limitation, it is currently unclear how the dependency-injection container would even discover the classes that it should instantiate. In a non-modularized application, a framework can for example expect a file of a given name to exist on the classpath. This file then serves as an entry point for describing how user code can be discovered. This file is typically obtained by requesting a named resource from a class loader. With project Jigsaw, this might no longer be possible when the required resource is also encapsulated within a module’s boundaries. As far as I know, the final state of resource encapsulation is not yet fully determined. When trying current early access builds, resources of foreign modules can however not be accessed.<br />
<br />
Of course, this problem is also addressed in project Jigsaw’s current draft. To overcome module boundaries, Java’s <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html">preexisting <code>ServiceLoader</code> class</a> is granted super powers. For making specific classes available to other modules, a module descriptor provides a special syntax that enables leaking certain classes through module boundaries. Applying this syntax, a framework module declares that it provides a certain service. A user library then declares an implementation of the same service to be accessible to the framework. At runtime, the framework module looks up any implementation of its service using the service loader API. This can serve as way for discovering other modules at runtime and could substitute resource discovery.<br />
<br />
While this solution seems elegant on a first glance, I remain sceptical of this proposal. The service loader API is fairly simple to use but at the same time, it is very limited in its capabilities. Furthermore, few people have adapted it for their own code which could be seen as an indicator for its limited scope. Unfortunately, only time can tell if this API accommodates all use cases in a sufficient manner. At the same time it is granted that a single Java class gets tied deeply into the Java runtime, making deprecation and substitution of the service loader API almost impossible. In the context of the history of Java which has already told many stories about ideas that seemed good but turned sour, I find it precarious to create such a magical hub that could easily turn out to be an implementation bottleneck.<br />
<br />
Finally, it remains unclear how resources are exposed in modularized applications. While Jigsaw does not break any binary compatibility, returning <code>null</code> from a call to <code>ClassLoader::getResource</code> where a value was always returned previously might just bury applications under piles of null pointer exceptions. As an example, code manipulation tools require a means to locate class files which are now encapsulated what would at a minimum hinder their adoption process.<br />
<br />
<h3>
Optional dependencies</h3>
<br />
Another use case that the service loader API does not accommodate is the declaration of optional dependencies. In many cases, optional dependencies are not considered a good practice but in reality they offer a convenient way out if dependencies can be combined in a large number of permutations.<br />
<br />
For example, a library might be able to provide better performance if a specific dependency is available. Otherwise, it would fall back to another, less optimal alternative. In order to use the optional dependency, the library is required to compile against its specific API. If this API is however not available at runtime, the library needs to assure that the optional code is never executed and fall back to the available default. Such an optional dependency cannot be expressed in a modularized environment where any declared module dependency is validated upon the application’s startup, even if the dependency was never used.<br />
<br />
A special use-case for optional dependencies are optional annotation bundles. Today, the Java runtime treats annotations as optional metadata. This means that if an annotation’s type cannot be located by a class loader, the Java runtime simply ignores the annotation in question instead of throwing a <code>NoClassDefFoundError</code>. For example, the <a href="http://findbugs.sourceforge.net/">FindBugs</a> application offers an annotation bundle for suppressing potential bugs after a user found the code in question to be a false-positive. During an application’s regular runtime, the FindBugs-specific annotations are not required and are therefore not included in the application bundle. However, when running FindBugs, the utility explicitly adds the annotation package such that the annotations become visible. In project Jigsaw, this is no longer possible. The annotation type is only available if a module declares a dependency to the annotation bundle. If this dependency is later missing at runtime, an error is raised, despite the annotation's irrelevance.<br />
<br />
<h3>
Non-modularization</h3>
<br />
Not bundling a framework as a module in Java 9 is of course the easiest way to avoid all of the discussed restrictions. The Java runtime considers any non-modularized jar-file to be part of a class loader’s so-called <i>unnamed module</i>. This unnamed module defines an implicit dependency on all other modules that exist within the running application and exports all of its packages to any other module. This serves as a fallback when mixing modularized and non-modularized code. Due to the implicit imports and exports of an unnamed module, all non-migrated code should continue to function as before.<br />
<br />
While such an opt-out might be the best solution for a reflection-heavy framework, slow adoption of project Jigsaw does also defeat the purpose of a module system. With a lack of time being the major constraint of most open-source projects, this outcome is unfortunately quite probable. Furthermore, many open-source developers are bound to compiling their libraries to older versions of Java. Due to the different runtime behavior of modularized and non-modularized code, a framework would need to maintain two branches for being able to use Java 9 APIs to traverse module boundaries in the modularized bundle. It is unlikely that many open-source developers would make the time for such a hybrid solution.<br />
<br />
<h3>
Code instrumentation</h3>
<br />
In Java, reflective method access is not the only way of a library to interact with unknown user code. Using the <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html">instrumentation API</a>, it is possible to redefine classes to include additional method calls. This is commonly used to for example implement method-level security or to collect code metrics.<br />
<br />
When instrumenting code, the bytecode of a Java class is typically altered right before it is loaded by a class loader. This can cause unresolvable conflicts if the instrumenting code cannot access a loaded class before its first usage. Currently, there exists no solution to this problem.<br />
<br />
<h3>
Summary</h3>
<br />
Software estimates are difficult and we all tend to underestimate the complexity of our applications. Project Jigsaw imposes a fundamental change to the runtime behavior of Java applications and it makes perfect sense to delay the release until every eventuality is thoroughly evaluated. Currently, there are too many open questions and it is a good choice to delay the release date.<br />
<br />
I would prefer that module boundaries were not enforced by the runtime at all but remain a compiler construct. The Java platform already implements compile-time erasure of generic types and despite some imperfections this solution has worked very well. Without runtime enforcement, modules would also be optional to adopt for dynamic languages on the JVM where the same form of modularization as in Java might not make sense. Finally, I feel that the current strict form of runtime encapsulation tries to solve a problem that does not exist. After working with Java for many years, I have rarely encountered situations where the unintentional usage of internal APIs has caused big problems. In contrast, I remember many occasions where abusing an API that was meant to be private has solved a problem that I could not have worked around. At the same time, other symptoms of lacking modules in Java, often referred to as <a href="https://en.wikipedia.org/wiki/Java_Classloader#JAR_hell"><i>jar hell</i></a>, remain unsolved by Jigsaw which does not distinguish between different versions of a module.<br />
<br />
Finally, I argue that backwards compatibility applies beyond the binary level. As a matter of fact, a binary incompatibility is usually easier to deal with than a behavioral change. Therefore, method contracts should be respected at least as highly as binary compatibility. In this context, Java has done a great job over the years. While project Jigsaw does not technically break method contracts by providing unnamed modules, modularization makes subtle changes to code behavior that is based on its bundling. In my opinion, this will be confusing to both experienced Java developers and newcomers and result in reappearing runtime errors.<br />
<br />
This is why I find the price for enforcing runtime module boundaries too high compared to the benefits that it offers. OSGi, a runtime module system with versioning capabilities already exists for those that really require modularization. As a big benefit, OSGi is implemented on top of the virtual machine and can therefore not influence VM behavior. Alternatively, I think that Jigsaw could include a canonical way for libraries to opt-out of runtime constraints where it makes sense such as for reflection-heavy libraries. </div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com1tag:blogger.com,1999:blog-3237092529299307504.post-40471298442807135292015-03-30T19:44:00.000+02:002015-03-31T14:29:40.137+02:00Dismantling invokedynamic<div dir="ltr" style="text-align: left;" trbidi="on">
Many Java developers regarded the JDK's version seven release as somewhat a disappointment. On the surface, merely a few language and library extensions made it into the release, namely <a href="http://openjdk.java.net/projects/coin/">Project Coin</a> and <a href="https://docs.oracle.com/javase/tutorial/essential/io/fileio.html">NIO2</a>. But under the covers, the seventh version of the platform shipped the single biggest extension to the JVM's type system ever introduced after its initial release. Adding the invokedynamic instruction did not only lay the foundation for implementing lambda expressions in Java 8, it also was a game changer for translating dynamic languages into the Java byte code format.<br />
<br />
While the invokedynamic instruction is an implementation detail for executing a language on the Java virtual machine, understanding the functioning of this instruction gives true insights into the inner workings of executing a Java program. This article gives a beginner's view on what problem the invokedynamic instruction solves and how it solves it.<br />
<br />
<h3>
Method handles</h3>
<br />
Method handles are often described as a retrofitted version of Java's reflection API, but this is not what they are meant to represent. While method handles can represent a method, constructor or field, they are not intended to describe properties of these class members. It is for example not possible to directly extract metadata from a method handle such as modifiers or annotation values of the represented method. And while method handles allow for the invocation of a referenced method, their main purpose is to be used together with an invokedynamic call site. For gaining a better understanding of method handles, looking at them as an imperfect replacement for the reflection API is however a reasonable starting point.<br />
<br />
Method handles cannot be instantiated. Instead, method handles are created by using a designated lookup object. These objects are themselves created by using a factory method that is provided by the <code>MethodHandles</code> class. Whenever this factory is invoked, it first creates a security context which ensures that the resulting lookup object can only locate methods that are also visible to the class from which the factory method was invoked. A lookup object can then be created as follows:<br />
<br />
<pre class="brush: java">class Example {
void doSomething() {
MethodHandles.Lookup lookup = MethodHandles.lookup();
}
private void foo() { /* ... */ }
}</pre>
<br />
As argued before, the above lookup object could only be used to locate methods that are also visible to the <code>Example</code> class such as <code>foo</code>. It would for example be impossible to look up a private method of another class. This is a first major difference to using the reflection API where private methods of outside classes can be located just as any other method and where these methods can even be invoked after marking such a method as accessible. Method handles are therefore sensible of their creation context which is a first major difference to the reflection API.<br />
<br />
Apart from that, a method handle is more specific than the reflection API by describing a specific type of method rather than representing just any method. In a Java program, a method's type is a composite of both the method's return type and the types of its parameters. For example, the only method of the following <code>Counter</code> class returns an <code>int</code> representing the number of characters of the only <code>String</code>-typed argument:<br />
<br />
<pre class="brush: java">class Counter {
static int count(String name) {
return name.length();
}
}</pre>
<br />
A representation of this method's type can be created by using another factory. This factory is found in the <code>MethodType</code> class which also represents instances of created method types. Using this factory, the method type for <code>Counter::count</code> can be created by handing over the method's return type and its parameter types bundled as an array:<br />
<br />
<pre class="brush: java">MethodType methodType = MethodType.methodType(int.class, new Class<?>[] {String.class});</pre>
<br />
By using the lookup object that was created before and the above method type, it is now possible to locate a method handle that represents the <code>Counter::count</code> method as depicted in the following code:<br />
<br />
<pre class="brush: java">MethodType methodType = MethodType.methodType(int.class, new Class<?>[] {String.class});
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle methodHandle = lookup.findStatic(Counter.class, "count", methodType);
int count = methodHandle.invokeExact("foo");
assertThat(count, is(3));</pre>
<br />
At first glance, using a method handle might seem like an overly complex version of using the reflection API. However, keep in mind that the direct invocation of a method using a handle is not the main intent of its use.<br />
<br />
The main difference of the above example code and of invoking a method via the reflection API is only revealed when looking into the differences of how the Java compiler translates both invocations into Java byte code. When a Java program invokes a method, this method is uniquely identified by its name and by its (non-generic) parameter types and even by its return type. It is for this reason that it is possible to overload methods in Java. And even though the Java programming language does not allow it, the JVM does in theory allow to overload a method by its return type.<br />
<br />
Following this principle, a reflective method call is executed as a common method call of the <code>Method::invoke</code> method. This method is identified by its two parameters which are of the types <code>Object</code> and <code>Object[]</code>. In addition to this, the method is identified by its Object return type. Because of this signature, all arguments to this method need to always be boxed and enclosed in an array. Similarly, the return value needs to be boxed if it was primitive or null is returned if the method was void.<br />
<br />
Method handles are the exception to this rule. Instead of invoking a method handle by referring to the signature of <code>MethodHandle::invokeExact</code> signature which takes an <code>Object[]</code> as its single argument and returns <code>Object</code>, method handles are invoked by using a so-called polymorphic signature. A polymorphic signature is created by the Java compiler dependant on the types of the actual arguments and the expected return type at a call site. For example, when invoking the method handle as above with<br />
<br />
<pre class="brush: java">int count = methodHandle.invokeExact("foo");</pre>
<br />
the Java compiler translates this invocation as if the <code>invokeExact</code> method was defined to accept a single single argument of type <code>String</code> and returning an <code>int</code> type. Obviously, such a method does not exist and for (almost) any other method, this would result in a linkage error at runtime. For method handles, the Java Virtual Machine does however recognize this signature to be polymorphic and treats the invocation of the method handle as if the <code>Counter::count</code> method that the handle refers to was inset directly into the call site. Thus, the method can be invoked without the overhead of boxing primitive values or the return type and without placing the argument values inside an array. <br />
<br />
At the same time, when using the <code>invokeExact</code> invocation, it is guaranteed to the Java virtual machine that the method handle always references a method at runtime that is compatible to the polymorphic signature. For the example, the JVM expected that the referenced method actually accepts a <code>String</code> as its only argument and that it returns a primitive <code>int</code>. If this constraint was not fulfilled, the execution would instead result in a runtime error. However, any other method that accepts a single <code>String</code> and that returns a primitive <code>int</code> could be successfully filled into the method handle's call site to replace <code>Counter::count</code>. <br />
<br />
In contrast, using the <code>Counter::count</code> method handle at the following three invocations would result in runtime errors, even though the code compiles successfully:<br />
<br />
<pre class="brush: java">int count1 = methodHandle.invokeExact((Object) "foo");
int count2 = (Integer) methodHandle.invokeExact("foo");
methodHandle.invokeExact("foo");</pre>
<br />
The first statement results in an error because the argument that is handed to the handle is too general. While the JVM expected a <code>String</code> as an argument to the method, the Java compiler suggested that the argument would be an <code>Object</code> type. It is important to understand that the Java compiler took the casting as a hint for creating a different polymorphic signature with an <code>Object</code> type as a single parameter type while the JVM expected a <code>String</code> at runtime. Note that this restriction also holds for handing too specific arguments, for example when casting an argument to an <code>Integer</code> where the method handle required a <code>Number</code> type as its argument. In the second statement, the Java compiler suggested to the runtime that the handle's method would return an <code>Integer</code> wrapper type instead of the primitive <code>int</code>. And without suggesting a return type at all in the third statement, the Java compiler implicitly translated the invocation into a void method call. Hence, <code>invokeExact</code> really does mean exact.<br />
<br />
This restriction can sometimes be too harsh. For this reason, instead of requiring an exact invocation, the method handle also allows for a more forgiving invocation where conversions such as type castings and boxings are applied. This sort of invocation can be applied by using the <code>MethodHandle::invoke</code> method. Using this method, the Java compiler still creates a polymorphic signature. This time, the Java virtual machine does however test the actual arguments and the return type for compatibility at run time and converts them by applying boxings or castings, if appropriate. Obviously, these transformations can sometimes add a runtime overhead. <br />
<br />
<h3 style="text-align: left;">
Fields, methods and constructors: handles as a unified interface</h3>
<br />
Other than <code>Method</code> instances of the reflection API, method handles can equally reference fields or constructors. The name of the <code>MethodHandle</code> type could therefore be seen as too narrow. Effectively, it does not matter what class member is referenced via a method handle at runtime as long as its <code>MethodType</code>, another type with a misleading name, matches the arguments that are passed at the associated call site.<br />
<br />
Using the appropriate factories of a <code>MethodHandles.Lookup</code> object, a field can be looked up to represent a getter or a setter. Using getters or setters in this context does not refer to invoking an actual method that follows the Java bean specification. Instead, the field-based method handle directly reads from or writes to the field but in shape of a method call via invoking the method handle. By representing such field access via method handles, field access or method invocations can be used interchangeably.<br />
<br />
As an example for such interchange, take the following class:<br />
<br />
<pre class="brush: java">class Bean {
String value;
void print(String x) {
System.out.println(x);
}
}</pre>
<br />
For the above <code>Bean</code> class, the following method handles can be used for either writing a string to the value field or for invoking the print method with the same string as an argument:<br />
<br />
<pre class="brush: java">MethodHandle fieldHandle = lookup.findSetter(Bean.class, "value", String.class);
MethodType methodType = MethodType.methodType(void.class, new Class<?>[] {String.class});
MethodHandle methodHandle = lookup.findVirtual(Bean.class, "print", methodType);</pre>
<br />
As long as the method handle call site is handed an instance of Bean together with a <code>String</code> while returning <code>void</code>, both method handles could be used interchangeably as shown here:<br />
<br />
<pre class="brush: java">anyHandle.invokeExact((Bean) mybean, (String) myString);</pre>
<br />
Note that the polymorphic signature of the above call site does <b>not</b> match the method type of the above handle. However, within Java byte code, non-static methods are invoked as if they were static methods with where the this reference is handed as a first, implicit argument. A non-static method's nominal type does therefore diverge from its actual runtime type. Similarly, access to a non-static field requires an instance to be access.<br />
<br />
Similarly to fields and methods, it is possible to locate and invoke constructors which are considered as methods with a <code>void</code> return value for their nominal type. Furthermore, one can not only invoke a method directly but even invoke a super method as long as this super method is reachable for the class from which the lookup factory was created. In contrast, invoking a super method is not possible at all when relying on the reflection API. If required, it is even possible to return a constant value from a handle.<br />
<br />
<h3 style="text-align: left;">
Performance metrics</h3>
<br />
Method handles are often described as being a more performant as the Java reflection API. At least for recent releases of the HotSpot virtual machine, this is not true. The simplest way of proving this is <a href="https://gist.github.com/raphw/881e1745996f9d314ab0">writing an appropriate benchmark</a>. Then again, is not all too simple to write a benchmark for a Java program which is optimized while it is executed. The de facto standard for writing a benchmark has become using JMH, a harness that ships under the OpenJDK umbrella. The full benchmark can be found as a gist in my GitHub profile. In this article, only the most important aspects of this benchmark are covered.<br />
<br />
From the benchmark, it becomes obvious that reflection is already implemented quite efficiently. Modern JVMs know a concept named inflation where a frequently invoked reflective method call is replaced with runtime generated Java byte code. What remains is the overhead of applying the boxing for passing arguments and receiving a return values. These boxings can sometimes be eliminated by the JVM's Just-in-time compiler but this is not always possible. For this reason, using method handles can be more performant than using the reflection API if method calls involve a significant amount of primitive values. This does however require that the exact method signatures are already known at compile time such that the appropriate polymorphic signature can be created. For most use cases of the reflection API, this guarantee can however not be given because the invoked method's types are not known at compile time. In this case, using method handles does not offer any performance benefits and should not be used to replace it.<br />
<br />
<h3 style="text-align: left;">
Creating an invokedynamic call site</h3>
<br />
Normally, invokedynamic call sites are created by the Java compiler only when it needs to translate a lambda expression into byte code. It is worthwhile to note that lambda expressions could have been implemented without invokedynamic call sites altogether, for example by converting them into anonymous inner classes. As a main difference to the suggested approach, using invokedynamic delays the creation of a similar class to runtime. We are looking into class creation in the next section. For now, bear however in mind that invokedynamic does not have anything to do with class creation, it only allows to delay the decision of how to dispatch a method until runtime.<br />
<br />
For a better understanding of invokedynamic call sites, it helps to create such call sites explicitly in order to look at the mechanic in isolation. To do so, the following example makes use of <a href="https://github.com/raphw/byte-buddy">my code generation framework Byte Buddy </a>which provides explicit byte code generation of invokedynamic call sites without requiring a any knowledge of the byte code format.<br />
<br />
Any invokedynamic call site eventually yields a MethodHandle that references the method to be invoked. Instead of invoking this method handle manually, it is however up to the Java runtime to do so. Because method handles have become a known concept to the Java virtual machine, these invocations are then optimized similarly to a common method call. Any such method handle is received from a so-called bootstrap method which is nothing more than a plain Java method that fulfills a specific signature. For a trivial example of a bootstrap method, look at the following code:<br />
<br />
<pre class="brush: java">class Bootstrapper {
public static CallSite bootstrap(Object... args) throws Throwable {
MethodType methodType = MethodType.methodType(int.class, new Class<?>[] {String.class})
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle methodHandle = lookup.findStatic(Counter.class, "count", methodType);
return new ConstantCallSite(methodHandle);
}
}</pre>
<br />
For now, we do not care much about the arguments of the method. Instead, notice that the method is static what is as a matter of fact a requirement. Within Java byte code, an invokedynamic call site references the full signature of a bootstrap method but not a specific object which could have a state and a life cycle. Once the invokedynamic call site is invoked, control flow is handed to the referenced bootstrap method which is now responsible for identifying a method handle. Once this method handle is returned from the bootstrap method, it is invoked by the Java runtime.<br />
<br />
As obvious from the above example, a <code>MethodHandle</code> is not returned directly from a bootstrap method. Instead, the handle is wrapped inside of a <code>CallSite</code> object. Whenever a bootstrap method is invoked, the invokedynamic call site is later permanently bound to the <code>CallSite</code> object that is returned from this method. Consequently, a bootstrap method is only invoked a single time for any call site. Thanks to this intermediate <code>CallSite</code> object, it is however possible to exchange the referenced <code>MethodHandle</code> at a later point. For this purpose, the Java class library already offers different implementations of <code>CallSite</code>. We have already seen a <code>ConstantCallSite</code> in the example code above. As the name suggests, a <code>ConstantCallSite</code> always references the same method handle without a possibility of a later exchange. Alternatively, it is however also possible to for example use a <code>MutableCallSite</code> which allows to change the referenced <code>MethodHandle</code> at a later point in time or it is even possible to implement a custom <code>CallSite</code> class.<br />
<br />
With the above bootstrap method and Byte Buddy, we can now implement a custom invokedynamic instruction. For this, Byte Buddy offers the <code>InvokeDynamic</code> instrumentation that accepts a bootstrap method as its only mandatory argument. Such instrumentations are then fed to Byte Buddy. Assuming the following class:<br />
<br />
<pre class="brush: java">abstract class Example {
abstract int method();
}</pre>
<br />
we can use Byte Buddy to subclass <code>Example</code> in order to override <code>method</code>. We are then going to implement this method to contain a single invokedynamic call site. Without any further configuration, Byte Buddy creates a polymorphic signature that resembles the method type of the overridden method. However, for non-static methods, the <code>this</code> reference is set as a first, implicit argument. Assuming that we want to bind the <code>Counter::count</code> method which expects a <code>String</code> as a single argument, we could not bind this handle to <code>Example::method</code> because of this type mismatch. Therefore, we need to create a different call site without the implicit argument but with an <code>String</code> in its place. This can be achieved by using Byte Buddy's domain specific language:<br />
<br />
<pre class="brush: java">Instrumentation invokeDynamic = InvokeDynamic
.bootstrap(Bootstrapper.class.getDeclaredMethod(“bootstrap”, Object[].class))
.withoutImplicitArguments()
.withValue("foo");</pre>
<br />
With this instrumentation in place, we can finally extend the Example class and override method to implement the invokedynamic call site as in the following code snippet:<br />
<br />
<pre class="brush: java">Example example = new ByteBuddy()
.subclass(Example.class)
.method(named(“method”)).intercept(invokeDynamic)
.make()
.load(Example.class.getClassLoader(),
ClassLoadingStrategy.Default.INJECTION)
.getLoaded()
.newInstance();
int result = example.method();
assertThat(result, is(3));</pre>
<br />
As obvious from the above assertion, the characters of the <code>"foo"</code> string were counted correctly. By setting appropriate break points in the code, it is further possible to validate that the bootstrap method is called and that control flow further reaches the <code>Counter::count</code> method.<br />
<br />
So far, we did not gain much from using an invokedynamic call site. The above bootstrap method would always bind <code>Counter::count</code> and can therefore only produce a valid result if the invokedynamic call site really wanted to transform a <code>String</code> into an <code>int</code>. Obviously, bootstrap methods can however be more flexible thanks to the arguments they receive from the invokedynamic call site. Any bootstrap method receives at least three arguments: <br />
<br />
As a first argument, the bootstrap method receives a <code>MethodHandles.Lookup</code> object. The security context of this object is that of the class that contains the invokedynamic call site that triggered the bootstrapping. As discussed before, this implies that private methods of the defining class could be bound to the invokedynamic call site using this lookup instance.<br />
The second argument is a <code>String</code> representing a method name. This string serves as a hint to indicate from the call site which method should be bound to it. Strictly speaking, this argument is not required as it is perfectly legal to bind a method with another name. Byte Buddy simply serves the the name of the overridden method as this argument, if not specified differently.<br />
Finally, the <code>MethodType</code> of the method handle that is expected to be returned is served as a third argument. For the example above, we specified explicitly that we expect a <code>String</code> as a single parameter. At the same time, Byte Buddy derived that we require an int as a return value from looking at the overridden method, as we again did not specify any explicit return type.<br />
<br />
It is up to the implementor of a bootstrap method what exact signature this method should portray as long as it can at least accept these three arguments. If the last parameter of a bootstrap method represents an <code>Object</code> array, this last parameter is treated as a varargs and can therefore accept any excess arguments. This is also the reason why the above example bootstrap method is valid.<br />
<br />
Additionally, a bootstrap method can receive several arguments from an invokedynamic call site as long as these arguments can be stored in a class's constant pool. For any Java class, a constant pool stores values that are used inside of a class, largely numbers or string values. As of today, such constants can be primitive values of at least 32 bit size, <code>String</code>s, <code>Class</code>es, <code>MethodHandl</code>es and <code>MethodType</code>s. This allows bootstrap methods to be used more flexible, if locating a suitable method handle requires additional information in form of such arguments. <br />
<br />
<h3 style="text-align: left;">
Lambda expressions</h3>
<br />
Whenever the Java compiler translates a lambda expression into byte code, it copies the lambda's body into a private method inside of the class in which the expression is defined. These methods are named <code>lambda$X$Y</code> with <code>X</code> being the name of the method that contains the lambda expression and with <code>Y</code> being a zero-based sequence number. The parameters of such a method are those of the functional interface that the lambda expression implements. Given that the lambda expression makes no use of non-static fields or methods of the enclosing class, the method is also defined to be static.<br />
<br />
For compensation, the lambda expression is itself substituted by an invokedynamic call site. On its invocation, this call site requests the binding of a factory for an instance of the functional interface. As arguments to this factory, the call site supplies any values of the lambda expression's enclosing method which are used inside of the expression and a reference to the enclosing instance, if required. As a return type, the factory is required to provide an instance of the functional interface. <br />
<br />
For bootstrapping a call site, any invokedynamic instruction currently delegates to the <code>LambdaMetafactory</code> class which is included in the Java class library. This factory is then responsible for creating a class that implements the functional interface and which invokes the appropriate method that contains the lambda's body which, as described before, is stored in the original class. In the future, this bootstrapping process might however change which is one of the major advantages of using invokedynamic for implementing lambda expressions. If one day, a better suited language feature was available for implementing lambda expressions, the current implementation could simply be swapped out.<br />
<br />
In order to being able to create a class that implements the functional interface, any call site representing a lambda expression provides additional arguments to the bootstrap method. For the obligatory arguments, it already provides the name of the functional interface's method. Also, it provides a <code>MethodType</code> of the factory method that the bootstrapping is supposed to yield as a result. Additionally, the bootstrap method is supplied another <code>MethodType</code> that describes the signature of the functional interface's method. To that, it receives a <code>MethodHandle</code> referencing the method that contains the lambda's method body. Finally, the call site provides a <code>MethodType</code> of the generic signature of the functional interface's method, i.e. the signature of the method at the call site before type-erasure was applied.<br />
<br />
When invoked, the bootstrap method looks at these arguments and creates an appropriate implementation of a class that implements the functional interface. This class is created using the <a href="http://asm.ow2.org/">ASM library</a>, a low-level byte code parser and writer that has become the de facto standard for direct Java byte code manipulation. Besides implementing the functional interface's method, the bootstrap method also adds an appropriate constructor and a static factory method for creating instances of the class. It is this factory method that is later bound to the invokedyanmic call site. As arguments, the factory receives an instance to the lambda method's enclosing instance, in case it is accessed and also any values that are read from the enclosing method.<br />
<br />
As an example, consider the following lambda expression:<br />
<br />
<pre class="brush: java">class Foo {
int i;
void bar(int j) {
Consumer consumer = k -> System.out.println(i + j + k);
}
}</pre>
<br />
In order to be executed, the lambda expression requires access to both the enclosing instance of <code>Foo</code> and to the value j of its enclosing method. Therefore, the desugared version of the above class looks something like the following where the invokedynamic instruction is represented by some pseudo-code:<br />
<br />
<pre class="brush: java">class Foo {
int i;
void bar(int j) {
Consumer consumer = <invokedynamic(this, j)>;
}
private /* non-static */ void lambda$foo$0(int j, int k) {
System.out.println(this.i + j + k);
}
}</pre>
<br />
In order to being able to invoke <code>lambda$foo$0</code>, both the enclosing <code>Foo</code> instance and the <code>j</code> variable are handed to the factory that is bound by the invokedyanmic instruction. This factory then receives the variables it requires in order to create an instance of the generated class. This generated class would then look something like the following:<br />
<br />
<pre class="brush: java">class Foo$$Lambda$0 implements Consumer {
private final Foo _this;
private final int j;
private Foo$$Lambda$0(Foo _this, int j) {
this._this = _this;
this.j = j;
}
private static Consumer get$Lambda(Foo _this, int j) {
return new Foo$$Lambda$0(_this, j);
}
public void accept(Object value) { // type erasure
_this.lambda$foo$0(_this, j, (Integer) value);
}
}</pre>
<br />
Eventually, the factory method of the generated class is bound to the invokedynamic call site via a method handle that is contained by a <code>ConstantCallSite</code>. However, if the lambda expression is fully stateless, i.e. it does not require access to the instance or method in which it is enclosed, the <code>LambdaMetafactory</code> returns a so-called constant method handle that references an eagerly created instance of the generated class. Hence, this instance serves as a singleton to be used for every time that the lambda expression's call site is reached. Obviously, this optimization decision affects your application's memory footprint and is something to keep in mind when writing lambda expressions. Also, no factory method is added to a class of a stateless lambda expression.<br />
<br />
You might have noticed that the lambda expression's method body is contained in a private method which is now invoked from another class. Normally, this would result in an illegal access error. To overcome this limitation, the generated classes are loaded using so-called anonymous class loading. Anonymous class loading can only be applied when a class is loaded explicitly by handing a byte array. Also, it is not normally possible to apply anonymous class loading in user code as it is hidden away in the internal classes of the Java class library. When a class is loaded using anonymous class loading, it receives a host class of which it inherits its full security context. This involves both method and field access rights and the protection domain such that a lambda expression can also be generated for signed jar files. Using this approch, lambda expression can be considered more secure than anonymous inner classes because private methods are never reachable from outside of a class.<br />
<br />
<h3 style="text-align: left;">
Under the covers: lambda forms</h3>
<br />
Lambda forms are an implementation detail of how MethodHandles are executed by the virtual machine. Because of their name, lambda forms are however often confused with lambda expressions. Instead, lambda forms are inspired by lambda calculus and received their name for that reason, not for their actual usage to implement lambda expressions in the OpenJDK.<br />
<br />
In earlier versions of the OpenJDK 7, method handles could be executed in one of two modes. Method handles were either directly rendered as byte code or they were dispatched using explicit assembly code that was supplied by the Java runtime. The byte code rendering was applied to any method handle that was considered to be fully constant throughout the lifetime of a Java class. If the JVM could however not prove this property, the method handle was instead executed by dispatching it to the supplied assembly code. Unfortunately, because assembly code cannot be optimized by Java's JIT-compiler, this lead to non-constant method handle invocations to "fall off the performance cliff". As this also affected the lazily bound lambda expressions, this was obviously not a satisfactory solution. <br />
<br />
<code>LambdaForm</code>s were introduced to solve this problem. Roughly speaking, lambda forms represent byte code instructions which, as stated before, can be optimized by a JIT-compiler. In the OpenJDK, a <code>MethodHandle</code>'s invocation semantics are today represented by a <code>LambdaForm</code> to which the handle carries a reference. With this optimizable intermediate representation, the use of non-constant <code>MethodHandle</code>s has become significantly more performant. As a matter of fact, it is even possible to see a byte-code compiled <code>LambdaForm</code> in action. Simply place a break point inside of a bootstrap method or inside of a method that is invoked via a <code>MethodHandle</code>. Once the break point kicks it, the byte code-translated <code>LambdaForm</code>s can be found on the call stack.<br />
<br />
<h3 style="text-align: left;">
Why this matters for dynamic languages</h3>
<br />
Any language that should be executed on the Java virtual machine needs to be translated to Java byte code. And as the name suggests, Java byte code aligns rather close to the Java programming language. This includes the requirement to define a strict type for any value and before invokedynamic was introduced, a method call required to specify an explicit target class for dispatching a method. Looking at the following JavaScript code, specifying either information is however not possible when translating the method into byte code:<br />
<br />
<pre class="brush: javascript">function (foo) {
foo.bar();
}</pre>
<br />
Using an invokedynamic call site, it has become possible to delay the identification of the method's dispatcher until runtime and furthermore, to rebind the invocation target, in case that a previous decision needs to be corrected. Before, using the reflection API with all of its performance drawbacks was the only real alternative to implementing a dynamic language.<br />
<br />
The real profiteer of the invokedynamic instruction are therefore dynamic programming languages. Adding the instruction was a first step away from aligning the byte code format to the Java programming language, making the JVM a powerful runtime even for dynamic languages. And as lambda expressions proved, this stronger focus on hosting dynamic languages on the JVM does neither interfere with evolving the Java language. In contrast, the Java programming languages gained from these efforts.</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com2tag:blogger.com,1999:blog-3237092529299307504.post-13328270319398674562015-01-09T08:54:00.000+01:002015-01-09T09:21:02.014+01:00Make agents, not frameworks<div dir="ltr" style="text-align: left;" trbidi="on">
Ever since their introduction, <a href="http://docs.oracle.com/javase/tutorial/java/annotations/">Java annotations</a> have become an integral part of the APIs of larger application frameworks. Good examples for such APIs are those of Spring or Hibernate where adding a few lines of annotation code implements quite complex program logic. And while one can argue about the drawbacks of these particular APIs, most developers would agree that this form of declarative programming is quite expressive when used right. However, only few developers choose to implement annotation-based APIs for their own frameworks or application middleware, mainly because they are regarded as difficult to realize. In the following article, I want to convince you that such APIs are in contrast quite trivial to implement and, using the right tools, do not require any special knowledge of Java intrinsics.<br />
<br />
One problem that becomes quite obvious when implementing an annotation-based API is that annotations are not being handled by an executing Java runtime. As a consequence, it is not possible to assign a specific meaning to a given user annotation. For example, consider that we wanted to define a <code>@Log</code> annotation which we want to provide for simply logging each invocation of an annotated method:<br />
<br />
<pre class="brush: java">class Service {
@Log
void doSomething() {
// do something ...
}
}</pre>
<br />
As the <code>@Log</code> annotation is not capable of executing program logic by its mere existence, it would be up to the annotation's user to perform the requested logging. Obviously, this renders the annotation almost useless as we cannot invoke the <code>doSomething</code> method and expect to observe a corresponding statement in our log. So far, the annotation only serves as a marker without contributing any program logic.<br />
<br />
<h3 style="text-align: left;">Bridging the gap</h3>
<br/>
In order to overcome this glaring limitation, many annotation-driven frameworks use subclassing in combination with method overriding to implement the logic that is associated with a particular annotation. This is commonly referred to as subclass instrumentation. For the proposed <code>@Log</code> annotation, subclass instrumentation would result in creating a class similar to the following <code>LoggingService</code>:<br />
<br />
<pre class="brush: java">class LoggingService extends Service {
@Override
void doSomething() {
Logger.log("doSomething() was called");
super.doSomething();
}
}</pre>
<br />
Of course, the above class does not normally need to be implemented explicitly. Instead, it is a popular approach to generate such classes only at runtime using a code generation library such as <a href="http://sourceforge.net/projects/cglib/">cglib</a> or <a href="http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/">Javassist</a>. Both these libraries offer simple APIs for creating program enhancing subclasses. As a nice side effect of delaying the class's creation until runtime, the proposed logging framework would be usable without any specific preparation and would always stay in sync with the user's code. Neither would be the case if the class would be created in a more explicit manner, for example by writing a Java source file during a build process.<br />
<br />
<h3 style="text-align: left;">
But, does it scale?</h3>
<br/>
However, this solution brings along another drawback. By placing the annotation's logic into the generated subclass, one must not longer instantiate the example <code>Service</code> class by its constructor. Otherwise, invocations of annotated methods would still not be logged: Obviously, calling the constructor does not create an instance of the required subclass. And to make things worse - when using the suggested approach of runtime generation - the <code>LoggingService</code> cannot be instantiated directly either as the Java compiler does not know about the runtime-generated class.<br />
<br />
For this reason, frameworks such as Spring or Hibernate use object factories and do not allow for direct instantiation of objects that are considered to be a part of their framework logic. With Spring, creating objects by a factory comes naturally as all of Spring's objects are already managed beans which are to be created by the framework in the first place. Similarly, most Hibernate entities are created as a result of a query and are thus not instantiated explicitly. However, when for example saving an entity instance that is not yet represented in the database, a user of Hibernate needs to substitute a recently saved instance with an instance that is returned from Hibernate after storage. From looking at questions on Hibernate, ignoring this substitution already renders a common beginner's mistake. Other than that, thanks to these factories in place, subclass instrumentation happens mostly transparent to a framework user because Java's type system implies that a subclass can substitute any of its super classes. Hence, an instance of <code>LoggingService</code> can be used everywhere a user would expect an instance of the user-defined <code>Service</code> class.<br />
<br />
Unfortunately, this approved method of instance factories proves difficult for implementing the proposed <code>@Log</code> annotation as this would entail using a factory for every single instance of a potentially annotated class. Obviously, this would add a tremendous amount of boilerplate code. Probably, we would even create more boilerplate than we avoid by not hard-coding the logging instruction into the methods. Also, the accidental use of a constructor would introduce subtle bugs to a Java program because the annotations on such instances would not longer be treated as we expect them to be. As another problem, factories are not easily composable. What if we wanted to add a <code>@Log</code> annotation to a class that already is a Hibernate bean? This sounds trivial but would require extensive configuration to merge both framework's factories. And finally, the resulting, factory-bloated code would not turn out too pretty to read and migrations to using the framework would be costly to implement. This is where instrumentation with Java agents comes into place. This underestimated form of instrumentation offers a great alternative to the discussed subclass instrumentation.<br />
<br />
<h3 style="text-align: left;">
A simple agent</h3>
<br/>
A Java agent is represented by a simple jar file. Similarly to normal Java programs, Java agents define some class as an entry point. This class is then expected to define a static method which is invoked before the actual Java program's <code>main</code> method is called:<br />
<br />
<pre class="brush: java">class MyAgent {
public static void premain(String args, Instrumentation inst) {
// implement agent here ...
}
}</pre>
<br />
The most interesting part when dealing with Java agents is the <code>premain</code> method's second argument which represents an instance of the <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/instrument/Instrumentation.html"><code>Instrumentation</code></a> interface. This interface offers a way of hooking into Java's class loading process by defining a <code>ClassFileTransformer</code>. With such transformers, we are able to enhance any class of a Java program before its first use.<br />
<br />
While using this API might sound straight forward at first, it imposes a new challenge. Class file transformations are executed by altering compiled Java classes which are represented as Java byte code. As a matter of fact, the Java virtual machine has no notion of what Java, the programming language is. Instead, it only deals with this byte code. And it is also thanks to this byte code abstraction that the JVM is easily capable of running other languages such as Scala or Groovy. As a consequence, a registered class file transformer only offers to transform a given byte (code) array into another one.<br />
<br />
Even though libraries such as <a href="http://asm.ow2.org/">ASM</a> or <a href="http://commons.apache.org/proper/commons-bcel/">BCEL</a> offer an easy API for manipulating compiled Java classes, only few developers are experienced in working with raw byte code. To make things worse, getting byte code manipulation right is often cumbersome and even small mistakes are redeemed by the virtual machine with throwing a nasty and unrecoverable <code>VerifierError</code>. Fortunately, there are better, easier ways to manipulate byte code.<br />
<br />
<a href="https://github.com/raphw/byte-buddy">Byte Buddy</a>, a library that I wrote and maintain, provides a simple API both for manipulating compiled Java classes and for creating Java agents. In some aspects, Byte Buddy is a code generation library similar to cglib and Javassist. However, other than those libraries, Byte Buddy offers a unified API for implementing subclasses and for redefining existing classes. For this article, we do however only want to look into redefining a class using a Java agent. Curious readers are referred to <a href="http://bytebuddy.net/#/tutorial">Byte Buddy's webpage which offers a detailed tutorial</a> on its full feature set.<br />
<br />
<h3 style="text-align: left;">
Using Byte Buddy for a simple agent</h3>
<br/>
One way that Byte Buddy offers for defining an instrumentation, is using dependency injection. Doing so, an interceptor class - which is represented by any plain old Java object - simply requests any required information by annotations on its parameters. For example, by using Byte Buddy's <code>@Origin</code> annotation on a parameter of the <code>Method</code> type, Byte Buddy deducts that the interceptor wants to know about the method that is being intercepted. This way, we can define a generic interceptor that is always aware of the method that is being intercepted:<br />
<br />
<pre class="brush: java">class LogInterceptor {
static void log(@Origin Method method) {
Logger.log(method + " was called");
}
}</pre>
<br />
Of course, Byte Buddy ships with many more annotations.<br />
<br />
But how does this interceptor represent the logic that we intended for the proposed logging framework? So far, we only defined an interceptor that is logging the method call. What we miss is the subsequent invocation of the original code of the method. Fortunately, Byte Buddy's instrumentations are composable. First, we define a <code>MethodDelegation</code> to the recently defined <code>LogInterceptor</code> which by default invokes the interceptor's static method on every call of a method. Starting from this, we can then compose the delegation with a subsequent call of the original method's code which is represented by <code>SuperMethodCall</code>:<br />
<br />
<pre class="brush: java">MethodDelegation.to(LogInterceptor.class)
.andThen(SuperMethodCall.INSTANCE)</pre>
<br />
Finally, we need to inform Byte Buddy on the methods that are to be intercepted by the specified instrumentation. As we explained before, we want this instrumentation to apply for any method that is annotated with <code>@Log</code>. Within Byte Buddy, such a property of a method can be identified using an <code>ElementMatcher</code> which is similar to a Java 8 predicate. In the static utility class <code>ElementMatchers</code>, we can already find a suitable matcher for identifying methods with a given annotation: <code>ElementMatchers.isAnnotatedWith(Log.class)</code>.<br />
<br />
With all this, we can now define an agent that implements the suggested logging framework. For Java agents, Byte Buddy provides a utility API that builds on the class modification API that we just discussed. Similarly to this latter API, it is designed as a domain specific language such that its meaning should be easily understood only by looking at the implementation. As we can see, defining such an agent only requires a few lines of code:<br />
<br />
<pre class="brush: java">class LogAgent {
public static void premain(String args, Instrumentation inst) {
new AgentBuilder.Default()
.rebase(ElementMatchers.any())
.transform( builder -> return builder
.method(ElementMatchers.isAnnotatedWith(Log.class))
.intercept(MethodDelegation.to(LogInterceptor.class)
.andThen(SuperMethodCall.INSTANCE)) )
.installOn(inst);
}
}</pre>
<br />
Note that this minimal Java agent would not interfere with the remainder of the application as any executing code observes the instrumented Java classes just as if the logging statement was hard-coded into any annotated method.<br />
<br />
<h3 style="text-align: left;">
What about real life?</h3>
<br/>
Of course the presented agent-based logger is a trivial example. And often, broadly-scoped frameworks that offer similar features out-of-the-box such for example Spring or Dropwizard are great. However, such frameworks are equally often opinionated about how to approach programming problems. For a large number of software applications, this might not be a problem. And yet, sometimes these opinions are in the way of something bigger. Then, working around a framework's assumption on how to do things can cause more than just a few problems, often causes leaky abstractions and might just result in exploding costs for software maintenance. This is true especially when applications grow and change over time and diverge in their needs from what an underlying framework offers.<br />
<br />
In contrast, when composing more specialized frameworks or libraries in a <i>pic n mix</i> fashion, one simply replaces problematic components with another one. And if this does not work either, one can even implement a custom solution without interfering with the rest of the application. As we learned, this seems difficult to realize on the JVM, mainly as a consequence of Java's strict type system. Using Java agents, it is however very much possible to overcome these typing constraints.<br />
<br />
I came to the point where I believe that at least any cross-cutting concern should be covered by an agent-driven, specialized library instead of by a built-in module of a monolithic framework. And I really wish more applications would consider this approach. In the most trivial case, it is enough to use an agent to register listeners on methods of interest and to take it from there. This indirect approach of composing code modules avoids the strong cohesion that I observe in a large fraction of the Java applications I come across. As a nice side effect, It also makes testing very easy. And similarly to running tests, not adding an agent when starting up an application, allows to pointedly disable a certain application feature like for example logging. All this without changing a line of code and without crashing the application as the JVM simply ignores annotations that it cannot resolve at runtime. Security, logging, caching, there are many reasons that these topics and more should be taken care of in the suggested manner. Therefore, sometimes, make agents, not frameworks.
</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com5tag:blogger.com,1999:blog-3237092529299307504.post-5445326702459235462014-05-16T11:22:00.001+02:002014-05-19T13:19:01.500+02:00Java 8 default methods can break your (users') code<div dir="ltr" style="text-align: left;" trbidi="on">
At first glance, <a href="http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html">default methods</a> brought a great new feature to the Java Virtual Machine's instruction set. Finally, library developers are able to evolve established APIs without introducing incompatibilities to their user's code. Using default methods, any user class that implements a library interface automatically adopts the default code when a new method is introduced to this interface. And once a user updates his implementing classes, he can simply override the default with something more meaningful to his particular use case. Even better, the user can call the default implementation of the interface from the overridden method and add logic around it.<br />
<br />
So far, so good. However, adding default methods to established interfaces can render Java code uncompilable. This is easiest to understand when looking at an example. Let us assume a library that requires a class of one of its interfaces as its input:<br />
<br />
<pre class="brush: java">interface SimpleInput {
void foo();
void bar();
}
abstract class SimpleInputAdapter implements SimpleInput {
@Override
public void bar() {
// some default behavior ...
}
}</pre>
<br />
Prior to Java 8, the above combination of an interface and a corresponding adapter class is a rather common pattern in the Java programming language. The adapter is usually offered by the library supplier to save the library's users some typing. However, the interface is offered additionally in order to allow an approximation of multiple inheritance.<br />
<br />
Let us further assume that a user made use of this adapter:<br />
<br />
<pre class="brush: java">class MyInput extends SimpleInputAdapter {
@Override
public void foo() {
// do something ...
}
@Override
public void bar() {
super.bar();
// do something additionally ...
}
}</pre>
<br />
With this implementation, the user can finally interact with the library. Note how the implementation overrides the bar method to add some functionality to the default implementation.<br />
<br />
So what happens if the library migrates to Java 8? First of all, the library will most likely deprecate the adapter class and move the functionality to default methods. As a result, the interface will now look like this:<br />
<br />
<pre class="brush: java">interface SimpleInput {
void foo();
default void bar() {
// some default behavior
}
}
</pre>
<br />
With this new interface, a user can update his code to adapt the default method instead of using the adapter class. The great thing about using interfaces instead of adapter classes is the ability to extend another class than the particular adapter. Let's put this into action and migrate the <code>MyInput</code> class to use the default method instead. Because we can now extend another class, let us additionally extend some third party base class. What this base class does is not of particular relevance here, so let us just assume that this makes sense for our use-case.<br />
<br />
<pre class="brush: java">class MyInput extends ThirdPartyBaseClass implements SimpleInput {
@Override
public void foo() {
// do something ...
}
@Override
public void bar() {
SimpleInput.super.bar();
// do something additionally ...
}
}
</pre>
<br />
To implement similar behavior as in the original class, we make use of Java 8's new syntax for calling a default method of a specific interface. Also, we moved the logic for <code>myMethod</code> to some base class <code>MyBase</code>. Clap on our shoulders. Nice refactoring here!<br />
<br />
The library we are using is a great success. However, the maintainer needs to add another interface to offer more functionality. This interface represents a <code>ComplexInput</code> which extends the <code>SimpleInput</code> with an additional method. Because default methods are in general considered as being <i>safe to add</i>, the maintainer additionally overrides the <code>SimpleInput</code>'s default method and adds some behavior to offer a better default. After all, doing so was quite common when implementing adapter classes:<br />
<br />
<pre class="brush: java">interface ComplexInput extends SimpleInput {
void qux();
@Override
default void bar() {
SimpleInput.super.bar();
// so complex, we need to do more ...
}
}
</pre>
<br />
This new feature turns out so great that the maintainer of the <code>ThirdPartyBaseClass</code> decided to also rely on this library. For making this work, he implements the <code>ComplexInput</code> interface for the <code>ThirdPartyLibrary</code>.<br />
<br />
But what does that mean to the <code>MyInput</code> class? Due to the implicit implementation of <code>ComplexInput</code> by extending <code>ThirdPartyBaseClass</code>, calling the default method of <code>SimpleInput</code> has suddenly become illegal. As a result, the user's code does not longer compile. Also, it is now generally forbidden to call this method since Java sees this call as illegal as calling a super-super method of an indirect super class. Instead, you could call the default method of the <code>ComplexInput</code> class. However, this would require you to first explicitly implement this interface in <code>MyInput</code>. For the user of the library, this change comes most likely rather unexpected!<br />
<br />
Oddly enough, the Java runtime does not make this distinction. The JVM's verifier will allow a compiled class to call <code>SimpleInput::foo</code> even if the loaded class at run time implicitly implements the <code>ComplexClass</code> by extending the updated version of <code>ThirdPartyBaseClass</code>. It is only the compiler that complains here.<br />
<br />
But what do we learn from this? In a nutshell, make sure to never override a default method in another interface. Neither with another default method, nor with an abstract method. In general, be careful about using default methods at all. As much as they ease the evolution of established APIs as Java's collection interfaces, they are intrinsically complex by allowing to perform method invocations that go sideways in your type hierarchy. Before Java 7, you would only need to look for the actually invoked code by traversing down a linear class hierarchy. Only add this complexity when you really feel it is absolutely necessary.</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com1tag:blogger.com,1999:blog-3237092529299307504.post-36818633337850101412013-12-12T22:28:00.002+01:002018-04-07T23:23:31.098+02:00The infamous sun.misc.Unsafe explained<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
The biggest competitor to the Java virtual machine might be <a href="http://msdn.microsoft.com/en-us/library/8bs2ecf4%28v=vs.110%29.aspx">Microsoft's CLR</a> that hosts languages such as C#. The CLR allows to write <a href="http://msdn.microsoft.com/de-de/library/chfa2zb8%28v=vs.90%29.aspx">unsafe</a> code as an entry gate for low level programming, something that is hard to achieve on the JVM. If you need such advanced functionality in Java, you might be forced to use the <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/jni/">JNI</a> which requires you to know some C and will quickly lead to code that is tightly coupled to a specific platform. With <a href="http://sun.misc.unsafe/"><code>sun.misc.Unsafe</code></a>, there is however another alternative to low-level programming on the Java plarform using a Java API, even though this alternative is <a href="http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html">discouraged</a>. Nevertheless, several applications rely on <code>sun.misc.Unsafe</code> such for example <a href="http://code.google.com/p/objenesis/">objenesis</a> and therewith all libraries that build on the latter such for example <a href="https://github.com/EsotericSoftware/kryo">kryo</a> which is again used in for example <a href="http://storm-project.net/">Twitter's Storm</a>. Therefore, it is time to have a look, especially since the functionality of <code>sun.misc.Unsafe</code> is considered to <a href="http://openjdk.5641.n7.nabble.com/Turn-sun-misc-Unsafe-into-a-public-API-td158365.html">become part of Java's public API in Java 9</a>.<br />
<br />
<h3 style="text-align: left;">
Getting hold of an instance of sun.misc.Unsafe</h3>
<br />
The <code>sun.misc.Unsafe</code> class is intended to be only used by core Java classes which is why its authors made its only constructor private and only added an equally private singleton instance. The public getter for this instances performs a security check in order to avoid its public use:<br />
<br />
<pre class="brush: java">public static Unsafe getUnsafe() {
Class cc = sun.reflect.Reflection.getCallerClass(2);
if (cc.getClassLoader() != null)
throw new SecurityException("Unsafe");
return theUnsafe;
}</pre>
<br />
This method first looks up the calling <code>Class</code> from the current thread’s method stack. This lookup is implemented by another internal class named <code>sun.reflection.Reflection</code> which is basically browsing down the given number of call stack frames and then returns this method’s defining class. This security check is however likely to <a href="http://www.infoq.com/news/2013/07/Oracle-Removes-getCallerClass">change in future version</a>. When browsing the stack, the first found class (index <code>0</code>) will obviously be the <code>Reflection</code> class itself, and the second (index <code>1</code>) class will be the <code>Unsafe</code> class such that index <code>2</code> will hold your application class that was calling <code>Unsafe#getUnsafe()</code>. <br />
<br />
This looked-up class is then checked for its <code>ClassLoader</code> where a <code>null</code> reference is used to represent the bootstrap class loader on a HotSpot virtual machine. (This is documented in <code>Class#getClassLoader()</code> where it says that “<i>some implementations may use null to represent the bootstrap class loader</i>”.) Since no non-core Java class is normally ever loaded with this class loader, you will therefore never be able to call this method directly but receive a thrown <code>SecurityException</code> as an answer. (Technically, you could force the VM to load your application classes using the bootstrap class loader by adding it to the <code>–Xbootclasspath</code>, but this would require some setup outside of your application code which you might want to avoid.) Thus, the following test will succeed:<br />
<br />
<pre class="brush: java">@Test(expected = SecurityException.class)
public void testSingletonGetter() throws Exception {
Unsafe.getUnsafe();
}</pre>
<br />
However, the security check is poorly designed and should be seen as a warning against the <a href="http://en.wikipedia.org/wiki/Singleton_pattern">singleton anti-pattern</a>. As long as the use of <a href="http://docs.oracle.com/javase/tutorial/reflect/">reflection is not prohibited</a> (which is hard since it is so widely used in many frameworks), you can always get hold of an instance by inspecting the private members of the class. From the <code>Unsafe</code> class's source code, you can learn that the singleton instance is stored in a private static field called <code>theUnsafe</code>. This is at least true for the HotSpot virtual machine. Unfortunately for us, other virtual machine implementations sometimes use other names for this field. Android’s <code>Unsafe</code> class is for example storing its singleton instance in a field called <code>THE_ONE</code>. This makes it hard to provide a “compatible” way of receiving the instance. However, since we already left the save territory of compatibility by using the <code>Unsafe</code> class, we should not worry about this more than we should worry about using the class at all. For getting hold of the singleton instance, you simply read the singleton field's value:<br />
<br />
<pre class="brush: java">Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
</pre>
<br />
Alternatively, you can invoke the private instructor. I do personally prefer this way since it works for example with Android while extracting the field does not:<br />
<br />
<pre class="brush: java">Constructor<Unsafe> unsafeConstructor = Unsafe.class.getDeclaredConstructor();
unsafeConstructor.setAccessible(true);
Unsafe unsafe = unsafeConstructor.newInstance();
</pre>
<br />
The price you pay for this minor compatibility advantage is a minimal amount of heap space. The security checks performed when using reflection on fields or constructors are however similar.<br />
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
Create an instance of a class without calling a constructor</h3>
<div style="text-align: left;">
</div>
<br />
The first time I made use of the <code>Unsafe</code> class was for creating an instance of a class without calling any of the class's constructors. I needed to proxy an entire class which only had a rather <i>noisy</i> constructor but I only wanted to delegate all method invocations to a real instance which I did however not know at the time of construction. Creating a subclass was easy and if the class had been represented by an interface, creating a proxy would have been a straight-forward task. With the expensive constructor, I was however stuck. By using the <code>Unsafe</code> class, I was however able to work my way around it. Consider a class with an artificially expensive constructor:<br />
<br />
<pre class="brush: java">class ClassWithExpensiveConstructor {
private final int value;
private ClassWithExpensiveConstructor() {
value = doExpensiveLookup();
}
private int doExpensiveLookup() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
}
public int getValue() {
return value;
}
}
</pre>
<br />
Using the <code>Unsafe</code>, we can create an instance of <code>ClassWithExpensiveConstructor</code> (or any of its subclasses) without having to invoke the above constructor, simply by allocating an instance directly on the heap:<br />
<br />
<pre class="brush: java">@Test
public void testObjectCreation() throws Exception {
ClassWithExpensiveConstructor instance = (ClassWithExpensiveConstructor)
unsafe.allocateInstance(ClassWithExpensiveConstructor.class);
assertEquals(0, instance.getValue());
}
</pre>
<br />
Note that final field remained uninitialized by the constructor but is set with <a href="http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">its type's default value</a>. Other than that, the constructed instance behaves like a normal Java object. It will for example be garbage collected when it becomes unreachable.<br />
<br />
The Java run time itself creates objects without calling a constructor when for example creating objects for deserialization. Therefore, the <a href="http://www.docjar.com/html/api/sun/reflect/ReflectionFactory.java.html"><code>ReflectionFactory</code></a> offers even more access to individual object creation:<br />
<br />
<pre class="brush: java">@Test
public void testReflectionFactory() throws Exception {
@SuppressWarnings("unchecked")
Constructor<ClassWithExpensiveConstructor> silentConstructor = ReflectionFactory.getReflectionFactory()
.newConstructorForSerialization(ClassWithExpensiveConstructor.class, Object.class.getConstructor());
silentConstructor.setAccessible(true);
assertEquals(10, silentConstructor.newInstance().getValue());
}</pre>
<br />
Note that the <code>ReflectionFactory</code> class only requires a <code>RuntimePermission</code> called <code>reflectionFactoryAccess</code> for receiving its singleton instance and no reflection is therefore required here. The received instance of <code>ReflectionFactory</code> allows you to define any constructor to <i>become</i> a constructor for the given type. In the example above, I used the default constructor of <code>java.lang.Object</code> for this purpose. You can however use any constructor:<br />
<br />
<pre class="brush: java">class OtherClass {
private final int value;
private final int unknownValue;
private OtherClass() {
System.out.println("test");
this.value = 10;
this.unknownValue = 20;
}
}
@Test
public void testStrangeReflectionFactory() throws Exception {
@SuppressWarnings("unchecked")
Constructor<ClassWithExpensiveConstructor> silentConstructor = ReflectionFactory.getReflectionFactory()
.newConstructorForSerialization(ClassWithExpensiveConstructor.class,
OtherClass.class.getDeclaredConstructor());
silentConstructor.setAccessible(true);
ClassWithExpensiveConstructor instance = silentConstructor.newInstance();
assertEquals(10, instance.getValue());
assertEquals(ClassWithExpensiveConstructor.class, instance.getClass());
assertEquals(Object.class, instance.getClass().getSuperclass());
}</pre>
<br />
Note that <code>value</code> was set in this constructor even though the constructor of a completely different class was invoked. Non-existing fields in the target class are however ignored as also obvious from the above example. Note that <code>OtherClass</code> does not become part of the constructed instances type hierarchy, the <code>OtherClass</code>'s constructor is simply borrowed for the "serialized" type.<br />
<br />
Not mentioned in this blog entry are other methods such as <code>Unsafe#defineClass</code>, <code>Unsafe#defineAnonymousClass</code> or <code>Unsafe#ensureClassInitialized</code>. Similar functionality is however also defined in the public API's <code>ClassLoader</code>.<br />
<br />
<h3 style="text-align: left;">
Native memory allocation</h3>
<br />
Did you ever want to allocate an array in Java that should have had more than <code>Integer.MAX_VALUE</code> entries? Probably not because this is not a common task, but if you once need this functionality, it is possible. You can create such an array by allocating <b>native memory</b>. Native memory allocation is used by for example <a href="http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html">direct byte buffers</a> that are offered in <a href="http://docs.oracle.com/javase/6/docs/api/java/nio/package-summary.html">Java's NIO</a> packages. Other than heap memory, native memory is not part of the heap area and can be used non-exclusively for example for communicating with other processes. As a result, Java's heap space is in competition with the native space: the more memory you assign to the JVM, the less native memory is left.<br />
<br />
Let us look at an example for using native (off-heap) memory in Java with creating the mentioned oversized array:<br />
<br />
<pre class="brush: java">class DirectIntArray {
private final static long INT_SIZE_IN_BYTES = 4;
private final long startIndex;
public DirectIntArray(long size) {
startIndex = unsafe.allocateMemory(size * INT_SIZE_IN_BYTES);
unsafe.setMemory(startIndex, size * INT_SIZE_IN_BYTES, (byte) 0);
}
}
public void setValue(long index, int value) {
unsafe.putInt(index(index), value);
}
public int getValue(long index) {
return unsafe.getInt(index(index));
}
private long index(long offset) {
return startIndex + offset * INT_SIZE_IN_BYTES;
}
public void destroy() {
unsafe.freeMemory(startIndex);
}
}
@Test
public void testDirectIntArray() throws Exception {
long maximum = Integer.MAX_VALUE + 1L;
DirectIntArray directIntArray = new DirectIntArray(maximum);
directIntArray.setValue(0L, 10);
directIntArray.setValue(maximum, 20);
assertEquals(10, directIntArray.getValue(0L));
assertEquals(20, directIntArray.getValue(maximum));
directIntArray.destroy();
}
</pre>
<br />
First, make sure that your machine has sufficient memory for running this example! You need at least <code>(2147483647 + 1) * 4 byte = 8192 MB</code> of native memory for running the code. If you have worked with other programming languages as for example C, direct memory allocation is something you do every day. By calling <code>Unsafe#allocateMemory(long)</code>, the virtual machine allocates the requested amount of native memory for you. After that, it will be your responsibility to handle this memory correctly.<br />
<br />
The amount of memory that is required for storing a specific value is dependent on the type's size. In the above example, I used an <code>int</code> type which represents a 32-bit integer. Consequently a single <code>int</code> value consumes 4 byte. For primitive types, <a href="http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">size is well-documented</a>. It is however more complex to compute the size of object types since they are dependent on the number of non-static fields that are declared anywhere in the type hierarchy. The most canonical way of computing an object's size is <a href="http://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to-determine-the-size-of-an-object">using the <code>Instrumented</code> class from Java's attach API</a> which offers a dedicated method for this purpose called <code>getObjectSize</code>. I will however evaluate another (hacky) way of dealing with objects in the end of this section.<br />
<br />
Be aware that directly allocated memory is always <a href="http://www.ibm.com/developerworks/linux/library/j-nativememory-linux/index.html">native memory</a> and therefore not garbage collected. You therefore have to free memory explicitly as demonstrated in the above example by a call to <code>Unsafe#freeMemory(long)</code>. Otherwise you reserved some memory that can never be used for something else as long as the JVM instance is running what is a memory leak and a common problem in non-garbage collected languages. Alternatively, you can also directly reallocate memory at a certain address by calling <code>Unsafe#reallocateMemory(long, long)</code> where the second argument describes the new amount of bytes to be reserved by the JVM at the given address.<br />
<br />
Also, note that the directly allocated memory is <b>not</b> initialized with a certain value. In general, you will find garbage from old usages of this memory area such that you have to explicitly initialize your allocated memory if you require a default value. This is something that is normally done for you when you let the Java run time allocate the memory for you. In the above example, the entire area is overriden with zeros with help of the <code>Unsafe#setMemory</code> method.<br />
<br />
When using directly allocated memory, the JVM will neither do range checks for you. It is therefore possible to corrupt your memory as this example shows:<br />
<br /></div>
<pre class="brush: java">@Test
public void testMallaciousAllocation() throws Exception {
long address = unsafe.allocateMemory(2L * 4);
unsafe.setMemory(address, 8L, (byte) 0);
assertEquals(0, unsafe.getInt(address));
assertEquals(0, unsafe.getInt(address + 4));
unsafe.putInt(address + 1, 0xffffffff);
assertEquals(0xffffff00, unsafe.getInt(address));
assertEquals(0x000000ff, unsafe.getInt(address + 4));
}
</pre>
<br />
Note that we wrote a value into the space that was each partly reserved for the first and for the second number. This picture might clear things up. Be aware that the values in the memory run from the "right to the left" (but this might be machine dependent).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmFAoiA-SnrS84lOBJTAVsSrqPlUnR1jRcFcpNU5CZtPFp1XHaS89wpagtGfrASAUjToXVJBFso3LDP-vd6QuW_RFlE2wk9GETegqCOEtwVAkgIquBtArpGMBMlLttOMZRY3CmCPPUg_8/s1600/untitled.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="130" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmFAoiA-SnrS84lOBJTAVsSrqPlUnR1jRcFcpNU5CZtPFp1XHaS89wpagtGfrASAUjToXVJBFso3LDP-vd6QuW_RFlE2wk9GETegqCOEtwVAkgIquBtArpGMBMlLttOMZRY3CmCPPUg_8/s320/untitled.png" width="320" /></a></div>
The first row shows the initial state after writing zeros to the entire allocated native memory area. Then we override 4 byte with an offset of a single byte using 32 ones. The last row shows the result after this writing operation.<br />
<br />
Finally, we want to write an entire object into native memory. As mentioned above, this is a difficult task since we first need to compute the size of the object in order to know the amount of size we need to reserve. The <code>Unsafe</code> class does however not offer such functionality. At least not directly since we can at least use the <code>Unsafe</code> class to find the offset of an instance's field which is used by the JVM when itself allocates objects on the heap. This allows us to find the approximate size of an object:<br />
<br />
<pre class="brush: java">public long sizeOf(Class<?> clazz)
long maximumOffset = 0;
do {
for (Field f : clazz.getDeclaredFields()) {
if (!Modifier.isStatic(f.getModifiers())) {
maximumOffset = Math.max(maximumOffset, unsafe.objectFieldOffset(f));
}
}
} while ((clazz = clazz.getSuperclass()) != null);
return maximumOffset + 8;
}</pre>
<br />
This might at first look cryptic, but there is no big secret behind this code. We simply iterate over all non-static fields that are declared in the class itself or in any of its super classes. We do not have to worry about interfaces since those cannot define fields and will therefore never alter an object's memory layout. Any of these fields has an offset which represents the <b>first</b> byte that is occupied by this field's value when the JVM stores an instance of this type in memory, relative to a first byte that is used for this object. We simply have to find the maximum offset in order to find the space that is required for all fields but the last field. Since a field will never occupy more than 64 bit (8 byte) for a <code>long</code> or <code>double</code> value or for an object reference when run on a 64 bit machine, we have at least found an upper bound for the space that is used to store an object. Therefore, we simply add these 8 byte to the maximum index and we will not run into danger of having reserved to little space. This idea is of course wasting some byte and a better algorithm should be used for production code.<br />
<br />
In this context, it is best to think of a class definition as a form of heterogeneous array. Note that the minimum field offset is not <code>0</code> but a positive value. The first few byte contain meta information. The graphic below visualizes this principle for an example object with an <code>int</code> and a <code>long</code> field where both fields have an offset. Note that we do not normally write meta information when writing a copy of an object into native memory so we could further reduce the amount of used native memoy. Also note that this memory layout might be highly dependent on an implementation of the Java virtual machine.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif-pl63nwByZ3qBXNIJiKjMzobPcojpY2CPs2n2_QO237-Rrmld30iq4KKs7nQs_8rpeFaP5UZYAvb9t6D_ApRgQsGdyateCxY-8hYYHST-tRz-SrUJRZgK-rm0dOGID8zI8NuICJhFkA/s1600/object_layout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif-pl63nwByZ3qBXNIJiKjMzobPcojpY2CPs2n2_QO237-Rrmld30iq4KKs7nQs_8rpeFaP5UZYAvb9t6D_ApRgQsGdyateCxY-8hYYHST-tRz-SrUJRZgK-rm0dOGID8zI8NuICJhFkA/s320/object_layout.png" width="320" /></a></div>
With this overly careful estimate, we can now implement some stub methods for writing shallow copies of objects directly into native memory. Note that native memory does not really know the concept of an object. We are basically just setting a given amount of byte to values that reflect an object's current values. As long as we remember the memory layout for this type, these byte contain however enough information to reconstruct this object.<br />
<br />
<pre class="brush: java">public void place(Object o, long address) throws Exception {
Class clazz = o.getClass();
do {
for (Field f : clazz.getDeclaredFields()) {
if (!Modifier.isStatic(f.getModifiers())) {
long offset = unsafe.objectFieldOffset(f);
if (f.getType() == long.class) {
unsafe.putLong(address + offset, unsafe.getLong(o, offset));
} else if (f.getType() == int.class) {
unsafe.putInt(address + offset, unsafe.getInt(o, offset));
} else {
throw new UnsupportedOperationException();
}
}
}
} while ((clazz = clazz.getSuperclass()) != null);
}
public Object read(Class clazz, long address) throws Exception {
Object instance = unsafe.allocateInstance(clazz);
do {
for (Field f : clazz.getDeclaredFields()) {
if (!Modifier.isStatic(f.getModifiers())) {
long offset = unsafe.objectFieldOffset(f);
if (f.getType() == long.class) {
unsafe.putLong(instance, offset, unsafe.getLong(address + offset));
} else if (f.getType() == int.class) {
unsafe.putLong(instance, offset, unsafe.getInt(address + offset));
} else {
throw new UnsupportedOperationException();
}
}
}
} while ((clazz = clazz.getSuperclass()) != null);
return instance;
}
@Test
public void testObjectAllocation() throws Exception {
long containerSize = sizeOf(Container.class);
long address = unsafe.allocateMemory(containerSize);
Container c1 = new Container(10, 1000L);
Container c2 = new Container(5, -10L);
place(c1, address);
place(c2, address + containerSize);
Container newC1 = (Container) read(Container.class, address);
Container newC2 = (Container) read(Container.class, address + containerSize);
assertEquals(c1, newC1);
assertEquals(c2, newC2);
}
</pre>
<br />
Note that these stub methods for writing and reading objects in native memory only support <code>int</code> and <code>long</code> field values. Of course, <code>Unsafe</code> supports all primitive values and can even write values without hitting thread-local caches by using the volatile forms of the methods. The stubs were only used to keep the examples concise. Be aware that these "instances" would <b>never</b> get garbage collected since their memory was allocated directly. (But maybe this is what you want.) Also, be careful when precalculating size since an object's memory layout might be VM dependent and also alter if a 64-bit machine runs your code compared to a 32-bit machine. The offsets might even change between JVM restarts.<br />
<br />
For reading and writing primitives or object references, <code>Unsafe</code> provides the following type-dependent methods:<br />
<ul style="text-align: left;">
<li><code>getXXX(Object target, long offset)</code>: Will read a value of type XXX from target's address at the specified offset.</li>
<li><code>putXXX(Object target, long offset, XXX value)</code>: Will place value at target's address at the specified offset.</li>
<li><code>getXXXVolatile(Object target, long offset)</code>: Will read a value of type XXX from target's address at the specified offset and not hit any thread local caches.</li>
<li><code>putXXXVolatile(Object target, long offset, XXX value)</code>: Will place value at target's address at the specified offset and not hit any thread local caches.</li>
<li><code>putOrderedXXX(Object target, long offset, XXX value)</code>: Will place value at target's address at the specified offet and might not hit all thread local caches.</li>
<li><code>putXXX(long address, XXX value)</code>: Will place the specified value of type XXX directly at the specified address.</li>
<li><code>getXXX(long address)</code>: Will read a value of type XXX from the specified address.</li>
<li><code>compareAndSwapXXX(Object target, long offset, long expectedValue, long value)</code>: Will atomicly read a value of type XXX from target's address at the specified offset and set the given value if the current value at this offset equals the expected value.</li>
</ul>
Be aware that you are copying references when writing or reading object copies in native memory by using the <code>getObject(Object, long)</code> method family. You are therefore only creating shallow copies of instances when applying the above method. You could however always read object sizes and offsets recursively and create deep copies. Pay however attention for cyclic object references which would cause infinitive loops when applying this principle carelessly.<br />
<br />
Not mentioned here are existing utilities in the Unsafe class that allow manipulation of static field values sucht as <code>staticFieldOffset</code> and for handling array types. Finally, both methods named <code>Unsafe#copyMemory</code> allow to instruct a direct copy of memory, either relative to a specific object offset or at an absolute address as the following example shows:<br />
<br />
<pre class="brush: java">@Test
public void testCopy() throws Exception {
long address = unsafe.allocateMemory(4L);
unsafe.putInt(address, 100);
long otherAddress = unsafe.allocateMemory(4L);
unsafe.copyMemory(address, otherAddress, 4L);
assertEquals(100, unsafe.getInt(otherAddress));
}
</pre>
<br />
<h3 style="text-align: left;">
Throwing checked exceptions without declaration</h3>
<br />
There are some other interesting methods to find in <code>Unsafe</code>. Did you ever want to throw a specific exception to be handled in a lower layer but you high layer interface type did not declare this checked exception? <code>Unsafe#throwException</code> allows to do so:<br />
<br />
<pre class="brush: java">@Test(expected = Exception.class)
public void testThrowChecked() throws Exception {
throwChecked();
}
public void throwChecked() {
unsafe.throwException(new Exception());
}</pre>
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
Native concurrency</h3>
<br />
The <code>park</code> and <code>unpark</code> methods allow you to pause a thread for a certain amount of time and to resume it:<br />
<br />
<pre class="brush: java">@Test
public void testPark() throws Exception {
final boolean[] run = new boolean[1];
Thread thread = new Thread() {
@Override
public void run() {
unsafe.park(true, 100000L);
run[0] = true;
}
};
thread.start();
unsafe.unpark(thread);
thread.join(100L);
assertTrue(run[0]);
}
</pre>
<br />
Also, monitors can be acquired directly by using Unsafe using <code>monitorEnter(Object)</code>, <code>monitorExit(Object)</code> and <code>tryMonitorEnter(Object)</code>.<br />
<br />
A file containing all the examples of this blog entry is <a href="https://gist.github.com/raphw/7935844">available as a gist</a>. </div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com3tag:blogger.com,1999:blog-3237092529299307504.post-21086247160938284592013-11-23T15:00:00.001+01:002013-11-23T15:04:53.381+01:00A declarative content parser for Java<div dir="ltr" style="text-align: left;" trbidi="on">
Recently, I worked on a project that required me to parse several files which came in their own file formats. To make things worse,
the file format changed quite often such that the related code had to be adjusted quite often. In my opinion, object-oriented
languages such as Java are not necessarily the sharpest tools for dealing with file parsing. For this reason, I tried to solve this
problem with a declarative approach, the result of which I <a href="https://github.com/raphw/declarative-parser">published on GitHub</a> and on <a href="http://search.maven.org/#search|ga|1|a%3A%22declarative-parser%22">Maven Central</a>.<br />
<br />
This miniature tool provides help with parsing a custom content format by creating Java beans that extract this data
where each bean resembles a single row of content of a specified source. The mapping of the input to a Java bean is based
on regular expressions what allows great flexibility. However, the syntax of regular expressions is enhanced by
properties expressions that allow the direct mapping of bean properties within this regular expression describing these
contents.<br />
This tool is intended to be as light-weight as possible and comes without dependencies. It is however quite extensible as
demonstrated below.<br />
<br />
<h4>
A simple example</h4>
The tool is used by a single entry point, an instance of <code>BeanTransformer</code> which can read content for a specified bean. By
doing so, the parser only needs to build patterns for a specified bean a single time. Therefore, this tool performs equally
good as writing native content parsers, once it is set up.<br />
As an example for the use of this tool, imagine you want to read in data from some sample file <i>sample.txt</i> containing
the following data in an imaginary format:<br />
<br />
<pre>##This is a first value##foo&&2319949,
##This is a second value##bar&&741981,
##This is a third value##&&998483,
</pre>
<br />
This tool would now allow you to directly translate this file by declaring the following Java bean:<br />
<br />
<pre class="brush: java">@MatchBy("##@intro@##@value@&&@number@,")
class MyBean {
private String intro;
@OptionalMatch
private String value;
private int number;
// Getters and setters...
}
</pre>
<br />
The <code>@name@</code> expressions each represent a property in the bean which will be filled by the data found at this particular point
within the regular expression. The expression can be escaped by preceeding the <b>first</b> <code>@</code> symbol with backslashes as for
example <code>\\@name@</code>. A back slash can be escaped in the same manner.
With calling <code>BeanTransformer.make(MyBean.class).read(new FileReader("./sample.txt"))</code> you would receive a list of <code>MyBean</code>
instances where each instance resembles one line of the file. All properties would be matched to the according property name
that is declared in the bean.<br />
<br />
<h4>
Matching properties</h4>
The <code>@MatchBy</code> annotation can also be used for fields within a bean that is used for matching. This tool will normally discover
a pattern by interpreting the type of a field that is referenced in the expression used for parsing the content. Since the
<code>@number@</code> expression in the example above references a field of type <code>int</code>, the field would be matched against the regular expression
<code>[0-9]+</code>, representing any non-decimal number. All other primitive types and their wrapper types are also equipped with a
predefined matching pattern. All other types will by default be matched by a <b>non-greedy</b> match-everything pattern. After
extracting a property, the type of the property will be tried to be instantiated by:
<br />
<ul>
<li>Invoking a static function with the signature <code>valueOf(String)</code> defined on the type.</li>
<li>Using a constructor taking a single <code>String</code> as its argument</li>
</ul>
This default behavior can however be changed. A field can be annotated with <code>@ResolveMatchWith</code> which requires a subtype of
a <code>PropertyDelegate</code> as its single argument. An instance of this class will be instantiated for transforming expressions from
a string to a value and reverse. The subclass needs to override the only constructor of <code>PropertyDelegate</code> and accept the same
types as this constructor.
An optional match can be declared by annotating a field with <code>@OptionalMatch</code>. If no match can be made for such a field, the
<code>PropertyDelegate</code>'s setter will never be invoked (when using a custom <code>PropertyDelegate</code>).<br />
<br />
<h4>
Dealing with regular expressions</h4>
Always keep in mind that <code>@MatchBy</code> annotation take regular expressions as their arguments. Therefore, it is important to escape
all special characters that are found in regular expressions such as for example <code>.\\*,[](){}+?^$</code>. Also, note that the
default matching patterns for non-primitive types or their wrappers is <b>non-greedy</b>. This means that the pattern <code>@name@</code>
would match the line <b>foo</b> by only the first letter <b>f</b>. If you want to match the full line, you have to declare the matching
expression as <code>^@name@$</code> what is the regular expression for a full line match. Be aware that using regular expressions might
require you to define a <code>@WritePattern</code> which is described below.
Using regular expressions allows you to specify matching constraints natively. Annotating a field with <code>@MatchBy("[a-z]{1,5]")</code>
would for example allow for only matching lines where the property is represented by one to five lower case characters.
Configuring mismatch handling is described below.<br />
<br />
<h4>
Writing beans</h4>
Similar to reading contents from a source, this utility allows to write a list of beans to a target. Without further
configuration, the same pattern as in <code>@MatchBy</code> will be used for writing where the property expressions are substituted by
the bean values. This can however result in distorted output since symbols of regular expressions are written <i>as they are</i>.
Therefore, a user can define an output pattern by declaring <code>@WritePattern</code>. This pattern understands the same type of property
expressions such as <code>@name</code> but does not use regular expressions. Remember that regular expressions must therefore not be escaped
when a <code>@WritePattern</code> is specified. A property expression can however be escaped in the same manner as in a <code>@MatchBy</code> statement.<br />
<br />
<h4>
Handling mismatches</h4>
When a content source is parsed but a single line cannot be matched to the specified expression, the extraction will abort
with throwing a <code>TransformationException</code>. Empty lines will however be skipped. This behavior can be configured by declaring
a policy within <code>@Skip</code>. That way, a non-matched line can either ignored, throw an exception or be ignored for empty lines. An
empty line a the end of a file is always ignored.<br />
<br />
<h4>
Builder</h4>
The <code>BeanTransformer</code> offers a builder which allows to specify different properties. Mostly, it allows to override properties
that were declared in a specific bean such as the content pattern provided by <code>@MatchBy</code>, a <code>@Skip</code> policy or the <code>@WritePattern</code>.
This allows the reuse of a bean for different content sources that contain the same properties but differ in their display. Also,
this allows to provide a pattern at run time.<br />
<br />
<h4>
Performance considerations</h4>
All beans are constructed and accessed via field reflection. (It is therefore not required to define setters and getters for beans.
A default constructor is however required. In the process, primitive types are accessed as such and not wrapped in order to
avoid such overhead. Java reflection is usually considered to be slower than conventional access. However, modern JVMs such as
the HotSpot JVM are efficient in detecting the repetitive use of reflection and compile such access into native byte code.
Therefore, this tool should not perform worse than a hand-written matcher once the <code>BeanTransformer</code> is set up.<br />
<br />
<h4>
Extension points</h4>
Besides providing your own <code>PropertyDelegate</code>s, it is possible to implement a custom <code>IDelegationFactory</code> which is responsible
for creating (custom) <code>PropertyDelegate</code>s for any field. The default implementation <code>SimpleDelegationFactory</code> provides an example
for such an implementation. That way, it would be for example possible to automatically create suitable patterns for <a href="http://beanvalidation.org/1.0/spec/">bean validation (JSR-303) annotations</a>.<br />
<br />
The code is licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache Software License, Version 2.0</a>. </div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-7987500235123976622013-11-13T23:21:00.000+01:002015-01-17T02:59:00.912+01:00cglib: The missing manual<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
The <a href="http://en.wikipedia.org/wiki/Java_bytecode">byte code</a> instrumentation library <a href="http://cglib.sourceforge.net/"><b>cglib</b></a> is a popular choice among many well-known Java frameworks such as <a href="http://www.hibernate.org/">Hibernate</a> (<a href="http://relation.to/16658.lace">not anymore</a>) or <a href="http://spring.io/">Spring</a> for doing their dirty work. Byte code instrumentation allows to manipulate or to create classes after the compilation phase of a Java application. Since Java classes are linked dynamically at run time, it is possible to add new classes to an already running Java program. Hibernate uses cglib for example for its generation of dynamic proxies. Instead of returning the full object that you stored ina a database, Hibernate will return you an instrumented version of your stored class that lazily loads some values from the database only when they are requested. Spring used cglib for example when adding security constraints to your method calls. Instead of calling your method directly, Spring security will first check if a specified security check passes and only delegate to your actual method after this verification. Another popular use of cglib is within mocking frameworks such as <a href="http://code.google.com/p/mockito/">mockito</a>, where mocks are nothing more than instrumented class where the methods were replaced with empty implementations (plus some tracking logic).
<br />
<br />
Other than <a href="http://asm.ow2.org/">ASM</a> - another very high-level byte code manipulation library on top of which cglib is built - cglib offers rather low-level byte code transformers that can be used without even knowing about the details of a compiled Java class. Unfortunately, the documentation of cglib is rather short, not to say that there is basically none. Besides a <a href="http://jnb.ociweb.com/jnb/jnbNov2005.html">single blog article from 2005</a> that demonstrates the Enhancer class, there is not much to find. This blog article is an attempt to demonstrate cglib and its unfortunately often awkward API.<br />
<br />
<h1 style="text-align: left;">
Enhancer
</h1>
Let's start with the <code>Enhancer</code> class, the probably most used class of the cglib library. An enhancer allows the creation of Java proxies for non-interface types. The <code>Enhancer</code> can be compared with the Java standard library's <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html"><code>Proxy</code></a> class which was introduced in Java 1.3. The <code>Enhancer</code> dynamically creates a subclass of a given type but intercepts all method calls. Other than with the <code>Proxy</code> class, this works for both class and interface types. The following example and some of the examples after are based on this simple Java POJO:<br />
<br />
<pre class="brush: java">public class SampleClass {
public String test(String input) {
return "Hello world!";
}
}</pre>
<br />
Using cglib, the return value of <code>test(String)</code> method can easily be replaced by another value using an <code>Enhancer</code> and a <code>FixedValue</code> callback:
<br />
<br />
<pre class="brush: java">@Test
public void testFixedValue() throws Exception {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class);
enhancer.setCallback(new FixedValue() {
@Override
public Object loadObject() throws Exception {
return "Hello cglib!";
}
});
SampleClass proxy = (SampleClass) enhancer.create();
assertEquals("Hello cglib!", proxy.test(null));
}</pre>
<br />
In the above example, the enhancer will return an instance of an instrumented subclass of <code>SampleClass</code> where all method calls return a fixed value which is generated by the anonymous <code>FixedValue</code> implementation above. The object is created by <code>Enhancer#create(Object...)</code> where the method takes any number of arguments which are used to pick any constructor of the enhanced class. (Even though constructors are only methods on the Java byte code level, the <code>Enhancer</code> class cannot instrument constructors. Neither can it instrument <code>static</code> or <code>final</code> classes.) If you only want to create a class, but no instance, <code>Enhancer#createClass</code> will create a <code>Class</code> instance which can be used to create instances dynamically. All constructors of the enhanced class will be available as delegation constructors in this dynamically generated class.<br />
<br />
Be aware that any method call will be delegated in the above example, also calls to the methods defined in <code>java.lang.Object</code>. As a result, a call to <code>proxy.toString()</code> will also return "Hello cglib!". In contrast will a call to <code>proxy.hashCode()</code> result in a <code>ClassCastException</code> since the <code>FixedValue</code> interceptor always returns a <code>String</code> even though the <code>Object#hashCode</code> signature requires a primitive integer.<br />
<br />
Another observation that can be made is that final methods are not intercepted. An example of such a method is <code>Object#getClass</code> which will return something like "SampleClass$$EnhancerByCGLIB$$e277c63c" when it is invoked. This class name is generated randomly by cglib in order to avoid naming conflicts. Be aware of the different class of the enhanced instance when you are making use of explicit types in your program code. The class generated by cglib will however be in the same package as the enhanced class (and therefore be able to override package-private methods). Similar to final methods, the subclassing approach makes for the inability of enhancing final classes. Therefore frameworks as Hibernate cannot persist final classes.<br />
<br />
<br />
Next, let us look at a more powerful callback class, the <code>InvocationHandler</code>, that can also be used with an <code>Enhancer</code>:
<br />
<br />
<pre class="brush: java">@Test
public void testInvocationHandler() throws Exception {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class);
enhancer.setCallback(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
return "Hello cglib!";
} else {
throw new RuntimeException("Do not know what to do.");
}
}
});
SampleClass proxy = (SampleClass) enhancer.create();
assertEquals("Hello cglib!", proxy.test(null));
assertNotEquals("Hello cglib!", proxy.toString());
}</pre>
<br />
<br />
This callback allows us to answer with regards to the invoked method. However, you should be careful when calling a method on the proxy object that comes with the <code>InvocationHandler#invoke</code> method. All calls on this method will be dispatched with the same <code>InvocationHandler</code> and might therefore result in an endless loop. In order to avoid this, we can use yet another callback dispatcher:
<br />
<br />
<pre class="brush: java">@Test
public void testMethodInterceptor() throws Exception {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
if(method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
return "Hello cglib!";
} else {
proxy.invokeSuper(obj, args);
}
}
});
SampleClass proxy = (SampleClass) enhancer.create();
assertEquals("Hello cglib!", proxy.test(null));
assertNotEquals("Hello cglib!", proxy.toString());
proxy.hashCode(); // Does not throw an exception or result in an endless loop.
}</pre>
<br />
<br />
The <code>MethodInterceptor</code> allows full control over the intercepted method and offers some utilities for calling the method of the enhanced class in their original state. But why would one want to use other methods anyways? Because the other methods are more efficient and cglib is often used in edge case frameworks where efficiency plays a significant role. The creation and linkage of the <code>MethodInterceptor</code> requires for example the generation of a different type of byte code and the creation of some runtime objects that are not required with the InvocationHandler. Because of that, there are other classes that can be used with the Enhancer:<br />
<ul style="text-align: left;">
<li><code>LazyLoader</code>: Even though the <code>LazyLoader</code>'s only method has the same method signature as <code>FixedValue</code>, the <code>LazyLoader</code> is fundamentally different to the <code>FixedValue</code> interceptor. The <code>LazyLoader</code> is actually supposed to return an instance of a subclass of the enhanced class. This instance is requested only when a method is called on the enhanced object and then stored for future invocations of the generated proxy. This makes sense if your object is expensive in its creation without knowing if the object will ever be used. Be aware that some constructor of the enhanced class must be called both for the proxy object and for the lazily loaded object. Thus, make sure that there is another cheap (maybe <code>protected</code>) constructor available or use an interface type for the proxy. You can choose the invoked constructed by supplying arguments to <code>Enhancer#create(Object...)</code>.</li>
<li><code>Dispatcher</code>: The <code>Dispatcher</code> is like the <code>LazyLoader</code> but will be invoked on every method call without storing the loaded object. This allows to change the implementation of a class without changing the reference to it. Again, be aware that some constructor must be called for both the proxy and the generated objects.</li>
<li><code>ProxyRefDispatcher</code>: This class carries a reference to the proxy object it is invoked from in its signature. This allows for example to delegate method calls to another method of this proxy. Be aware that this can easily cause an endless loop and will always cause an endless loop if the same method is called from within <code>ProxyRefDispatcher#loadObject(Object)</code>.</li>
<li><code>NoOp</code>: The <code>NoOp</code> class does not what its name suggests. Instead, it delegates each method call to the enhanced class's method implementation.</li>
</ul>
<br />
At this point, the last two interceptors might not make sense to you. Why would you even want to enhance a class when you will always delegate method calls to the enhanced class anyways? And you are right. These interceptors should only be used together with a <code>CallbackFilter</code> as it is demonstrated in the following code snippet:<br />
<br />
<pre class="brush: java">@Test
public void testCallbackFilter() throws Exception {
Enhancer enhancer = new Enhancer();
CallbackHelper callbackHelper = new CallbackHelper(SampleClass.class, new Class[0]) {
@Override
protected Object getCallback(Method method) {
if(method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
return new FixedValue() {
@Override
public Object loadObject() throws Exception {
return "Hello cglib!";
};
}
} else {
return NoOp.INSTANCE; // A singleton provided by NoOp.
}
}
};
enhancer.setSuperclass(MyClass.class);
enhancer.setCallbackFilter(callbackHelper);
enhancer.setCallbacks(callbackHelper.getCallbacks());
SampleClass proxy = (SampleClass) enhancer.create();
assertEquals("Hello cglib!", proxy.test(null));
assertNotEquals("Hello cglib!", proxy.toString());
proxy.hashCode(); // Does not throw an exception or result in an endless loop.
}</pre>
<br />
The <code>Enhancer</code> instance accepts a <code>CallbackFilter</code> in its <code>Enhancer#setCallbackFilter(CallbackFilter)</code> method where it expects methods of the enhanced class to be mapped to array indices of an array of <code>Callback</code> instances. When a method is invoked on the created proxy, the <code>Enhancer</code> will then choose the according interceptor and dispatch the called method on the corresponding <code>Callback</code> (which is a marker interface for all the interceptors that were introduced so far). To make this API less awkward, cglib offers a <code>CallbackHelper</code> which will represent a <code>CallbackFilter</code> and which can create an array of <code>Callback</code>s for you. The enhanced object above will be functionally equivalent to the one in the example for the <code>MethodInterceptor</code> but it allows you to write specialized interceptors whilst keeping the dispatching logic to these interceptors separate.<br />
<h3 style="text-align: left;">
<span style="font-size: small;"> </span></h3>
<h3 style="text-align: left;">
<span style="font-size: small;">How does it work?</span></h3>
<br />
When the <code>Enhancer</code> creates a class, it will set create a <code>private</code> <s><code>static</code></s> field for each interceptor that was registered as a <code>Callback</code> for the enhanced class after its creation. This also means that class definitions that were created with cglib cannot be reused after their creation since the registration of callbacks does not become a part of the generated class's initialization phase but are prepared manually by cglib after the class was already initialized by the JVM. This also means that classes created with cglib are not technically ready after their initialization and for example cannot be sent over the wire since the callbacks would not exist for the class loaded in the target machine.<br />
<br />
Depending on the registered interceptors, cglib might register additional fields such as for example for the <code>MethodInterceptor</code> where two <code>private</code> <code>static</code> fields (one holding a reflective <code>Method</code> and a the other holding <code>MethodProxy</code>) are registered per method that is intercepted in the enhanced class or any of its subclasses. Be aware that the <code>MethodProxy</code> is making excessive use of the <code>FastClass</code> which triggers the creation of additional classes and is described in further detail below.<br />
<br />
For all these reasons, be careful when using the <code>Enhancer</code>. And always register callback types defensively, since the <code>MethodInterceptor</code> will for example trigger the creation of additional classes and register additional fields in the enhanced class. This is specifically dangerous since the callback variables are also stored in the enhancer's cache: This implies that the callback instances are <b>not</b> garbage collected (unless all instances and the enhancer's <code>ClassLoader</code> is, what is unusual). This is in particular dangerous when using anonymous classes which silently carry a reference to their outer class. Recall the example above:<br />
<br />
<br />
<pre class="brush: java">@Test
public void testFixedValue() throws Exception {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class);
enhancer.setCallback(new FixedValue() {
@Override
public Object loadObject() throws Exception {
return "Hello cglib!";
}
});
SampleClass proxy = (SampleClass) enhancer.create();
assertEquals("Hello cglib!", proxy.test(null));
}</pre>
<br />
The anonymous subclass of <code>FixedValue</code> would become hardly referenced from the enhanced <code>SampleClass</code> such that neither the anonymous <code>FixedValue</code> instance or the class holding the <code>@Test</code> method would ever be garbage collected. This can introduce nasty memory leaks in your applications. Therefore, do not use non-<code>static</code> inner classes with cglib. (I only use them in this blog entry for keeping the examples short.)<br />
<br />
Finally, you should never intercept <code>Object#finalize()</code>. Due to the subclassing approach of cglib, intercepting <code>finalize</code> is implemented by overriding it what is <a href="http://howtodoinjava.com/2012/10/31/why-not-to-use-finalize-method-in-java/">in general a bad idea</a>. Enhanced instances that intercept finalize will be treated differently by the garbage collector and will also cause these objects being queued in the JVM's finalization queue. Also, if you (accidentally) create a hard reference to the enhanced class in your intercepted call to <code>finalize</code>, you have effectively created an noncollectable instance. This is in general nothing you want. Note that <code>final</code> methods are never intercepted by cglib. Thus, <code>Object#wait</code>, <code>Object#notify</code> and <code>Object#notifyAll</code> do not impose the same problems. Be however aware that <code>Object#clone</code> can be intercepted what is something you might not want to do.<br />
<br />
<h1 style="text-align: left;">
Immutable bean
</h1>
cglib's <code>ImmutableBean</code> allows you to create an immutability wrapper similar to for example <code>Collections#immutableSet</code>. All changes of the underlying bean will be prevented by an <code>IllegalStateException</code> (however, not by an <code>UnsupportedOperationException</code> as recommended by the Java API). Looking at some bean<br />
<br />
<pre class="brush: java">public class SampleBean {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}</pre>
<br />
we can make this bean immutable:<br />
<br />
<pre class="brush: java">@Test(expected = IllegalStateException.class)
public void testImmutableBean() throws Exception {
SampleBean bean = new SampleBean();
bean.setValue("Hello world!");
SampleBean immutableBean = (SampleBean) ImmutableBean.create(bean);
assertEquals("Hello world!", immutableBean.getValue());
bean.setValue("Hello world, again!");
assertEquals("Hello world, again!", immutableBean.getValue());
immutableBean.setValue("Hello cglib!"); // Causes exception.
}</pre>
<br />
As obvious from the example, the immutable bean prevents all state changes by throwing an <code>IllegalStateException</code>. However, the state of the bean can be changed by changing the original object. All such changes will be reflected by the <code>ImmutableBean</code>.
<br />
<br />
<h1 style="text-align: left;">
Bean generator
</h1>
The <code>BeanGenerator</code> is another bean utility of cglib. It will create a bean for you at run time:<br />
<br />
<pre class="brush: java">@Test
public void testBeanGenerator() throws Exception {
BeanGenerator beanGenerator = new BeanGenerator();
beanGenerator.addProperty("value", String.class);
Object myBean = beanGenerator.create();
Method setter = myBean.getClass().getMethod("setValue", String.class);
setter.invoke(myBean, "Hello cglib!");
Method getter = myBean.getClass().getMethod("getValue");
assertEquals("Hello cglib!", getter.invoke(myBean));
}</pre>
<br />
As obvious from the example, the <code>BeanGenerator</code> first takes some properties as name value pairs. On creation, the <code>BeanGenerator</code> creates the accessors
<br />
<ul>
<li><code><type> get<name>()</code></li>
<code>
</code>
<li><code>void set<name>(<type>)</code></li>
</ul>
for you. This might be useful when another library expects beans which it resolved by reflection but you do not know these beans at run time. (An example would be <a href="http://wicket.apache.org/">Apache Wicket</a> which works a lot with beans.)
<br />
<br />
<h1 style="text-align: left;">
Bean copier
</h1>
The <code>BeanCopier</code> is another bean utility that copies beans by their property values. Consider another bean with similar properties as <code>SampleBean</code>:<br />
<br />
<pre class="brush: java">public class OtherSampleBean {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}</pre>
<br />
Now you can copy properties from one bean to another:<br />
<br />
<pre class="brush: java">@Test
public void testBeanCopier() throws Exception {
BeanCopier copier = BeanCopier.create(SampleBean.class, OtherSampleBean.class, false);
SampleBean bean = new SampleBean();
myBean.setValue("Hello cglib!");
OtherSampleBean otherBean = new OtherSampleBean();
copier.copy(bean, otherBean, null);
assertEquals("Hello cglib!", otherBean.getValue());
}</pre>
<br />
without being restrained to a specific type. The <code>BeanCopier#copy</code> mehtod takles an (eventually) optional <code>Converter</code> which allows to do some further manipulations on each bean property. If the <code>BeanCopier</code> is created with false as the third constructor argument, the <code>Converter</code> is ignored and can therefore be <code>null</code>.
<br />
<br />
<h1 style="text-align: left;">
Bulk bean
</h1>
A <code>BulkBean</code> allows to use a specified set of a bean's accessors by arrays instead of method calls:<br />
<br />
<pre class="brush: java">@Test
public void testBulkBean() throws Exception {
BulkBean bulkBean = BulkBean.create(SampleBean.class,
new String[]{"getValue"},
new String[]{"setValue"},
new Class[]{String.class});
SampleBean bean = new SampleBean();
bean.setValue("Hello world!");
assertEquals(1, bulkBean.getPropertyValues(bean).length);
assertEquals("Hello world!", bulkBean.getPropertyValues(bean)[0]);
bulkBean.setPropertyValues(bean, new Object[] {"Hello cglib!"});
assertEquals("Hello cglib!", bean.getValue());
}</pre>
<br />
The <code>BulkBean</code> takes an array of getter names, an array of setter names and an array of property types as its constructor arguments. The resulting instrumented class can then extracted as an array by <code>BulkBean#getPropertyBalues(Object)</code>. Similarly, a bean's properties can be set by <code>BulkBean#setPropertyBalues(Object, Object[])</code>.<br />
<br />
<h1 style="text-align: left;">
Bean map
</h1>
This is the last bean utility within the cglib library. The <code>BeanMap</code> converts all properties of a bean to a <code>String</code>-to-<code>Object</code> Java <code>Map</code>:<br />
<br />
<pre class="brush: java">@Test
public void testBeanGenerator() throws Exception {
SampleBean bean = new SampleBean();
BeanMap map = BeanMap.create(bean);
bean.setValue("Hello cglib!");
assertEquals("Hello cglib", map.get("value"));
}</pre>
<br />
Additionally, the <code>BeanMap#newInstance(Object)</code> method allows to create maps for other beans by reusing the same <code>Class</code>.<br />
<br />
<h1 style="text-align: left;">
Key factory </h1>
The <code>KeyFactory</code> factory allows the dynamic creation of keys that are composed of multiple values that can be used in for example <code>Map</code> implementations. For doing so, the <code>KeyFactory</code> requires some interface that defines the values that should be used in such a key. This interface must contain a single method by the name newInstance that returns an <code>Object</code>. For example:<br />
<br />
<pre class="brush: java">public interface SampleKeyFactory {
Object newInstance(String first, int second);
}
</pre>
<br />
Now an instance of a a key can be created by:<br />
<br />
<pre class="brush: java">@Test
public void testKeyFactory() throws Exception {
SampleKeyFactory keyFactory = (SampleKeyFactory) KeyFactory.create(Key.class);
Object key = keyFactory.newInstance("foo", 42);
Map<Object, String> map = new HashMap<Object, String>();
map.put(key, "Hello cglib!");
assertEquals("Hello cglib!", map.get(keyFactory.newInstance("foo", 42)));
}</pre>
<br />
The <code>KeyFactory</code> will assure the correct implementation of the <code>Object#equals(Object)</code> and <code>Object#hashCode</code> methods such that the resulting key objects can be used in a <code>Map</code> or a <code>Set</code>. The <code>KeyFactory</code> is also used quite a lot internally in the cglib library.<br />
<br />
<h1 style="text-align: left;">
Mixin</h1>
</div>
</div>
Some might already know the concept of the <code>Mixin</code> class from other programing languages such as Ruby or Scala (where mixins are called traits). cglib <code>Mixin</code>s allow the combination of several objects into a single object. However, in order to do so, those objects must be backed by interfaces:<br />
<br />
<pre class="brush: java">public interface Interface1 {
String first();
}
public interface Interface2 {
String second();
}
public class Class1 implements Interface1 {
@Override
public String first() {
return "first";
}
}
public class Class2 implements Interface2 {
@Override
public String second() {
return "second";
}
}
</pre>
<br />
Now the classes <code>Class1</code> and <code>Class2</code> can be combined to a single class by an additional interface:<br />
<br />
<pre class="brush: java">public interface MixinInterface extends Interface1, Interface2 { /* empty */ }
@Test
public void testMixin() throws Exception {
Mixin mixin = Mixin.create(new Class[]{Interface1.class, Interface2.class,
MixinInterface.class}, new Object[]{new Class1(), new Class2()});
MixinInterface mixinDelegate = (MixinInterface) mixin;
assertEquals("first", mixinDelegate.first());
assertEquals("second", mixinDelegate.second());
}</pre>
<br />
Admittedly, the <code>Mixin</code> API is rather awkward since it requires the classes used for a mixin to implement some interface such that the problem could also be solved by non-instrumented Java.<br />
<br />
<h1 style="text-align: left;">
<span style="font-family: inherit;">String switcher</span></h1>
The <code>StringSwitcher</code> emulates a <code>String</code> to int Java <code>Map</code>:
<br />
<pre class="brush: java">@Test
public void testStringSwitcher() throws Exception {
String[] strings = new String[]{"one", "two"};
int[] values = new int[]{10, 20};
StringSwitcher stringSwitcher = StringSwitcher.create(strings, values, true);
assertEquals(10, stringSwitcher.intValue("one"));
assertEquals(20, stringSwitcher.intValue("two"));
assertEquals(-1, stringSwitcher.intValue("three"));
}
</pre>
<br />
The StringSwitcher allows to emulate a <code>switch</code> command on <code>String</code>s such as it is possible with the built-in Java <code>switch</code> statement since Java 7. If using the <code>StringSwitcher</code> in Java 6 or less really adds a benefit to your code remains however doubtful and I would personally not recommend its use.<br />
<br />
<h1 style="text-align: left;">
Interface maker</h1>
The InterfaceMaker does what its name suggests: It dynamically creates a new interface.<br />
<br />
<pre class="brush: java">@Test
public void testInterfaceMaker() throws Exception {
Signature signature = new Signature("foo", Type.DOUBLE_TYPE, new Type[]{Type.INT_TYPE});
InterfaceMaker interfaceMaker = new InterfaceMaker();
interfaceMaker.add(signature, new Type[0]);
Class iface = interfaceMaker.create();
assertEquals(1, iface.getMethods().length);
assertEquals("foo", iface.getMethods()[0].getName());
assertEquals(double.class, iface.getMethods()[0].getReturnType());
}
</pre>
<br />
Other than any other class of cglib's public API, the interface maker relies on ASM types. The creation of an interface in a running application will hardly make sense since an interface only represents a type which can be used by a compiler to check types. It can however make sense when you are generating code that is to be used in later development.
<br />
<br />
<h1 style="text-align: left;">
Method delegate</h1>
A <code>MethodDelegate</code> allows to emulate a <a href="http://msdn.microsoft.com/de-de/library/900fyy8e%28v=vs.90%29.aspx"><code>C#</code>-like delegate</a> to a specific method by binding a method call to some interface. For example, the following code would bind the <code>SampleBean#getValue</code> method to a delegate:<br />
<br />
<pre class="brush: java">public interface BeanDelegate {
String getValueFromDelegate();
}
@Test
public void testMethodDelegate() throws Exception {
SampleBean bean = new SampleBean();
bean.setValue("Hello cglib!");
BeanDelegate delegate = (BeanDelegate) MethodDelegate.create(
bean, "getValue", BeanDelegate.class);
assertEquals("Hello world!", delegate.getValueFromDelegate());
}</pre>
<br />
There are however some things to note:<br />
<ul style="text-align: left;">
<li>The factory method <code>MethodDelegate#create</code> takes exactly one method name as its second argument. This is the method the <code>MethodDelegate</code> will proxy for you.</li>
<li>There must be a method <b>without</b> arguments defined for the object which is given to the factory method as its first argument. Thus, the <code>MethodDelegate</code> is not as strong as it could be.</li>
<li>The third argument must be an interface with exactly one argument. The <code>MethodDelegate</code>
implements this interface and can be cast to it. When the method is
invoked, it will call the proxied method on the object that is the first
argument.</li>
</ul>
Furthermore, consider these drawbacks:<br />
<ul style="text-align: left;">
<li>cglib creates a new class for each proxy. Eventually, this will litter
up your permanent generation heap space</li>
<li>You cannot proxy methods that take arguments.</li>
<li>If your interface takes arguments, the method delegation will simply not
work without an exception thrown (the return value will always be <code>null</code>). If your interface requires another return type (even if that is more general), you will get a <code>IllegalArgumentException</code>. </li>
</ul>
<br />
<br />
<h1 style="text-align: left;">
Multicast delegate</h1>
The <code>MulticastDelegate</code> works a little different than the <code>MethodDelegate</code> even though it aims at similar functionality. For using the <code>MulticastDelegate</code>, we require an object that implements an interface:<br />
<br />
<pre class="brush: java">public interface DelegatationProvider {
void setValue(String value);
}
public class SimpleMulticastBean implements DelegatationProvider {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}</pre>
<br />
Based on this interface-backed bean we can create a <code>MulticastDelegate</code> that dispatches all calls to <code>setValue(String)</code> to several classes that implement the <code>DelegationProvider</code> interface:<br />
<br />
<pre class="brush: java">@Test
public void testMulticastDelegate() throws Exception {
MulticastDelegate multicastDelegate = MulticastDelegate.create(
DelegatationProvider.class);
SimpleMulticastBean first = new SimpleMulticastBean();
SimpleMulticastBean second = new SimpleMulticastBean();
multicastDelegate = multicastDelegate.add(first);
multicastDelegate = multicastDelegate.add(second);
DelegatationProvider provider = (DelegatationProvider)multicastDelegate;
provider.setValue("Hello world!");
assertEquals("Hello world!", first.getValue());
assertEquals("Hello world!", second.getValue());
}
</pre>
<br />
Again, there are some drawbacks:<br />
<ul style="text-align: left;">
<li>The objects need to implement a single-method interface. This sucks for
third-party libraries and is awkward when you use CGlib to do some <i>magic</i> where this magic gets exposed to the <i>normal code</i>.
Also, you could implement your own delegate easily (without byte code
though but I doubt that you win so much over manual delegation).</li>
<li>When your delegates return a value, you will receive only that of the
last delegate you added. All other return values are lost (but retrieved
at some point by the multicast delegate). </li>
</ul>
<br />
<br />
<h1 style="text-align: left;">
Constructor delegate</h1>
A <code>ConstructorDelegate</code> allows to create a byte-instrumented <a href="http://en.wikipedia.org/wiki/Factory_method_pattern">factory method</a>. For that, that we first require an interface with a single method <code>newInstance</code> which returns an <code>Object</code> and takes any amount of parameters to be used for a constructor call of the specified class. For example, in order to create a <code>ConstructorDelegate</code> for the <code>SampleBean</code>, we require the following to call <code>SampleBean</code>'s default (no-argument) constructor:<br />
<br />
<pre class="brush: java">public interface SampleBeanConstructorDelegate {
Object newInstance();
}
@Test
public void testConstructorDelegate() throws Exception {
SampleBeanConstructorDelegate constructorDelegate = (SampleBeanConstructorDelegate) ConstructorDelegate.create(
SampleBean.class, SampleBeanConstructorDelegate.class);
SampleBean bean = (SampleBean) constructorDelegate.newInstance();
assertTrue(SampleBean.class.isAssignableFrom(bean.getClass()));
}
</pre>
<br />
<br />
<h1 style="text-align: left;">
Parallel sorter</h1>
The <code>ParallelSorter</code> claims to be a faster alternative to the Java standard library's array sorters when sorting arrays of arrays:<br />
<br />
<pre class="brush: java">@Test
public void testParallelSorter() throws Exception {
Integer[][] value = {
{4, 3, 9, 0},
{2, 1, 6, 0}
};
ParallelSorter.create(value).mergeSort(0);
for(Integer[] row : value) {
int former = -1;
for(int val : row) {
assertTrue(former < val);
former = val;
}
}
}
</pre>
<br />
The <code>ParallelSorter</code> takes an array of arrays and allows to either apply a merge sort or a quick sort on every row of the array. Be however careful when you use it:<br />
<ul style="text-align: left;">
<li> When using arrays of primitives, you have to call merge sort with explicit sorting ranges (e.g. <code>ParallelSorter.create(value).mergeSort(0, 0, 3)</code> in the example. Otherwise, the <code>ParallelSorter</code> has a pretty obvious bug where it tries to cast the primitive array to an array <code>Object[]</code> what will cause a <code>ClassCastException</code>.</li>
<li>If the array rows are uneven, the first argument will determine the length of what row to consider. Uneven rows will either lead to the extra values not being considered for sorting or a <code>ArrayIndexOutOfBoundException</code>.</li>
</ul>
Personally, I doubt that the <code>ParallelSorter</code> really offers a time advantage. Admittedly, I did however not yet try to benchmark it. If you tried it, I'd be happy to hear about it in the comments.<br />
<ul style="text-align: left;">
</ul>
<br />
<br />
<h1 style="text-align: left;">
Fast class and fast members</h1>
The <code>FastClass</code> promises a faster invocation of methods than the <a href="http://docs.oracle.com/javase/tutorial/reflect/">Java reflection API</a> by wrapping a Java class and offering similar methods to the reflection API:<br />
<br />
<pre class="brush: java">@Test
public void testFastClass() throws Exception {
FastClass fastClass = FastClass.create(SampleBean.class);
FastMethod fastMethod = fastClass.getMethod(SampleBean.class.getMethod("getValue"));
MyBean myBean = new MyBean();
myBean.setValue("Hello cglib!");
assertTrue("Hello cglib!", fastMethod.invoke(myBean, new Object[0]));
}</pre>
<br />
Besides the demonstrated <code>FastMethod</code>, the <code>FastClass</code> can also create <code>FastConstructor</code>s but no fast fields. But how can the FastClass be faster than normal reflection? Java reflection is executed by JNI where method invocations are executed by some <code>C</code>-code. The <code>FastClass</code> on the other side creates some byte code that calls the method directly from within the JVM. However, the newer versions of the HotSpot JVM (and probably many other modern JVMs) know a concept called inflation where the JVM will <a href="http://www.docjar.com/html/api/sun/reflect/ReflectionFactory.java.html">translate reflective method calls</a> into <a href="http://www.docjar.com/html/api/sun/reflect/NativeMethodAccessorImpl.java.html">native version</a>'s of <code>FastClass</code> when a reflective method is executed often enough. You can even control this behavior (at least on a HotSpot JVM) with setting the <code>sun.reflect.inflationThreshold</code> property to a lower value. (The default is 15.) This property determines after how many reflective invocations a JNI call should be substituted by a byte code instrumented version. I would therefore recommend to not use <code>FastClass</code> on modern JVMs, it can however fine-tune performance on older Java virtual machines.<br />
<br />
<h1 style="text-align: left;">
cglib proxy</h1>
The cglib <code>Proxy</code> is a reimplementation of the Java <code>Proxy</code> class mentioned in the beginning of this article. It is intended to allow using the Java library's proxy in Java versions before Java 1.3 and differs only in minor details. The better documentation of the cglib <code>Proxy</code> can however be found in the <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html">Java standard library's <code>Proxy</code> javadoc</a> where an example of its use is provided. For this reason, I will skip a more detailed discussion of the cglib's <code>Proxy</code> at this place.<br />
<br />
<h1 style="text-align: left;">
A final word of warning </h1>
After this overview of cglib's functionality, I want to speak a final word of warning. All cglib classes generate byte code which results in additional classes being stored in a special section of the JVM's memory: The so called perm space. This permanent space is, as the name suggests, used for permanent objects that do not usually get garbage collected. This is however not completely true: Once a <code>Class</code> is loaded, it cannot be unloaded until the loading <code>ClassLoader</code> becomes available for garbage collection. This is only the case the Class was loaded with a custom <code>ClassLoader</code> which is not a native JVM system <code>ClassLoader</code>. This <code>ClassLoader</code> can be garbage collected if itself, all <code>Class</code>es it ever loaded and all instances of all <code>Class</code>es it ever loaded become available for garbage collection. This means: If you create more and more classes throughout the life of a Java application and if you do not take care of the removal of these classes, you will sooner or later run of of perm space what will result in your <a href="http://ghb.freshblurbs.com/blog/2005/05/19/explaining-java-lang-outofmemoryerror-permgen-space.html">application's death by the hands of an <code>OutOfMemoryError</code></a>. Therefore, use cglib sparingly. However, if you use cglib wisely and carefully, you can really do amazing things with it that go beyond what you can do with non-instrumented Java applications.<br />
<br />
Lastly, when creating projects that depend on cglib, you should be aware of the fact that the cglib project is not as well maintained and active as it should be, considering its popularity. The missing documentation is a first hint. The often messy public API a second. But then there are also broken deploys of cglib to Maven central. The mailing list reads like an archive of spam messages. And the release cycles are rather unstable. You might therefore want to have a look at <a href="http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/">javassist</a>, the only real low-level alternative to cglib. Javassist comes bundled with a pseudo-java compiler what allows to create quite amazing byte code instrumentations without even understanding Java byte code. If you like to get your hands dirty, you might also like <a href="http://asm.ow2.org/">ASM</a> on top of which cglib is built. ASM comes with a great documentation of both the library and Java class files and their byte code.<br />
<br />
Note that these examples only run with cglib 2.2.2 and are not compatible with the <a href="http://sourceforge.net/projects/cglib/files/cglib3/">newest release 3 of cglib</a>. Unfortunately, I experienced the newest cglib version to occasionally produce invalid byte code which is why I considered an old version and also use this version in production. Also, note that most projects using cglib move the library to their own namespace in order to avoid version conflicts with other dependencies such as <a href="http://docs.spring.io/spring/docs/3.2.5.RELEASE/javadoc-api/org/springframework/cglib/package-summary.html">for example demonstrated by the Spring project</a>. You should do the same with your project when making use of cglib. Tools such like <a href="https://code.google.com/p/jarjar/">jarjar</a> can help you with the automation of this good practice. </div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com14tag:blogger.com,1999:blog-3237092529299307504.post-33029481996689846132013-10-28T11:31:00.002+01:002013-12-09T16:28:01.328+01:00Java class loading anomaly<div dir="ltr" style="text-align: left;" trbidi="on">
I learned about a (for me) initially rather unintuitive anomaly in the Java language today. Of course, this is not technically an anomaly but something well-defined in the <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/">JVMS</a>. However, I was not aware of the class loading behavior described in this blog entry, despite having read the specification, which I decided this was worth sharing.<br />
<br />
I stumbled onto this when I was curious about reasons why it is <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.7.1">not allowed to use static fields referencing an <span style="font-family: "Courier New",Courier,monospace;">enum</span> for annotation values</a> while it is allowed for any other value. It turns out that the Java compiler is not allowed to substitute <span style="font-family: "Courier New",Courier,monospace;">enum</span> fields at compile time while it can substitute such values for all other possible annotation members. But what does this mean in practice?<br />
<br />
Let's look at this example class:
<br />
<br />
<pre class="brush: java">@MyAnnotation(HelloWorldHelper.VAL1)
class MyClass {
public static void main(String[] args) {
System.out.println(MyClass.class.getAnnotation(MyAnnotation.class).value());
System.out.println(HelloWorldHelper.VAL2);
System.out.println(HelloWorldHelper.class.getName());
System.out.println(HelloWorldHelper.VAL3);
}
}</pre>
<br />
with the following helper classes:<br />
<br />
<pre class="brush: java">enum MyEnum {
HELLO_WORLD_ENUM
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String value();
}
class HelloWorldHelper {
public static final String VAL1 = "Hello world!";
public static final String VAL2 = "Hello world again!";
public static final MyEnum VAL3 = MyEnum.HELLO_WORLD_ENUM;
static { System.out.println("Initialized class: HelloWorldHelper"); }
}
</pre>
<br />
the output (for me first unexpectedly) returns as:<br />
<br />
<pre>Hello world!
Hello world again!
HelloWorldHelper
Initialized class: HelloWorldHelper
HELLO_WORLD_ENUM
</pre>
<br />
But why is this so? The Java compiler substitutes constant references to <span style="font-family: "Courier New",Courier,monospace;">String</span> values (this is also true for primitives) with a direct entry of the referenced <span style="font-family: "Courier New",Courier,monospace;">String</span>'s value in the referencing <a href="http://en.m.wikipedia.org/wiki/Java_class_file#The_constant_pool">class's constant pool</a>. This also means that you could not load another class <span style="font-family: "Courier New",Courier,monospace;">HelloWorldHelper</span> at runtime and expect those values to be adjusted in <span style="font-family: "Courier New",Courier,monospace;">MyClass</span>. This adjustment would only happen for the <span style="font-family: "Courier New",Courier,monospace;">MyEnum</span> value which is as a matter of fact resolved at runtime (and therefore causes the <span style="font-family: "Courier New",Courier,monospace;">HelloWorldHelper</span> class to be loaded <b>and initialized</b> which can be observed by the execution of the <span style="font-family: "Courier New",Courier,monospace;">static</span> block). The motive for not allowing this anomaly for <span style="font-family: "Courier New",Courier,monospace;">enum</span>s but for <code>String</code>s might well be (of course, I can only guess) that the Java language specification treats strings differently than other object types such as the primitive wrapper types. Usually, copying an object reference would break Java's contract of object identity. Strings on the other side will still be identical even after they were technically duplicated due to Java's concept of <a href="http://en.m.wikipedia.org/wiki/String_interning">pooling load-time strings</a>. As mentioned before, primitives can also be copied into the referencing class since primitive types are implemented as <a href="http://en.m.wikipedia.org/wiki/Value_type-types">value types</a> in Java which do not know a concept of identity. However, the <span style="font-family: "Courier New",Courier,monospace;">HelloWorldHelper</span> class would be loaded when for example referencing a non-primitive <span style="font-family: "Courier New",Courier,monospace;">Integer</span> boxing type.<br />
<br />
Interestingly enough does <span style="font-family: "Courier New",Courier,monospace;">HelloWorldHelper.class.getName()</span> does not require the <span style="font-family: "Courier New",Courier,monospace;">HelloWorldHelper </span>class to be initialized. When looking at the generated byte code, one can observe that the <span style="font-family: "Courier New",Courier,monospace;">HelloWorldHelper</span> class is actually referenced this time and will as a matter of fact be <b>loaded</b> into the JVM. However, <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.5">JVMS §5.5</a> does not specify such a reflective access as a reason to <b>initialize</b> the class which is why the above output appears the way observed.</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-4783448454124242972013-07-18T17:09:00.001+02:002013-11-14T17:36:19.051+01:00Extending Guava caches to overflow to disk<div dir="ltr" style="text-align: left;" trbidi="on">
Caching allows you to significantly speed up applications with only little effort. Two great cache implementations for the Java platform are the <a href="http://code.google.com/p/guava-libraries/wiki/CachesExplained">Guava caches</a> and <a href="http://ehcache.org/">Ehcache</a>. While Ehcache is much richer in features (such as its <a href="http://ehcache.org/documentation/apis/search">Searchable API</a>, the possibility of persisting caches to disk or overflowing to <a href="http://ehcache.org/documentation/user-guide/bigmemory"><i>big memory</i></a>), it also comes with quite an overhead compared to Guava. In a recent project, I found a need to overflow a comprehensive cache to disk but at the same time, I regularly needed to invalidate particular values of this cache. Because Ehcache's Searchable API is only accessible to in-memory caches, this put me in quite a dilemma. However, it was quite easy to extend a Guava cache to allow overflowing to disk in a structured manner. This allowed me both overflowing to disk and the required invalidation feature. In this article, I want to show how this can be achieved.<br />
<br />
I will implement this file persisting cache <code>FilePersistingCache</code> in form of a wrapper to an actual Guava <code>Cache</code> instance. This is of course not the most elegant solution (more elegant would to implement an actual Guava <a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/Cache.html"><code>Cache</code></a> with this behavior), but I will do for most cases.<br />
<br />
To begin with, I will define a protected method that creates the backing cache I mentioned before:<br />
<br />
<pre class="brush: java">private LoadingCache<K, V> makeCache() {
return customCacheBuild()
.removalListener(new PersistingRemovalListener())
.build(new PersistedStateCacheLoader());
}
protected CacheBuilder<K, V> customCacheBuild(CacheBuilder<K, V> cacheBuilder) {
return CacheBuilder.newBuilder();
}</pre>
<br />
The first method will be used internally to build the necessary cache. The second method is supposed to be overridden in order to implement any custom requirement to the cache as for example an expiration strategy. This could for example be a maximum value of entries or soft references. This cache will be used just as any other Guava cache. The key to the cache's functionality are the <code>RemovalListener</code> and the <code>CacheLoader</code> that are used for this cache. We will define these two implementation as inner classes of the <code>FilePersistingCache</code>:<br />
<br />
<pre class="brush: java">private class PersistingRemovalListener implements RemovalListener<K, V> {
@Override
public void onRemoval(RemovalNotification<K, V> notification) {
if (notification.getCause() != RemovalCause.COLLECTED) {
try {
persistValue(notification.getKey(), notification.getValue());
} catch (IOException e) {
LOGGER.error(String.format("Could not persist key-value: %s, %s",
notification.getKey(), notification.getValue()), e);
}
}
}
}
public class PersistedStateCacheLoader extends CacheLoader<K, V> {
@Override
public V load(K key) {
V value = null;
try {
value = findValueOnDisk(key);
} catch (Exception e) {
LOGGER.error(String.format("Error on finding disk value to key: %s",
key), e);
}
if (value != null) {
return value;
} else {
return makeValue(key);
}
}
}</pre>
<br />
As obvious from the code, these inner classes call methods of <code>FilePersistingCache</code> we did not yet define. This allows us to define custom serialization behavior by overriding this class. The removal listener will check the reasons for a cache entry being evicted. If the <a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/RemovalCause.html"><code>RemovalCause</code></a> is <code>COLLECTED</code>, the cache entry was not manually removed by the user but it was removed as a consequence of the cache's eviction strategy. We will therefore only try to persist a cache entry if the user did not wish the entries removal. The <code>CacheLoader</code> will first attempt to restore an existent value from disk and create a new value only if such a value could not be restored.<br />
<br />
The missing methods are defined as follows: <br />
<br />
<pre class="brush: java">private V findValueOnDisk(K key) throws IOException {
if (!isPersist(key)) return null;
File persistenceFile = makePathToFile(persistenceDirectory, directoryFor(key));
(!persistenceFile.exists()) return null;
FileInputStream fileInputStream = new FileInputStream(persistenceFile);
try {
FileLock fileLock = fileInputStream.getChannel().lock();
try {
return readPersisted(key, fileInputStream);
} finally {
fileLock.release();
}
} finally {
fileInputStream.close();
}
}
private void persistValue(K key, V value) throws IOException {
if (!isPersist(key)) return;
File persistenceFile = makePathToFile(persistenceDirectory, directoryFor(key));
persistenceFile.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(persistenceFile);
try {
FileLock fileLock = fileOutputStream.getChannel().lock();
try {
persist(key, value, fileOutputStream);
} finally {
fileLock.release();
}
} finally {
fileOutputStream.close();
}
}
private File makePathToFile(@Nonnull File rootDir, List<String> pathSegments) {
File persistenceFile = rootDir;
for (String pathSegment : pathSegments) {
persistenceFile = new File(persistenceFile, pathSegment);
}
if (rootDir.equals(persistenceFile) || persistenceFile.isDirectory()) {
throw new IllegalArgumentException();
}
return persistenceFile;
}
protected abstract List<String> directoryFor(K key);
protected abstract void persist(K key, V value, OutputStream outputStream)
throws IOException;
protected abstract V readPersisted(K key, InputStream inputStream)
throws IOException;
protected abstract boolean isPersist(K key);
</pre>
<br />
The implemented methods take care of serializing and deserializing values while synchronizing file access and guaranteeing that streams are closed appropriately. The last four methods remain abstract and are up to the cache's user to implement. The <code>directoryFor(K)</code> method should identify a unique file name for each key. In the easiest case, the <code>toString</code> method of the key's <code>K</code> class is implemented in such a way. Additionally, I made the <code>persist</code>, <code>readPersisted</code> and <code>isPersist</code> methods abstract in order to allow for a custom serialization strategy such as using <a href="http://code.google.com/p/kryo/">Kryo</a>. In the easiest scenario, you would use the built in Java functionality which uses <code>ObjectInputStream</code> and <code>ObjectOutputStream</code>. For <code>isPersist</code>, you would return <code>true</code>, assuming that you would only use this implementation if you need serialization. I added this feature to support mixed caches where you can only serialize values to some keys. Be sure not to close the streams within the <code>persist</code> and <code>readPersisted</code> methods since the file system locks rely on the streams to be open. The above implementation will take care of closing the stream for you.<br />
<br />
Finally, I added some service methods to access the cache. Implementing Guava's <code>Cache</code> interface would of course be a more elegant solution:<br />
<br />
<pre class="brush: java">public V get(K key) {
return underlyingCache.getUnchecked(key);
}
public void put(K key, V value) {
underlyingCache.put(key, value);
}
public void remove(K key) {
underlyingCache.invalidate(key);
}
protected Cache<K, V> getUnderlyingCache() {
return underlyingCache;
}
</pre>
<br />
Of course, this solution can be further improved. If you use the cache in a concurrent scenario, be further aware that the <code>RemovalListener</code> is, other than most Guava cache method's executed asynchronously. As obvious from the code, I added file locks to avoid read/write conflicts on the file system. This asynchronicity does however imply that there is a small chance that a value entry gets recreated even though there is still a value in memory. If you need to avoid this, be sure to call the underlying cache's <code>cleanUp</code> method within the wrapper's get method. Finally, remember to clean up the file system when you expire your cache. Optimally, you will use a temporary folder of your system for storing your cache entries in order to avoid this problem at all. In the example code, the directory is represented by an instance field named <code>persistenceDirectory</code> which could for example be initialized in the constructor.<br />
<br />
<i>Update</i>: I wrote a clean implementation of what I described above <a href="https://github.com/raphw/guava-cache-overflow-extension">which you can find on my Git Hub page</a> and on <a href="http://search.maven.org/#browse|1935674660">Maven Central</a>. Feel free to use it, if you need to store your cache objects on disk.</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com2tag:blogger.com,1999:blog-3237092529299307504.post-54967829777493652202013-07-05T16:04:00.004+02:002013-07-05T22:13:06.997+02:00Object-based micro-locking for concurrent applications by using Guava<div dir="ltr" style="text-align: left;" trbidi="on">
One of the presumably most annoying problems with writing concurrent Java applications is the handling of resources that are shared among threads as for example a web applications' session and application data. As a result, many developers choose to not synchronize such resources at all, if an application's concurrency level is low. It is for example unlikely that a session resource is accessed concurrently: if request cycles complete within a short time span, it is unlikely that a user will ever send a concurrent request using a second browser tab while the first request cycle is still in progress. With the ascent of Ajax-driven web applications, this trusting approach does however become increasingly hazardous. In an Ajax-application, a user could for example request a longer-lasting task to complete while starting a similar task in another browser window. If these tasks access or write session data, you need to synchronize such access. Otherwise you will face subtle bugs or even security issues as it it for example <a href="http://www.ibm.com/developerworks/library/j-jtp09238/index.html">pointed out in this blog entry</a>.<br>
<br>
An easy way of introducing a lock is by Java's <span style="font-family: "Courier New",Courier,monospace;">synchronized</span> keyword. This example does for example only block a request cycle's thread if a new instance needs to be written to the session.<br>
<pre class="brush: java">HttpSession session = request.getSession(true);
if (session.getAttribute("shoppingCart") == null) {
synchronize(session) {
if(session.getAttribute("shoppingCart")= null) {
cart = new ShoppingCart();
session.setAttribute("shoppingCart");
}
}
}
ShoppingCart cart = (ShoppingCart)session.getAttribute("shoppingCart");
doSomethingWith(cart);
</pre>
<br>
This code will add a new instance of <span style="font-family: "Courier New",Courier,monospace;">ShoppingCart</span> to the session. Whenever no shopping cart is found, the code will acquire a monitor for the current user's session and add a new <span style="font-family: "Courier New",Courier,monospace;">ShoppingCart</span> to the <span style="font-family: "Courier New",Courier,monospace;">HttpSession</span> of the current user. This solution has however several downsides:<br>
<ol style="text-align: left;">
<li>Whenever any value is added to the session by the same method as described above, any thread that is accessing the current session will block. This will also happen, when two threads try to access different session values. This blocks the application more restrictive than it would be necessary.</li>
<li>A servlet API implementation might choose to implement <span style="font-family: "Courier New",Courier,monospace;">HttpSession</span> not to be a singleton instance. If this is the case, the whole synchronization would fail. (This is however not a common implementation of the servlet API.)</li>
</ol>
It would be much better to find a different object that the <span style="font-family: "Courier New",Courier,monospace;">HttpSession</span> instance to synchronize. Creating such objects and sharing them between different threads would however introduce the same problems. A nice way of avoiding that is by using Guava caches which are both intrinsically concurrent and allow the use of weak keys:<br>
<br>
<pre class="brush: java">LoadingCache<String, Object> monitorCache = CacheBuilder.newBuilder()
.weakValues()
.build(
new CacheLoader<String, Object>{
public Object load(String key) {
return new Object();
}
});
</pre>
<br>
Now we can rewrite the locking code like this:<br>
<br>
<pre class="brush: java">HttpSession session = request.getSession(true);
Object monitor = ((LoadingCache<String,Object>)session.getAttribute("cache"))
.get("shoppingCart");
if (session.getAttribute("shoppingCart") == null) {
synchronize(monitor) {
if(session.getAttribute("shoppingCart")= null) {
cart = new ShoppingCart();
session.setAttribute("shoppingCart");
}
}
}
ShoppingCart cart = (ShoppingCart)session.getAttribute("shoppingCart");
doSomethingWith(cart);
</pre>
<br>
The Guava cache is self-populating and will simply return a monitor Object instance which can be used as a lock on the shared session resource which is universially identified by shoppingCart. The Guava cache is backed by a ConcurrentHashMap which avoids synchronization by only synchronizing on the <a href="http://en.wikipedia.org/wiki/Hash_table">map key's hash value bucket</a>. As a result, the application was made thread safe without globally blocking it. Also, you do not need to worry about running out of memory sice the monitors (and the related cache entries) will be garbage collected if they are not longer in use. If you do not use other caches, you can even consider soft references to optimize run time.</div><div dir="ltr" style="text-align: left;" trbidi="on"><br></div><div dir="ltr" style="text-align: left;" trbidi="on">This mechanism can of course be refined. Instead of returning an <span style="font-family: "Courier New",Courier,monospace;">Object</span> instance, one could for example also return a <span style="font-family: "Courier New",Courier,monospace;">ReadWriteLock</span>. Also, it is important to instanciate the <span style="font-family: "Courier New",Courier,monospace;">LoadingCache</span> on the session's start up. This can be achieved by for example a <span style="font-family: "Courier New",Courier,monospace;">HttpSessionListener</span>.</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-28534742368333703962013-06-15T15:48:00.000+02:002013-06-15T17:32:01.342+02:00Subtyping in Java generics<div dir="ltr" style="text-align: left;" trbidi="on">
Generic types introduce a new spectrum of type safety to Java program. At the same type, generic types can be quite expressive, especially when using <a href="http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html">wildcards</a>. In this article, I want to explain how subtyping works with Java generics.<br />
<br />
<h3 style="text-align: left;">
General thoughts on generic type subtyping</h3>
<div>
<br />
Different generic types of the same class or interface do not define a <a href="https://en.wikipedia.org/wiki/Subtyping">subtype</a> hierarchy linear to the subtype hierarchy of possible generic argument types. This means for example that <span style="font-family: Courier New, Courier, monospace;">List<Number></span> is not a supertype of <span style="font-family: Courier New, Courier, monospace;">List<Integer></span>. The following <a href="http://docs.oracle.com/javase/tutorial/extra/generics/subtype.html">prominent example</a> gives a good intuition why this kind of subtyping is prohibited:<br />
<br /></div>
<pre class="brush: java">// assuming that such subtyping was possible
ArrayList<Number> list = new ArrayList<Integer>();
// the next line would cause a ClassCastException
// because Double is no subtype of Integer
list.add(new Double(.1d))
</pre>
<div>
<br />
Before discussing this in further detail, let us first think a little bit about types in general: types introduce redundancy to your program. When you define a variable to be of type <span style="font-family: Courier New, Courier, monospace;">Number</span>, you make sure that this variable only references objects that know how to handle any method defined by <span style="font-family: Courier New, Courier, monospace;">Number</span> such as <span style="font-family: Courier New, Courier, monospace;">Number.doubleValue</span>. By doing so, you make sure that you can safely call <span style="font-family: Courier New, Courier, monospace;">doubleValue</span> on any object that is currently represented by your variable and you do not longer need to keep track of the actual type of the variable's referenced object. (As long as the reference is not <span style="font-family: Courier New, Courier, monospace;">null</span>. The <span style="font-family: Courier New, Courier, monospace;">null</span> reference is actually one of the few exceptions of Java's strict type safety. Of course, the <span style="font-family: Courier New, Courier, monospace;">null</span> "object" does not know how to handle any method call.) If you however tried to assign an object of type <span style="font-family: Courier New, Courier, monospace;">String</span> to this <span style="font-family: Courier New, Courier, monospace;">Number</span>-typed variable, the Java compiler would recognize that this object does in fact not understand the methods required by <span style="font-family: Courier New, Courier, monospace;">Number</span> and would throw an error because it could otherwise not guarantee that a possible future call to for example <span style="font-family: Courier New, Courier, monospace;">doubleValue</span> would be understood. However, if we lacked types in Java, the program would not change its functionality just by that. As long if we never made an errornous method call, a Java program without types would be equivalent. Viewed in this light, types are merely to prevent us developers of doing something stupid while taking away a little bit of our freedom. Additionally, types are a nice way of implicit documentary of your program. (Other programming languages such as <a href="http://www.objs.com/x3h7/smalltalk.htm">Smalltalk</a> do not know types and besides being anoying most of the time this can also have its benefits.)</div>
<div>
<br /></div>
<div>
With this, let's return to generics. By defining generic types you allow users of your generic class or interface to add some type safety to their code because they can restrain themselfs to only using your class or interface in a certain way. When you for example define a <span style="font-family: Courier New, Courier, monospace;">List</span> to only contain <span style="font-family: Courier New, Courier, monospace;">Number</span>s by defining <span style="font-family: Courier New, Courier, monospace;">List<Number></span>, you advice the Java compiler to throw an error whenever you for example try to add a <span style="font-family: Courier New, Courier, monospace;">String</span>-typed object into this list. Before Java generics, you simply had to trust that the list only contained <span style="font-family: Courier New, Courier, monospace;">Number</span>s. This could be especially painful, when you handed references of your collections to methods defined in third-party code or received collections from this code. With generics, you could assure that all elements in your <span style="font-family: Courier New, Courier, monospace;">List</span> were of a certain supertype even at compile time. </div>
<div>
<br /></div>
<div>
At the same time, by using generics you loose some type-safety <i>within </i>your generic class or interface. When you for example implement a generic List</div>
<div>
<br /></div>
<pre class="brush: java">class MyList<T> extends ArrayList<T> { }</pre>
<div>
<br /></div>
<div>
you do not know the type of <span style="font-family: Courier New, Courier, monospace;">T</span> within <span style="font-family: Courier New, Courier, monospace;">MyList</span> and you have to expect that the type could be as unsophisticated as <span style="font-family: Courier New, Courier, monospace;">Object</span>. This is why you can restrain your generic type to require some minimum type:</div>
<div>
<br /></div>
<pre class="brush: java">class MyList<T extends Number> extends ArrayList<T> {
double sum() {
double sum = .0d;
for(Number val : this) {
sum += val.doubleValue();
}
return sum;
}
}
</pre>
<div>
<br /></div>
<div>
This allows you to asume that any object in <span style="font-family: Courier New, Courier, monospace;">MyList</span> is a subtype of <span style="font-family: Courier New, Courier, monospace;">Number</span>. That way, you gain some type safety within your generic class.<br />
<br /></div>
<h3 style="text-align: left;">
Wildcards</h3>
<div>
<br />
Wildcards are the Java equivalent to saying <i>whatever type</i>. Consequently, you are not allowed to use wildcards when instanciating a type, i.e. defining what concrete type some instance of a generic class should represent. A type instanciation occurs for example when instanciating an object as <span style="font-family: Courier New, Courier, monospace;">new ArrayList<Number></span> where you among other things implicitly call the <i>type constructor</i> of <span style="font-family: Courier New, Courier, monospace;">ArrayList</span> which is contained in its class definition</div>
<div>
<br /></div>
<pre class="brush: java">class ArrayList<T> implements List<T> { ... }</pre>
<div>
<br /></div>
<div>
with <span style="font-family: Courier New, Courier, monospace;">ArrayList<T></span> being a trivial type constructor with one single argument. Thus, neither within <span style="font-family: Courier New, Courier, monospace;">ArrayList</span><span style="font-family: inherit;">'s</span> type constructor definition (<span style="font-family: Courier New, Courier, monospace;">ArrayList<T></span>) nor in the call of this constructor (<span style="font-family: Courier New, Courier, monospace;">new ArrayList<Number></span>) you are allowed to use a wildcard. When you are however only referring to a type without instanciating a new object, you can use wildcards, such as in local variables. Therefore, the following definition is allowed:</div>
<div>
<br /></div>
<pre class="brush: java">ArrayList<?> list;</pre>
<div>
<br /></div>
<div>
By defining this variable, you are creating a place holder for an <span style="font-family: Courier New, Courier, monospace;">ArrayList</span> of any generic type. With this little restriction of the generic type however, you cannot add objects to the list via its reference by this variable. This is because you made such a general assumption of the generic type represented by the variable <span style="font-family: Courier New, Courier, monospace;">list</span> that it would not be safe to add an object of for example type <span style="font-family: Courier New, Courier, monospace;">String</span>, because the list beyond <span style="font-family: Courier New, Courier, monospace;">list</span> could require objects of any other <b>subtype</b> of some type. In general this required type is unknown and there exists no object which is a subtype of any type and could be added safely. (The exception is the <span style="font-family: Courier New, Courier, monospace;">null</span> reference which abrogates type checking. However, you should never add <span style="font-family: Courier New, Courier, monospace;">null</span> to collections.) At the same time, all objects you get out of the list will be of type <span style="font-family: Courier New, Courier, monospace;">Object</span> because this is the only safe asumption about a common <b>supertype</b> of al possible lists represented by this variable. For this reason, you can form more elaborate wildcards using the <span style="font-family: Courier New, Courier, monospace;">extends</span> and <span style="font-family: Courier New, Courier, monospace;">super</span> keywords:</div>
<div>
<br /></div>
<pre class="brush: java">ArrayList<? extends Number> list1 = new ArrayList<Integer>();
ArrayList<? super Number> list2 = new ArrayList<Object>();</pre>
<div>
<br /></div>
<div>
When a wildcard defines a minimum subtype via <span style="font-family: Courier New, Courier, monospace;">extends</span> such as <span style="font-family: Courier New, Courier, monospace;">list1</span>, the compiler will enforce that any objects you get out of this list will be some <b>subtype</b> of <span style="font-family: Courier New, Courier, monospace;">Number</span> such as for example <span style="font-family: Courier New, Courier, monospace;">Integer</span>. Similarly, when defining a maximum subtype via <span style="font-family: Courier New, Courier, monospace;">super</span> as in <span style="font-family: Courier New, Courier, monospace;">list2</span>, you can expect any list to represent a <b>supertype</b> of <span style="font-family: Courier New, Courier, monospace;">Number</span> such as <span style="font-family: Courier New, Courier, monospace;">Object</span>. Thus you can safely add instances of any subtype of <span style="font-family: Courier New, Courier, monospace;">Number</span> to this list.<br />
<br />
Finally, you should note that you can actually use wildcards within type constructors if the used type arguments are itself generic. The following use of a type constructor is for example perfectly legal:<br />
<br />
<pre class="brush: java">ArrayList<?> list = new ArrayList<List<?>>();
</pre>
<br />
In this example, the requirement that the <span style="font-family: Courier New, Courier, monospace;">ArrayList</span> must not be constructed by using a wildcard type is fullfilled because the wildcard is applied on the type argument and not on the constructed type itself.<br />
<br />
As for subtyping of generic classes, we can summarize that some generic type is a subtype of another type if the <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8">raw type</a> is a subtype and if the generic types are all subtypes to each other. Because of this we can define<br />
<br />
<pre class="brush: java">List<? extends Number> list = new ArrayList<Integer>();</pre>
<br />
because the raw type <span style="font-family: Courier New, Courier, monospace;">ArrayList</span> is a subtype of <span style="font-family: Courier New, Courier, monospace;">List</span> and because the generic type <span style="font-family: Courier New, Courier, monospace;">Integer</span> is a subtype of <span style="font-family: Courier New, Courier, monospace;">? extends Number</span>.<br />
<br />
Finally, be aware that a wildcard <span style="font-family: Courier New, Courier, monospace;">List<?></span> is a shortcut for <span style="font-family: Courier New, Courier, monospace;">List<? extends Object></span><span style="font-family: inherit;"> since this is a commonly used type definition.</span> If the generic type constructor does however enforce another lower type boundary as for example in<br />
<br />
<pre class="brush: java">class GenericClass<T extends Number> { }</pre>
<br />
a variable <span style="font-family: Courier New, Courier, monospace;">GenericClass<?></span> would instead be a shortcut to <span style="font-family: Courier New, Courier, monospace;">GenericClass<? extends Number></span>.<br />
<br />
<h3 style="text-align: left;">
The get-and-put principle</h3>
</div>
<div>
<br />
This observation leads us to the <i><a href="http://www.ibm.com/developerworks/library/j-jtp07018/">get-and-put principle</a></i>. This principle is best explained by another famous example:</div>
<div>
<br /></div>
<pre class="brush: java">class CopyClass {
<T> void copy(List<T> from, List<T> to) {
for(T item : from) to.add(item);
}
}</pre>
<div>
<br /></div>
<div>
This method definition is not very flexible. If you had some list <span style="font-family: Courier New, Courier, monospace;">List<Integer></span> you could not copy its contents to some <span style="font-family: Courier New, Courier, monospace;">List<Number></span> or even <span style="font-family: Courier New, Courier, monospace;">List<Object></span>. Therefore, the get-and-put principle states that you should always use lower-bounded wildcards (<span style="font-family: Courier New, Courier, monospace;">? extends</span>) when you only read objects from a generic instance (via a return argument) and always use upper-bounded wildcards (<span style="font-family: Courier New, Courier, monospace;">? super</span>) when you only provide arguments to a generic instance's methods. Therefore, a better implementation of <span style="font-family: Courier New, Courier, monospace;">MyAddRemoveList</span> would look like this:</div>
<div>
<br /></div>
<div>
<pre class="brush: java">class CopyClass {
<T> void copy(List<? extends T> from, List<? super T> to) {
for(T item : from) to.add(item);
}
}</pre>
</div>
<div>
<br />
Since you are only reading from one list and writing to the other list, Unfortunately, this is something that is easily forgoten and you can even find classes in the Java core API that do not apply the get-and-put principle. (Note that the above method also describes a generic type constructor.)<br />
<br /></div>
<div>
Note that the types <span style="font-family: Courier New, Courier, monospace;">List<? extends T></span> and <span style="font-family: Courier New, Courier, monospace;">List<? super T></span> are both less specific than the requirement of <span style="font-family: Courier New, Courier, monospace;">List<T></span>. Also note that this kind of subtyping is already implicit for non-generic types. If you define a method that asks for a method parameter of type <span style="font-family: Courier New, Courier, monospace;">Number</span>, you can automatically receive instances of any subtype as for example <span style="font-family: Courier New, Courier, monospace;">Integer</span>. Nevertheless, it is always type safe to <b>read</b> this <span style="font-family: Courier New, Courier, monospace;">Integer</span> object you received even when expecting the supertype <span style="font-family: Courier New, Courier, monospace;">Number</span>. And since it is impossible to <b>write</b> back to this reference, i.e. you cannot overwrite the <span style="font-family: Courier New, Courier, monospace;">Integer</span> object with for example an instance of <span style="font-family: Courier New, Courier, monospace;">Double</span>, the Java language does not require you to waive your writing intention by declaring a method signature like <span style="font-family: Courier New, Courier, monospace;">void someMethod(<? extends Number> number)</span>. Similarly, when you promised to return an <span style="font-family: Courier New, Courier, monospace;">Integer</span> from a method but the caller only requires a <span style="font-family: Courier New, Courier, monospace;">Number</span>-typed object as a result, you can still return (<b>write</b>) any subtype from your method. Similarly, because you cannot <b>read</b> in a value from a hypothetical return variable, you do not have to waive these hypothetical reading rights by a wildcard when declaring a return type in your method signature.</div>
</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-58574371164114920572013-06-07T11:20:00.000+02:002013-12-28T23:08:40.993+01:00Advanced Java generics: retreiving generic type arguments<div dir="ltr" style="text-align: left;" trbidi="on">
<h3 style="text-align: left;">
</h3>
After their introduction in the JDK5, <a href="http://docs.oracle.com/javase/tutorial/java/generics/">Java generics</a> quickly became an integral element of many Java programs. However, as easy Java generics seem at first glance, as quickly a programer can get lost with this feature.<br />
<br />
Most Java programers are aware of the Java compiler's <a href="http://docs.oracle.com/javase/tutorial/java/generics/erasure.html">type erasure</a>. Generally speaking, type erasure means that all generic type information about a Java class is lost during the compilation of its source code. This is a tribute to Java's backwards compatibility: all generic variations of a Java class share a single representation within a running Java application. If an instance of <span style="font-family: "Courier New",Courier,monospace;">ArrayList<String></span> would have to remember that its generic type was of type <span style="font-family: "Courier New",Courier,monospace;">String</span>, it would have to store this information somewhere within its functional description in order to indicate that for example <span style="font-family: Courier New, Courier, monospace;">List.get</span> actually returns a <span style="font-family: Courier New, Courier, monospace;">String</span> type. (By functional description I refer to properties which are shared among all instances of a class. This includes for example method or field definitions. In contrast to its functional description, an instance's state which is individual to each instance is stored in its object representation.) The functional description of the <span style="font-family: 'Courier New', Courier, monospace;">ArrayList<String></span> instance is thus represented by its class <span style="font-family: "Courier New",Courier,monospace;">ArrayList.class</span>. Since the <span style="font-family: "Courier New",Courier,monospace;">ArrayList.class</span> instance is however shared with other instances which could also be of type <span style="font-family: "Courier New",Courier,monospace;">ArrayList<Integer></span>, this would already require to have two different versions of <span style="font-family: "Courier New",Courier,monospace;">ArrayList.class</span>. Such modifications of the class representation would however be incomprehensible to older JREs and thus break the backwards compatibility of Java applications. As a consequence, the following comparison will always succeed:<br />
<br />
<pre class="brush: java">assert new ArrayList<String>().getClass() == new ArrayList<Integer>().getClass();
</pre>
<br />
Since such a comparison is conducted at run time where the generic type of a class was already erased, this comparison translates to <span style="font-family: "Courier New",Courier,monospace;">ArrayList.class == ArrayList.class</span> what is trivial. Or more specifically, the running application will determine that <span style="font-family: "Courier New",Courier,monospace;">ArrayList.class</span> is equal to itself and return <span style="font-family: "Courier New",Courier,monospace;">true</span>, despite of <span style="font-family: "Courier New",Courier,monospace;">String.class != Integer.class</span>. This is a major difference of Java to other programming languages like for example C++ and also the reason for a common complaint about Java. (Academically speaking, C++ does not actually know generic types. Instead, <a href="http://www.cplusplus.com/doc/tutorial/templates/">C++ offers templates</a> which are however similar to generics.)<br />
<br />
So far, this is nothing new to many developers. However, contrary to popular belief it is sometimes possible to retrieve generic type information even during run time. Before explaining, when this is possible, let us look at an example. For this we define the following two classes:<br />
<br />
<pre class="brush: java">class MyGenericClass<T> { }
class MyStringSubClass extends MyGenericClass<String> { }
</pre>
<br />
<span style="font-family: "Courier New",Courier,monospace;">MyGenericClass</span> has a single argument for a generic type <span style="font-family: "Courier New",Courier,monospace;">T</span>. <span style="font-family: "Courier New",Courier,monospace;">MyStringSubClass</span> extends this generic class and is assigning <span style="font-family: "Courier New",Courier,monospace;">T = String</span> as its type parameter. As a result, the Java compiler is able to store the information about the generic argument's type <span style="font-family: "Courier New",Courier,monospace;">String</span> of superclass <span style="font-family: "Courier New",Courier,monospace;">MyGenericClass</span> in the <a href="http://en.wikipedia.org/wiki/Java_bytecode">byte code</a> of<b> its <a href="http://en.wikipedia.org/wiki/Inheritance_%28object-oriented_programming%29">subclass</a></b> <span style="font-family: "Courier New",Courier,monospace;">MyStringSubClass</span>. This modification can be achieved without breaking backwards compatibility, because this information is simply stored in a region of the compiled class's byte code which is ignored by old JRE versions. At the same time, all instances of <span style="font-family: "Courier New",Courier,monospace;">MyStringSubClass</span> can still share a single class representation, since <span style="font-family: "Courier New",Courier,monospace;">T = String</span> is set for all instances of <span style="font-family: "Courier New",Courier,monospace;">MyStringSubClass</span>.<br />
<br />
But how can we get hold of this information stored in the byte code? The Java API provides the <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getGenericSuperclass()">Class.getGenericSuperclass</a> method which can be used to receive an instance of type <a href="http://docs.oracle.com/javase/7/docs/api/"><span style="font-family: "Courier New",Courier,monospace;">Type</span></a>. If the direct superclass is in fact generic, the returned instance is additionally of type <a href="http://docs.oracle.com/javase/7/docs/api/"><span style="font-family: "Courier New",Courier,monospace;">ParameterizedType</span></a> and can be cast to it. (Type is nothing but a <a href="http://en.wikipedia.org/wiki/Marker_interface_pattern">marker interface</a>. The actual instance will be an instance of the internal <span style="font-family: "Courier New",Courier,monospace;">ParameterizedTypeImpl</span> class, you should however always cast to the interface.) Thanks to a cast to the <span style="font-family: "Courier New",Courier,monospace;">ParameterizedType</span> interface, you can now call the method <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments()"><span style="font-family: "Courier New",Courier,monospace;">ParameterizedType.getActualTypeArguments</span></a> to retrieve an array which is again of type <span style="font-family: "Courier New",Courier,monospace;">Type</span>. Any generic type argument of the generic superclass will be contained in this array at the same index as in the type definition. Any <span style="font-family: Courier New, Courier, monospace;">Type</span> instance which represents a non-generic class is simply an implementation of a Java <span style="font-family: "Courier New",Courier,monospace;">Class</span> class. (Assuming, you are not handeling an array where the returned type is of <span style="font-family: Courier New, Courier, monospace;">GenericArrayType</span>. I will skip this scenario in this article for the sake of simplicity.)<br />
<br />
Now we can make use of this knowledge to write a utility function:<br />
<br />
<pre class="brush: java">public static Class<?> findSuperClassParameterType(Object instance, Class<?> classOfInterest, int parameterIndex) {
Class<?> subClass = instance.getClass();
while (classOfInterest != subClass.getSuperclass()) {
// instance.getClass() is no subclass of classOfInterest or instance is a direct instance of classOfInterest
subClass = subClass.getSuperclass();
if (subClass == null) throw new IllegalArgumentException();
}
ParameterizedType parameterizedType = (ParameterizedType) subClass.getGenericSuperclass();
return (Class<?>) parameterizedType.getActualTypeArguments()[parameterIndex];
}
</pre>
<br />
This function will browse through the class hierarchy of instance until it recognizes classOfInterest to be the next direct sub class in the hierarchy. When this is the case, this super class will be retrieved by using the <span style="font-family: Courier New, Courier, monospace;">Class.getGenericSuperclass</span> method. As described above, this method returns a class's super class in a wrapped representation (<span style="font-family: Courier New, Courier, monospace;">ParamererizedType</span>) which includes the generic types which are found in the <b>subclass</b>. This allows us to successfully run the following application:
<br />
<br />
<pre class="brush: java">Class<?> genericType = findSuperClassParameterType(new MyStringSubClass(), MyGenericClass.class, 0);
assert genericType == String.class;</pre>
<br />
Be however aware that<br />
<br />
<pre class="brush: java">findSuperClassParamerterType(new MyGenericClass<String>(), MyGenericClass.class, 0)
</pre>
<br />
will throw an exception in this implementation. As stated before: the generic information can only be retrieved with the help of a subclass. <span style="font-family: "Courier New",Courier,monospace;">MyGenericClass<String></span> is however not a subclass of <span style="font-family: "Courier New",Courier,monospace;">MyGenericClass.class</span> but a direct instance with a generic argument. But without an explicit subclass, there is no <span style="font-family: "Courier New",Courier,monospace;"><something>.class</span> representation to store the <span style="font-family: "Courier New",Courier,monospace;">String</span> argument. Therefore this time, the generic type was irretrievably erased during compilation. For this reason, it is a good practice to define <span style="font-family: Courier New, Courier, monospace;">MyGenericClass</span> to be abstract, if you are planing on performing such queries on a class.<br />
<br />
However, we have not yet solved the problem, since there are several pitfalls we ignored so far. To show why, think of the following class hierarchy:<br />
<br />
<pre class="brush: java">class MyGenericClass<T> { }
class MyGenericSubClass<U> extends MyGenericClass<U>
class MyStringSubSubClass extends MyGenericSubClass<String> { }
</pre>
<br />
If we now call<br />
<br />
<pre class="brush: java">findSuperClassParameterType(new MyStringSubClass(), MyGenericClass.class, 0);
</pre>
an exception will be thrown. But why is this so? So far, we assumed that the type parameter <span style="font-family: "Courier New",Courier,monospace;">T</span> for <span style="font-family: "Courier New",Courier,monospace;">MyGenericClass</span> was stored in a direct subclass. In our first example, this was <span style="font-family: "Courier New",Courier,monospace;">MyStringSubClass</span> which mapped the generic parameter <span style="font-family: "Courier New",Courier,monospace;">T = String</span>. In contrast, now <span style="font-family: "Courier New",Courier,monospace;">MyStringSubSubClass</span> stores a reference <span style="font-family: "Courier New",Courier,monospace;">U = String</span> while <span style="font-family: "Courier New",Courier,monospace;">MyGenericSubClass</span> only knows that <span style="font-family: "Courier New",Courier,monospace;">U = T</span>. U is however not an actual class but a type variable of Java type <span style="font-family: "Courier New",Courier,monospace;">TypeVariable</span>. If we want to resolve this hierarchy, we have to resolve all of these dependencies. This can be achieved by adjusting our example code:<br />
<br />
<pre class="brush: java">public static Class<?> findSubClassParameterType(Object instance, Class<?> classOfInterest, int parameterIndex) {
Map<Type, Type> typeMap = new HashMap<Type, Type>();
Class<?> instanceClass = instance.getClass();
while (classOfInterest != instanceClass.getSuperclass()) {
extractTypeArguments(typeMap, instanceClass);
instanceClass = instanceClass.getSuperclass();
if (instanceClass == null) throw new IllegalArgumentException();
}
ParameterizedType parameterizedType = (ParameterizedType) instanceClass.getGenericSuperclass();
Type actualType = parameterizedType.getActualTypeArguments()[parameterIndex];
if (typeMap.containsKey(actualType)) {
actualType = typeMap.get(actualType);
}
if (actualType instanceof Class) {
return (Class<?>) actualType;
} else {
throw new IllegalArgumentException();
}
private static void extractTypeArguments(Map<Type, Type> typeMap, Class<?> clazz) {
Type genericSuperclass = clazz.getGenericSuperclass();
if (!(genericSuperclass instanceof ParameterizedType)) {
return;
}
ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
Type[] typeParameter = ((Class<?>) parameterizedType.getRawType()).getTypeParameters();
Type[] actualTypeArgument = parameterizedType.getActualTypeArguments();
for (int i = 0; i < typeParameter.length; i++) {
if(typeMap.containsKey(actualTypeArgument[i])) {
actualTypeArgument[i] = typeMap.get(actualTypeArgument[i]);
}
typeMap.put(typeParameter[i], actualTypeArgument[i]);
}
}</pre>
<br />
The above code will resolve any chained generic type definitions by tracking them in a map. Please note that it is not enough to examine all type definitions by a specific index since <span style="font-family: "Courier New",Courier,monospace;">MyClass<A,B> extends MyOtherClass<B,A></span> defines a perfectly legal subtype.<br />
<br />
However, we are still not done. Again, we will look at an example first:<br />
<br />
<pre class="brush: java">class MyGenericOuterClass<U> {
public class MyGenericInnerClass<U> { }
}
class MyStringOuterSubClass extends MyGenericOuterClass<String> { }
MyStringOuterSubClass.MyGenericInnerClass inner = new MyStringOuterSubClass().new MyGenericInnerClass();</pre>
<br />
This time a reflection on the <a href="http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html">inner class</a> by calling<br />
<br />
<pre class="brush: java">findSuperClassParameterType(inner, MyGenericInnerClass.class, 0);
</pre>
<br />
will fail. At first glance, this might seem consequent. We are looking for the generic argument type in <span style="font-family: "Courier New",Courier,monospace;">MyGenericInnerClass</span> on an instance of the same class. As we described above, this is usually not possible since no generic type information can be stored in <span style="font-family: "Courier New",Courier,monospace;">MyGenericInnerClass.class</span>. Here however, we examine an instance of a (non-static) inner class of a generic class's subtype. <span style="font-family: "Courier New",Courier,monospace;">MyStringOuterSubClass</span> knows that <span style="font-family: "Courier New",Courier,monospace;">U = String</span>. We have to take this into account when reflecting on the parameter type of <span style="font-family: "Courier New",Courier,monospace;">MyGenericInnterClass</span>.<br />
<br />
Now here is where things get really tricky. In order to find generic declarations in outer classes, we have to first get hold of this outer class. This can be achieved by reflection and the fact that the Java compiler adds a <a href="http://stackoverflow.com/questions/3298130/how-to-create-synthetic-fields-in-java">synthetic</a> (this means without source code representation) field <span style="font-family: "Courier New",Courier,monospace;">this$0</span> to any inner class. This field can be retrieved by calling <span style="font-family: "Courier New",Courier,monospace;">Class.getDeclaredField("this$0")</span>. By obtaining the instance of the outer class in which the current inner class is contained, we automatically gain access to its Java class. Now we could just proceed as above and scan the enclosing class for generic definitions and add them to out map. However, type variable representation of U in <span style="font-family: "Courier New",Courier,monospace;">MyGenericOuterClass</span> will not equal the representation of U in <span style="font-family: "Courier New",Courier,monospace;">MyGenericInnerClass</span>. For all we know, <span style="font-family: "Courier New",Courier,monospace;">MyGenericInnerClass</span> could be static and define its own generic variable name space. Therefore, any <span style="font-family: "Courier New",Courier,monospace;">TypeVariable</span> type which represent generic variables in the Java API, is equipped with a <span style="font-family: "Courier New",Courier,monospace;">genericDeclaration</span> property. If two generic variables were defined in different classes, the <span style="font-family: "Courier New",Courier,monospace;">TypeVariable</span> representations are not equal by their definition, even if they share a name in the same name space by one class being a non-static inner class of the other.<br />
<br />
Therefore we have to do the following:<br />
<ol style="text-align: left;">
<li>First, try to find a generic type in the inner classes super class hierarchy. Just as you would do with a non-nested class.</li>
<li>If you cannot resolve the type: For the (non-static) inner class and all of its outer classes, resolve the type variables as complete as possible. This can be achieved by the same <span style="font-family: "Courier New",Courier,monospace;">extractTypeArguments</span> algorithm and is basically <i>1.</i> for each nested class. We can get hold of the outer classes by checking if the <span style="font-family: "Courier New",Courier,monospace;">this$0</span> field is defined for an inner class.</li>
<li>Check if one of the outer classes contains a definition for a generic variable with an identical variable name. If this is the case, you found the actual type of a generic variable you were looking for.</li>
</ol>
In code, this looks like this:<br />
<br />
<pre class="brush: java">public static Class<?> findSubClassParameterType(Object instance, Class<?> classOfInterest, int parameterIndex) {
Map<Type, Type> typeMap = new HashMap<Type, Type>();
Class<?> instanceClass = instance.getClass();
while (classOfInterest != instanceClass.getSuperclass()) {
extractTypeArguments(typeMap, instanceClass);
instanceClass = instanceClass.getSuperclass();
if (instanceClass == null) throw new IllegalArgumentException();
}
ParameterizedType parameterizedType = (ParameterizedType) instanceClass.getGenericSuperclass();
Type actualType = parameterizedType.getActualTypeArguments()[parameterIndex];
if (typeMap.containsKey(actualType)) {
actualType = typeMap.get(actualType);
}
if (actualType instanceof Class) {
return (Class<?>) actualType;
} else if (actualType instanceof TypeVariable) {
return browseNestedTypes(instance, (TypeVariable<?>) actualType);
} else {
throw new IllegalArgumentException();
}
}
private static Class<?> browseNestedTypes(Object instance, TypeVariable<?> actualType) {
Class<?> instanceClass = instance.getClass();
List<Class<?>> nestedOuterTypes = new LinkedList<Class<?>>();
for (
Class<?> enclosingClass = instanceClass.getEnclosingClass();
enclosingClass != null;
enclosingClass = enclosingClass.getEnclosingClass()) {
try {
Field this$0 = instanceClass.getDeclaredField("this$0");
Object outerInstance = this$0.get(instance);
Class<?> outerClass = outerInstance.getClass();
nestedOuterTypes.add(outerClass);
Map<Type, Type> outerTypeMap = new HashMap<Type, Type>();
extractTypeArguments(outerTypeMap, outerClass);
for (Map.Entry<Type, Type> entry : outerTypeMap.entrySet()) {
if (!(entry.getKey() instanceof TypeVariable)) {
continue;
}
TypeVariable<?> foundType = (TypeVariable<?>) entry.getKey();
if (foundType.getName().equals(actualType.getName())
&& isInnerClass(foundType.getGenericDeclaration(), actualType.getGenericDeclaration())) {
if (entry.getValue() instanceof Class) {
return (Class<?>) entry.getValue();
}
actualType = (TypeVariable<?>) entry.getValue();
}
}
} catch (NoSuchFieldException e) { /* this should never happen */ } catch (IllegalAccessException e) { /* this might happen */}
}
throw new IllegalArgumentException();
}
private static boolean isInnerClass(GenericDeclaration outerDeclaration, GenericDeclaration innerDeclaration) {
if (!(outerDeclaration instanceof Class) || !(innerDeclaration instanceof Class)) {
throw new IllegalArgumentException();
}
Class<?> outerClass = (Class<?>) outerDeclaration;
Class<?> innerClass = (Class<?>) innerDeclaration;
while ((innerClass = innerClass.getEnclosingClass()) != null) {
if (innerClass == outerClass) {
return true;
}
}
return false;
}
</pre>
<br />
Wow, this is ugly! But the above code makes <span style="font-family: "Courier New",Courier,monospace;">findSubClassParameterType</span> work even with nested classes. We could go into even greater detail, since we can also find types of generic interfaces, generic methods, fields or arrays. The idea of all such extractions however remains the same. If a subclass knows the generic arguments of its super class, they can be retreived via reflections. Otherwise, due to type erasure, the generic arguments will be irretrievably lost at run time.<br />
<br />
But in the end, what is this good for? To many developers, this conveys the impression of performed black magic such that they rather avoid writing such code. Admittedly, there are in general easier ways to perform such a query. We could have defined the <span style="font-family: Courier New, Courier, monospace;">MyGenericSubclass</span> like this instead:<br />
<br />
<pre class="brush: java">class MyGenericClass<T> {
private final Class<T> clazz;
public MyGenericClass(Class<T> clazz) {
this.clazz = clazz;
}
public Class<T> getGenericClass() {
return clazz;
}
}
</pre>
<br />
Of course, this works as well and is even less code. However, when you are writing APIs that are to be used by other developers, you often want them to be as slim and easy as possible. (This can go from writing a big framework to writing software in a team of two.) By the above implementation, you force the users of your class to provide redundant information that you could have retrieved differently. Also, this approach does not work likely well for interfaces where you implicitly require the implementing classes to add corresponding constructors. This matter will become even more relevant when looking towards Java 8 and its <a href="http://www.javac.info/closures-v05.html">functional interfaces</a> (also known as closures or lambda expressions). If you require your generic interfaces to supply a <span style="font-family: Courier New, Courier, monospace;">getGenericClass</span> method besides their functional method, you cannot longer use them within a lambda expression. <br />
<br />
PS: I hacked this code while I was writing this blog article and never really tested it but by <a href="http://lastsector.wordpress.com/tag/debugging/">dupa debugging</a>. If you need such functionality, there is an excellent library called <a href="http://code.google.com/p/gentyref">gentyref</a> which provides the above analysis and much more.</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-55447122219854877982013-05-28T13:56:00.000+02:002014-01-22T15:35:16.380+01:00Memory leaks and memory management in Java applications<div dir="ltr" style="text-align: left;" trbidi="on">
One of the more prominent features of the Java platform is its automatic memory management. Many people translate this feature erroneously into <i>there are no <a href="http://en.wikipedia.org/wiki/Memory_leak">memory leaks</a> in Java</i>. However, this is not the case and I am under the impression that modern Java frameworks and Java-based platforms, especially the Android platform, increasingly contradict this erroneous assumption. In order to get an impression on how memory leaks can occur on the Java platform, look at the following implementation of a <a href="http://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29">stack</a>:<br />
<br />
<pre class="brush: java">class SimpleStack {
private final Object[] objectPool = new Object[10];
private int pointer = -1;
public Object pop() {
if(pointer < 0) {
throw new IllegalStateException("no elements on stack");
}
return objectPool[pointer--];
}
public Object peek() {
if(pointer < 0) {
throw new IllegalStateException("no elements on stack");
}
return objectPool[pointer];
}
public void push(Object object) {
if(pointer > 8) {
throw new IllegalStateException("stack overflow");
}
objectPool[++pointer] = object;
}
}
</pre>
<br />
This stack implementation stores its content in form of an array and additionally manages an integer which points to the currently active stack cell. This implementation introduces a memory leak every time an element is popped off the top of the stack. More precisely, the stack keeps a reference to the top element in the array, even though it will not be used again. (Unless it is pushed onto the stack again what will cause the reference to be overridden with the exact same reference.) As a consequence, Java will not be able to garbage collect this object even after all other references to the object are released. Since the stack implementation does not allow direct access to the underlying object pool, this unreachable reference will prevent garbage collection of the referenced object, until a new element is pushed onto the same index of the stack.<br />
<br />
Fortunately, this memory leak is easy to fix:<br />
<br />
<pre class="brush: java">public Object pop() {
if(pointer < 0) {
throw new IllegalStateException("no elements on stack");
}
try {
return objectPool[pointer];
} finally {
objectPool[pointer--] = null;
}
}
</pre>
<br />
Of course, the implementation of a memory structure is not a very common task in day to day Java development. Therefore, let us look at a more common example of a Java memory leak. Such a leak is often introduced by the commonly used <a href="http://en.wikipedia.org/wiki/Observer_pattern">observer pattern</a>:<br />
<br />
<pre class="brush: java">class Observed {
public interface Observer {
void update();
}
private Collection<Observer> observers = new HashSet<Observer>();
void addListener(Observer observer) {
observers.add(observer);
}
void removeListener(Observer observer) {
observers.remove(observer);
}
}</pre>
<br />
This time, there exists a method that allows to directly remove a reference from the underlying object pool. As long as any registered observer gets unregistered after its use from the outside, there are no memory leaks to fear in this implementation. However, imagine a scenario where you or the user of your framework forget to deregister the observer after its use. Again, the observer will never be garbage collected because the observed keeps a reference to it. Even worse, without owning a reference to this now useless observer, it is impossible to remove the observer form the observed's object pool from the outside.<br />
<br />
But also this potential memory leak has an easy fix which involves using <a href="https://weblogs.java.net/blog/2006/05/04/understanding-weak-references">weak references</a>, a Java platform feature that I personally wished programmers would be more aware of. In a nutshell, weak references behave like normal references but do not prevent garbage collection. Thus, a weak reference can suddenly be found being <span style="font-family: "Courier New",Courier,monospace;">null</span> if there were no strong references remaining and the JVM performed a garbage collection. Using weak references, we can change the above code like this:<br />
<br />
<pre class="brush: java">private Collection<Observer> observers = Collections.newSetFromMap(
new WeakHashMap<Observer, Boolean>());</pre>
<br />
The <span style="font-family: "Courier New",Courier,monospace;"><a href="http://docs.oracle.com/javase/6/docs/api/java/util/WeakHashMap.html">WeakHashMap</a></span> is a ready-made implementation of a map that wraps its keys with weak references. With this change, the observed will not prevent garbage collection of its observers. However, you should always indicate this behavior in your Java docs! It can be quite confusing, if users of your code want to register a permanent observer to your observant like a logging utility to which they do not plan to keep a reference to. For example, Android's <span style="font-family: "Courier New",Courier,monospace;"><a href="http://developer.android.com/reference/android/content/SharedPreferences.html#registerOnSharedPreferenceChangeListener%28android.content.SharedPreferences.OnSharedPreferenceChangeListener%29">OnSharedPreferencesChangeListener</a></span> uses weak references to is listeners without documenting this feature. This can keep you up at night!<br />
<br />
In the beginning of this blog entry, I suggested that many of today's frameworks require careful memory management by their users and I want to give at least two examples on this topic to explain this concern.<br />
<br />
<h3 style="text-align: left;">
Android platform:</h3>
Programming for Android introduces a life cycle programming model to your core application classes. All in all, this means that you are not in control of creating and managing your own object instances of these classes but that they will instead by created by the Android OS for you whenever they are needed. (As for example if your application is supposed to show a certain screen.) In the same manner, Android will decide when it does not longer need a certain instance (as when your application's screen was closed by the user) and inform you about this removal by calling a specific life cycle method on the instance. If you however let a reference to this object slip away into some global context, the <a href="http://code.google.com/p/dalvik/">Android JVM</a> will not be able to garbage collect this instance contrary to its intent. Since Android phones are usually rather restrained in memory and because Android's object creation and destruction routines can grow pretty wild even for simple apps, you have to take extra care to clean up your references.<br />
<br />
Unfortunately, a reference to a core application class slips away quite easily. Can you spot the slipped reference in the following example?<br />
<br />
<pre class="brush: java">class ExampleActivity extends Activity {
@Override
public void onCreate(Bundle bundle) {
startService(new Intent(this, ExampleService.class).putExtra("mykey",
new Serializable() {
public String getInfo() {
return "myinfo";
}
}));
}
}
</pre>
<br />
If you thought, it the <span style="font-family: "Courier New",Courier,monospace;">this</span> reference in the intent's constructor, you are wrong. The intent only serves as a starting command to the service and will be removed after the service has started. Instead, the anonymous inner class will hold a reference to its enclosing class which is the <span style="font-family: "Courier New",Courier,monospace;">ExampleActivity</span> class. If the receiving <span style="font-family: "Courier New",Courier,monospace;">ExampleService</span> keeps a reference to the instance of this anonymous class, it will as a consequence also keep a reference to the <span style="font-family: "Courier New",Courier,monospace;">ExampleActivity</span> instance. Because of this, I can only suggest to Android developers to avoid the use of anonymous classes.<br />
<br />
<h3 style="text-align: left;">
Web application frameworks (<a href="http://wicket.apache.org/">Wicket</a>, in particular):</h3>
Web application frameworks usually store semi-permanent user data in sessions. Whatever you write into a session will usually stay in memory for an undetermined period of time. If you litter up your sessions while having a significant number of visitors, your servlet container's JVM will pack up sooner or later. An extreme example of needing to take extra care of your references is the Wicket framework: Wicket serializes any page a user visited in a versioned state. Oversimplified, this means that if one of your website's visitors clicks your welcome page ten times, Wicket will in its default configuration store ten serialized objects on your hard drive. This requires extra care because any references hold by a Wicket page object, will cause the references objects to be serialized together with the page. Look for example at this bad practice Wicket example:<br />
<br />
<pre class="brush: java">class ExampleWelcomePage extends WebPage {
private final List<People> peopleList;
public ExampleWelcomePage (PageParameters pageParameters) {
peopleList = new Service().getWorldPhonebook();
}
}
</pre>
By clicking your welcome page ten times, your user just stored ten copies of the world's phone book on your servers hard drive. Therefore, always use <span style="font-family: "Courier New",Courier,monospace;"><a href="http://wicket.apache.org/apidocs/1.5/org/apache/wicket/model/LoadableDetachableModel.html">LoadableDetachableModel</a></span>s in your Wicket applications which will take care of the reference management for you.<br />
<br />
Tracing memory leaks in Java applications can be tiresome and therefore, I want to name <a href="http://www.ej-technologies.com/products/jprofiler/overview.html">JProfiler</a> as a useful (but unfortunately non-free) debugging tool. It allows you to browse through the insides of your Java running application in form of for example heap dumps. If memory leaks are a problem for your applications, I recommend to give JProfiler a shot. There is an evaluation license available.<br />
<br />
<b>For further reading</b>: If you want to see another interesting occurrence of memory leaks when you are customizing <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html">class loaders</a>, refer to the <a href="http://zeroturnaround.com/rebellabs/rjc201/">Zeroturnaround blog</a>.</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com0tag:blogger.com,1999:blog-3237092529299307504.post-69876457060323734612013-05-24T11:01:00.004+02:002013-07-31T09:33:14.248+02:00Converting Microsoft DOC or DOCX files into PDF using Java without contortions<div dir="ltr" style="text-align: left;" trbidi="on">
I will give you a heads up: There is no simple, well-performing solution using pure Java. To get an intuition for why this is the case, just try to open a DOC-formated file with a non-Microsoft text editor, usually <a href="http://www.openoffice.org/">Apache Open Office</a> or <a href="http://www.libreoffice.org/">Libre Office</a>. If your file contains more than a few standard formated lines, you are likely to experience layout displacements. The same is true for the DOC-format's XML-based successor, the DOCX format.<br />
<br />
Unfortunately, converting a file to PDF conforms to opening the DOC-file and printing it out into another file. Consequently, the resulting PDF file will contain the same layout displacements as the software you originally used to open the DOC-file. Of course, this does not only apply to Open Office: You would face the same difficulties (or probably even worse) if you read a DOC(X) file using any Java library offering such functionality.<br />
<br />
Therefore, a fully functioning DOC(X) to PDF conversion will always require you to use Microsoft Word. Unfortunately, Microsoft Word <a href="http://support.microsoft.com/?scid=kb;en-us;210565">does not offer command line switches for direct printing or PDF-conversion</a>. <br />
<br />
Recently, I was faced with this problem what lead me to implement the small workaround which I will introduce in the reminder of this blog entry. To begin with, you need a working installation of <a href="http://office.microsoft.com/en-us/word/">Microsoft Word 2007 or higher</a> on your machine. If you are using Microsoft Word 2007, make sure that the <a href="http://www.microsoft.com/en-US/download/details.aspx?id=9943">PDF plugin</a> is installed. Later versions of MS Word are already bundled with this plugin. Secondly, you need to make sure that you have the <a href="http://technet.microsoft.com/en-us/scriptcenter/default.aspx">Windows Scripting Host</a> installed on your computer. This is basically the case for any Windows operating system. The Windows Scripting Host allows us to run Visual Basic scripts as this one:<br />
<br />
<pre class="brush:vb">' See http://msdn2.microsoft.com/en-us/library/bb238158.aspx
Const wdFormatPDF = 17 ' PDF format.
Const wdFormatXPS = 18 ' XPS format.
Const WdDoNotSaveChanges = 0
Dim arguments
Set arguments = WScript.Arguments
' Make sure that there are one or two arguments
Function CheckUserArguments()
If arguments.Unnamed.Count < 1 Or arguments.Unnamed.Count > 2 Then
WScript.Echo "Use:"
WScript.Echo "<script> input.doc"
WScript.Echo "<script> input.doc output.pdf"
WScript.Quit 1
End If
End Function
' Transforms a doc to a pdf
Function DocToPdf( docInputFile, pdfOutputFile )
Dim fileSystemObject
Dim wordApplication
Dim wordDocument
Dim wordDocuments
Dim baseFolder
Set fileSystemObject = CreateObject("Scripting.FileSystemObject")
Set wordApplication = CreateObject("Word.Application")
Set wordDocuments = wordApplication.Documents
docInputFile = fileSystemObject.GetAbsolutePathName(docInputFile)
baseFolder = fileSystemObject.GetParentFolderName(docInputFile)
If Len(pdfOutputFile) = 0 Then
pdfOutputFile = fileSystemObject.GetBaseName(docInputFile) + ".pdf"
End If
If Len(fileSystemObject.GetParentFolderName(pdfOutputFile)) = 0 Then
pdfOutputFile = baseFolder + "\" + pdfOutputFile
End If
' Disable any potential macros of the word document.
wordApplication.WordBasic.DisableAutoMacros
Set wordDocument = wordDocuments.Open(docInputFile)
' See http://msdn2.microsoft.com/en-us/library/bb221597.aspx
wordDocument.SaveAs pdfOutputFile, wdFormatPDF
wordDocument.Close WdDoNotSaveChanges
wordApplication.Quit WdDoNotSaveChanges
Set wordApplication = Nothing
Set fileSystemObject = Nothing
End Function
' Execute script
Call CheckUserArguments()
If arguments.Unnamed.Count = 2 Then
Call DocToPdf( arguments.Unnamed.Item(0), arguments.Unnamed.Item(1) )
Else
Call DocToPdf( arguments.Unnamed.Item(0), "" )
End If
Set arguments = Nothing
</pre>
<br />
Copy this script and save it on your machine. Name the file something like <i>doc2pdf.vbs</i>. I will at this point not go into the details of Visual Basic scripting since this blog is addressed to Java developers. In a nutshell, this scripts checks for the existence of two command line arguments. The first of these arguments represents the DOC(X) file to be converted. The second parameter is optional and represents the output file. If no such parameter can be found, the script will simply append <i>.pdf</i> to the DOC(X) file and save this output in the same directory. The conversion is achieved by calling Microsoft Word silently. There exist <a href="http://www.suodenjoki.dk/us/productions/articles/word2pdf.htm">more advanced implementations</a> of this functionality on the net.<br />
<br />
You will now be able to call this script from a MS Windows console (cmd) by typing:<br />
<br />
<pre class="brush:bash">C:\example\doc2pdf.vbs C:\example\myfile.docx
</pre>
<br />
After executing this script, you will find <span style="font-family: "Courier New",Courier,monospace;">C:\example\myfile.docx.pdf</span> on your machine. Make sure that this conversion works in order to confirm that your system is configured correctly.<br />
<br />
But there is more bad news. You will not be able to call this script from Java directly. Attempting to run the script via <span style="font-family: "Courier New",Courier,monospace;">Runtime.exec</span> will result in an <span style="font-family: "Courier New",Courier,monospace;">java.io.IOException</span>. The reason for this exception can be found in its description:<br />
<blockquote class="tr_bq">
<i>Cannot run program "C:\example\doc2pdf.vbs": CreateProcess error=193, %1 is not a valid Win32 application</i></blockquote>
Apparently, Java cannot access the Microsoft Script Host and does therefore not recognize our script as a valid application. This requires us to apply another workaround: We will write a small bash script that executes the Visual Basic script for us. This script will look something like this:<br />
<br />
<pre class="brush:bash">@Echo off
pushd %~dp0
cscript C:\example\doc2pdf.vbs %1 %2
</pre>
<br />
Save this file as <i>doc2pdf.bat</i>. Again, I will spare you the details of this short bash script but it generally will only execute the Visual Basic script and will additionally pass its first two command line arguments to it. (If there are any.) Try this script by typing <br />
<br />
<pre class="brush:bash">C:\example\doc2pdf C:\example\myfile.docx
</pre>
<br />
into your command line and to see if your script is set up correctly. The advantage of this bash script over the Visual Basic implementation is that it can be called by Java:<br />
<br />
<pre class="brush:java">try {
String docToPdf = "C:\\example\\doc2pdf.bat";
File docPath = new File(getClass().getResource("/mydocument.docx").getFile());
File pdfPath = new File(docPath.getAbsolutePath() + ".pdf");
String command = String.format("%s %s %s", docToPdf, docPath, pdfPath);
Process process = Runtime.getRuntime().exec(command);
// The next line is optional and will force the current Java
//thread to block until the script has finished its execution.
process.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
</pre>
<br />
By calling <span style="font-family: "Courier New",Courier,monospace;">Process.waitFor</span> you can block your execution thread until the bash script has finished its execution and the PDF file was produced. Additionally, you will receive a status code as a return value which informs you whether the bash script has terminated correctly. The PDF file can be accessed by the variable <span style="font-family: "Courier New",Courier,monospace;">pdfPath</span> in the above script.<br />
<br />
It remains disappointing that this solution will most likely only run on Windows systems. However, you might get it going on Linux via Wine and <a href="http://wiki.winehq.org/winetricks">winetricks</a>. (Winetricks allows to install Visual Basic for the Windows Scripting Host by the parameter option <i>wsh56vb</i>.) Any feedback on such further experiments are appreciated.</div>
Rafaelhttp://www.blogger.com/profile/06973690867431113468noreply@blogger.com5