2013. szeptember 25., szerda

JavaOne Wednesday: Lean and Opinionated Java EE Applications

This post is about the funniest presentation I heard at JavaOne 2013. It was Adam Bien's "Lean and Opinionated Java EE Applications" which started after some nice reggae music in the room. :) The audience really enjoyed this presentation (i.e lot of laughing), I was surprised to see something like this at a technical session. The demonstration was backed by a Maven project with some minimal code samples shown in NetBeans.

You can find the session's site here and the slides here, but there were only a few introduction slides, as the substance was in the speech given. I think that the code and project layout samples are not that important as they were only used to prove some points of the presentation. Some unorthodox opinions about Java EE were shared by Adam Bien, but they are really worth considering.

Below you can find a summary of the ones I liked most, and some quotes with the funniest lines. Please note that most of it is really only quotes from him which I wanted to share as I couldn't find them all in one piece on his blog which I really recommend to anyone in Java EE. Enjoy.

About Modularization

"The most important pattern is: don't distribute." This means that in real-world projects a lot of times the application is overly modularized into different projects and deployments, and probably distributed to different JVMs, whereas it could be kept in one JVM or even one WAR deployment. Since 2008 (Java EE 6), no EARs are strictly needed as you can package a lot of things into plain WARs. So when are EARs neeed? Only when WAR is not enough for yoe, e.g. for more classloading flexibility and packaging JCA connectors.

"Everything is monolithic until it's too big." If it gets too big, then you can modularize and the different WARs can communicate by REST. ("SOAP is the technology of 1945" and "remote EJBs are dead".) "You shouldn't like distributed transactions" because XA is problematic; provide compensation instead. Seeing how often and how well distributed transactions are designed or implemented on real-world projects, even something like this sounds reasonable...

Business and web components do have a many-to-many relation.

If you can achieve a one-to-one relation between business requirements and code, that's just great.

How to Start?

Always use a minimal starting pom, without any super pom. Keep it as minimal and as clean as possible. "treat pom.xml as Java code." Always specify the build/finalName element in pom.xml as it is defining the filename of your deployment unit.

About EE 6 and EE 7: "frameworks are counter-productive", start with implementation of the business logic.

"Look at JDK first, then EE6, amazing what's there." True again. Amazing how a lot of technical features can be reinvented or reimplemented or taken from external dependencies. All unnecessary a lot of times. External dependencies are forbidden, each one has to be justified, and relied on using your own build, because they may brake or dissapear any time.

A smaller WAR means faster deployment which means productivity gain. How much of your time do you spend just sitting at your desktop and waiting for deployments? (See also JRebel...)

About Business

"Meetings are forbidden", minimize meetings, concentrate on business logic.

A vision is always needed (see RUP), because we need to know why we are building the system. We also need to know the key entities and core concepts of the business (so that the components can be identified).

On the other hand, business needs to understand components and focus on business, not on technology. "There are exceptions, beans, DTOs etc. - Who cares?" True again. You will end up running in circles with the business if you cannot talk about the business and business only.

About Layers and Integration

REST: nothing is more portable, you will end up using it anyway with responsive design, iOS, Android etc. It's a good practice to introduce additional resource classes on top of you business logic, even it seems overkill at first, even for small projects. This way no JAX-RS or JAX-WS or other stuff pollutes your business EJBs.

Java client accessing the backend: message border reader/writer. Fastest serialization protocol mentioned: Kryo.

The control layer is empty in 80%. If you get too complex classes then divide and conquer, and the control layer appears. But not before!

About Packages, Classes, and Interfaces

Example package naming: "com.x.business.sessions.boundary", where "business" is to separate business concepts, "sessions" can be the name of a component, and "boundary" is the name of the pattern.

Package names like commons, domain, framework, infrastructure, base, util are forbidden as they have no meaning. In particular, "util is dangerous". You always end up having different non-related concepts in a "util" package.

"If you cannot name the class [implementing an interface] properly, interfaces are forbidden." This refers to an interface MyService, and non-descriptive class names like MyServiceImpl and so on. They really don't make any sense.

In the enterprise, type-safe interfaces are good. But on the web scale, nothing is type-safe.

You shouldn't have base classes at the EJB/CDI level, only at the entity level.

About Data Access and Transfer Objects (DAO, DTO)

Domain store pattern: why use it? the EntityManager is the same and it's already there. Just inject the EntityManager into the boundary. Factor out duplicate queries, handle SQL as Java, as there is no difference. There is usually no need for a separate DAO, it doesn't mean anything, you can call this control something else instead, if it's needed at all.

DTOs are forbidden as we already have one layer (e.g. REST). It is only allowed if it's substantially different from entities, otherwise it leads to more complexity and no encapsulation. If you are using or implementing a mapper between your entities and DTOs, you are in trouble. Experience shows that the mapper is never tested (i.e. builders and so).

Other Quotes, Questions and Answers

Here are a few more notes I've taken, in no specific topic or order. Some of them were Adam's answers to questions of the audience.

  • "OO programming for some reason is forgotten in Java EE programming." :)
  • Java only development vs. Scala + Groovy + etc. development: the latter one can be a sign of losing focus, meaning that if you need to consider other languages, you must already have a problem with your Java code. Or with Adam's words: "In enterprise development the verbosity of Java is not the problem. The problem is cargo cult and overuse of ancient design patterns. After the bloat elimination Java becomes surprisingly productive."
  • Simple classes (with getters and setters) shouldn't be tested.
  • Avoid bad architects, promote them to management. :D
  • Experience shows that one to five developers working on one WAR is ideal. EJB and web components can go into one piece of WAR. If modularity is needed then introduce JAR projects.
  • Avoid proprietary features, not only because of difficulties of migration, but they might disappear any time.
  • Lombok is just too much magic for enterprise.
  • Performance problems are always in the database, not in the application server, where you can just start more WARs if needed.
  • CMT and remote EJBs: "the idea was scalability but it never worked".

Bottom Line

What I got out of this presentation is a very pragmatic view of Java EE projects and development. Even if some advices might seem to go against well-established patterns or conventions, at their core they are just practical and common sense. And honestly, I think most of the things described you can experience in real-world EE projects. ;)

I would summarize the presentation in the following very simple points:

  • Keep it clean and minimal.
  • Focus on business.
  • Use your common sense.

Cheers! :)

JavaOne Wednesday: Permanent Generation Removal Overview

The presentation "Permanent Generation Removal Overview" on Wednesday at JavaOne 2013 shed some light on the motivation of the JVM designers and some details of the implementation when they decided to remove the Permanent Generation (PermGen) from the HotSpot JVM for JDK8. Here is a short summary of it.

Motivations

There were/are some problems with PermGen that the JVM designers wanted to address.

It has a fixed size that is specified at startup (-XX:MaxPermSize), so it's difficult to tune. Internal JVM types were Java objects which could move with full GC and were hard to debug. Simplification of full GCs is also desired, just like avoiding some full GC pauses caused by collecting class data which from now on should be done concurrently.

Metaspace: The New Place of Class Metadata

It is moved to the so-called Metaspace, which is part of the native memory.

Metaspace is a per classloader storage which takes advantage of the JLS property that metadata lifetimes match class loader lifetimes. This makes possible the allocation of multiple mapped virtual memory spaces with per classloader chunk lists. Class loaders are pointing to so-called metachunks residing in a specific virtual space, which in turn are pointing to another chunks in another spaces and so on. Virtual spaces are returned when emptied, and the VM applies different strategies to minimize fragmentation.

So now the object memory layout consists of the Heap for objects and the Metaspace for class metadata.

A compressed class pointer space (which is logically part of metaspace) is introduced for 64 bit platforms. For 64 bit platforms, the default behavior is using compressed (32 bit) object pointers (-XX:UseCompressedOops) and compressed (32 bit) class pointers (-XX:UseCompressedClassPointers). Whereas the compressed class pointer space contains only class metadata, the metaspace can contain all other large class metadata including methods, bytecode etc.

Metaspace Tuning

The maximum metaspace size can be set using the -XX:MaxMetaspaceSize flag, and the default is unlimited, which means that only your system memory is the limit. The -XX:MetaspaceSize tuning flag defines the initial size of metaspace (refer to the current PermSize parameter), and it can be set to higher than the default 21 Mb if you experience too many GCs on startup. Further memory management can be influenced with the MinMetaspaceFreeRatio and MaxMetaspaceFreeRatio parameters, which allow for fine-tuning when the collections should happen, just like with current GC FreeRatio parameters.

The -XX:CompressedClassSpaceSize currently has a fixed size that can be specified on startup. JVM designers are planning to make this growable and probably set it ergonomically based on class loading predictions.

The -XX:+PrintGCDetails and -XX:+PrintHeapAtGC parameters now include printing Metaspace statistics.

Improved Garbage Collection performance

A lot of complex code were removed, metadata to metadata pointers are not scanned. This means no scan and compaction time consumed. There are only a few pointers back to the heap: pointer to Class instance in class metadata and to component Class instance in array class metadata. The root scanning time is also reduced as there is no scanning of VM dictionary of loaded classes and other internal hashtables.

Monitoring and Management

For management purposes some JMX features were added. A new MXBean is introduced: the MemoryManagerMXBean with name MetaspaceManager. This is responsible for managing the two new MemoryPoolMXBeans called Metaspace and CompressedClassSpace, both of type MemoryType.NON_HEAP. They are used to report the usage of the corresponding memory spaces. In turn, the PermGen memory pool is removed from the MemoryManager MBean.

Changes in existing tools, mostly for metaspace:

  • jmap -clstats (instead of jmap -permstat) to print class loader statistics,
  • jstat -gc shows Metaspace instead of PermGen,
  • jcmd [pid] GC.class_stats gives detailed histogram of class metadata sizes(needs -XX:+UnlockDiagnosticVMOptions),
  • Mission Control, which is coming from JRockit, is the new GUI for JVM monitoring and management since 7u40.

Summary

HotSpot metadata is now allocated in Metaspace, which has new tuning flags with reasonable default values. This change of the memory model enables other class metadata and GC optimizations in the future (Class Data Sharing, G1 class unloading, metadata size reduction).

And also, something to keep in mind is that you will need to learn a bit about new JVM features and parameters when upgrading to JDK8. ;)

You can find the site of the presentation here and the slides here.

2013. szeptember 24., kedd

JavaOne Tuesday: Some Photos

Imperial Ballroom A in Hilton Hotel:
Taylor Street Open Café next to Hilton Hotel:
Parc 55 Hotel:
Parc 55 Hotel hall:

JavaOne Tuesday: Nuts and Bolts of Java EE 7 Interceptors

Interceptors 1.2 Specification

This session was held by Marina Vatkina and Emmanuel Bernard about JSR-318, the Interceptors 1.2 specification. Its basically a cleanup of the previous version with a few new features. Summary:

  • Better, more organized, cleaner specification with better separation from other specs.
  • Interceptor binding is now part of this specification (moved from CDI spec).
  • No ejb-jar.xml elements in the specification (moved to EJB spec).
  • New @AroundConstruct annotation to apply around object constructors. Note that this completes before injection happens!
  • New @Priority annotation in EE 7 for ordering interceptors.

Influence of Bean Validation 1.1

Emmanuel Bernard went on explaining how the Bean Validation 1.1 features influenced the new Interceptors specification, namely:

  • Return value and parameter (including constructor parameter) validation upon method calls. This was a strongly missing feature from BV 1.0. In this context the validation should really happen on method calls, not triggered by some clever framework or custom enforcement point, so there needs to be a way to do this. This is where interceptors come into the picture.
  • Validations need to be executed as late as possible in the interceptor chain, so there needs to be some kind of ordering. @Priority is the solution for this.

Note: The BV 1.1 reference implementation uses a CDI portable extension to programmatically add interceptors based on the validation annotations, so it is fully standard and interoperable Java EE solution.

Interceptor Ordering

Important properties of the @Priority annotation:
  • It is defined on the interceptor class, not on the intercepted class.
  • Ordering is undefined for interceptors that have the same priority.
  • EJB style interceptor declaration (@Interceptors) ignores this annotation as there would be no reasonable way to resolve priority conflicts.
  • There are some useful predefined values in the Interceptor.Priority class like PLATFORM_BEFORE, LIBRARY_BEFORE, APPLICATION etc. Suggested best practice is to define your custom ranges between these values so that they have a meaning in this context.

So now the global ordering of all interceptors (including lifecycle callbacks and EJB style) is defined as follows:
  1. interceptors bound using @Interceptors as ordered in the annotation
  2. interceptors bound using @InterceptorBinding, ordered by their @Priority
  3. interceptors on the target class (superclass first) (e.g. @PostConstruct)
  4. interceptors on the target method or constructor

Others

Other slight modifications are that lifecycle callback method signatures can have return values and can throw checked exceptions now. This is just to avoid boilerplate try-catch code as InvocationContext.proceed() can throw checked exceptions. Note that this is only the signature, they are still not allowed to do so!

There is a new @Transactional annotation in EE 7 for JTA declarative transactions that can be applied to CDI managed beans, but not to EJBs (as it would conflict with JTA EJB interceptors). (Note that transactional interceptors have a mandated predefined @Priority. See the javadoc.)

That was it, it was nice to hear the new Interceptor and Bean Validation features. BTW did you know that in BV 1.1 you can inject resources into your constraint validators? That was missing before as well.

Cheers.

Update: Here is the link for the presentation's site and the slides.

2013. szeptember 23., hétfő

JavaOne Monday: Bytecode Instrumentation for Beginners

This one was an introductory presentation to bytecode instrumentation in Java today, which is widely used by different code analysis (e.g. FindBugs) and AOP tools (e.g. AspectJ) and dynamic languages (Nashorn for JavaScript, JRuby). The session was a nice summary about instrumentation and the options you can choose from if you need to instrument classes yourself.

Instrumentation was introduced in JDK 1.5. You can start the JVM specifying a Java agent, or you can attach agents later. An agent's agentmain and/or premain methods will be called by the JVM, and this is where it can register a ClassFileTransformer to modify classes at runtime. (You can find a nice tutorial about instrumentation here.)

The hard way do instrument a class is to implement your own ClassFileTransformer and work with byte arrays representing class files directly, e.g. using a DataInputStream. Of course this is not recommended if you don't want to go into details of the class file structure, but as mentioned during the presentation, this way you can learn a lot about it. ;)

Easier ways:

Update: Here is the link for the presentation's site.

JavaOne Monday: Enhanced Java SE 8 Metadata

Annotation "fans" were happy at JavaOne to hear about new metadata/annotation features in Java SE 8. This topic was covered in Monday's session "Enhanced Java SE 8 Metadata". Outline below.

Repeating Annotations

Repeating annotations are now allowed. This means that you don't have to (manually) apply the so-called container pattern when declaring more than one instance of an annotation type. E.g. in JPA when you want to use multiple @JoinColumn annotations, what you do now (Java SE 6-7) is wrap them into a single @JoinColumns annotation. In the future this will not be necessary and you can just list the @JoinColumn annotations as needed. You will still need to define the containing annotation, but the compiler transforms the contained ones into it automatically.

So there is one more thing for you to decide when designing annotation types: their cardinality. If you want it to be repeatable, you have to do the followings (samples taken from the official docs):

  • Apply the @Repeatable annotation to it and specify the containing annotation type, i.e.
    @Repeatable(Schedules.class)
    public @interface Schedule { ... }
    
  • Create the containing annotation type. This is required for backward compatibility.
    public @interface Schedules {
        Schedule[] value;
    }
    

And that's it.

Type Annotations

Another new feature of annotations is the use of type annotations. This means that you can annotate a generic type or other usages of a type. An example to demonstrate this:

List<@NonNull String> list;

Here you annotate the usage of the type String, and this metadata can be used later by tools for whatever purposes. An example of such a tool is the Checker Framework which can perform additional checks on your code based on these kinds of annotations. This happens during compilation as it is a javac plugin.

When designing annotations that can be used this way, you can use two new element types to define where they are allowed: ElementType.TYPE_PARAMETER and ElementType.TYPE_USE.

Parameter Reflection

A new class, named Parameter, appeared in the Reflection API, along with the getParameters() method in the common base class of Constructor and Method, named Executable. So now you can access method parameters with their names and modifiers. The names are not stored in the class file by default; the designers chose an opt-in approach so that parameter names are only stored in the class when asked for. The ideas of explicit, semi-explicit or implicit use of annotations to achieve this were dropped as they did not seem reasonable. (Examples respectively: @IncludeParameterNames on classes/methods, @IncludeParameterNames meta-annotation on other annotations, auto-enabling it for any runtime annotation occurence on a class/method.)

Instead at the moment it can be enabled by the compiler flag -g:vars, just like in previous JDKs. So the new real thing here is the API.

Language Model and Annotation Processing

Access is finally granted to the Language Model API (javax.lang.model) in Java SE 7, and there are some new javax.lang.model features in Java SE 8 (supporting the above features). Also annotation processing is moving to javac, so the apt tool is deprecated in JDK 7 and removed in JDK 8.

Bottom line:

The main constraint for the designers when implementing these features was compatibility of course. The goal is to provides better access and so far missing features to the metadata of the language.

Update: Here is the link for the presentation's site and the slides.

JavaOne Monday: Looking into the JVM Crystal Ball

The session "Looking into the JVM Crystal Ball" by Mikael Vidstedt (JVM Architect) was quite useful to get up to date regarding new Java 8 and HotSpot JVM features. Here are my notes about the session.

The PermGen will be removed. Its contents will be stored in the heap and native memory (see Metaspace) in the future. This means no more -XX:PermSize and -XX:MaxPermSize settings but an increased need to carefully plan and monitor the native memory space.

New features heavily relying on the relatively new (Java SE 7) invokedynamic JVM instruction: lambda expressions and Nashorn, the new JavaScript engine replacing Rhino. Both are actually implemented using invokedynamic. You can read about the invokedynamic instruction and static and dynamic typing in the official documentation "Java Virtual Machine Support for Non-Java Languages".

Huge heaps are now possible, which means "40 Gb and above", but terabytes of heap was also mentioned during the presentation.

Project Sumatra is dealing with new compiler features so that some computations can be offloaded to the GPU.

The already existing (7u4) G1 (Garbage-First) garbage collector's base idea is dividing the heap to partitions that it can work on paralelly as it is focusing on big heaps and low pause times. The goal in the future is to go for G1 only and to deprecate and remove the CMS garbage collector.

The Runtime JVM team works on Class Data Sharing which, as its name suggests, provides a means to share class data between applications and even JVMs. This will be implemented by using an image file that can be referenced from different JVMs. Dynamic string & symbol tables are also planned, e.g. the String pool (see String.intern()) size is increased and it will be resized dynamically.

Changes in Serviceability features and tools: Flight Recorder is meant to be used in production with a very little overhead (2-3% estimated). The Mission Control GUI application will be used to monitor the JVM (heap, threads, etc.) including data collected by Flight Recorder. Some JMX improvements are planned: using annotations for MBean configuration, providing REST APIs. One goal regarding serviceability is to deprecate and drop JConsole.

Above all, and from start, the main message of the presentation was that the goal is convergence of different JVMs including HotSpot, HotSpot CDC and JRockit, leading to one common JVM, for which all the necessary tools are provided.

As usual, at the end of the session everybody was encouraged to participate in the JDK 8 evolution. They appreciate any general feedback, GC feedback, and JDK 8 testing and error reporting which you can start by downloading and using the JDK 8 Early Access release.

Update: Here is the link for the presentation's site and the slides.