Example settings for the Oracle Java Garbage Collector

Tuning and optimizing a JVM garbage collector can be a very rewarding process in terms of meeting project specific throughput and response time requirements. The OpenJDK/Oracle JVM becomes better with every release but the base settings are often a bit conservative. My baseline set up for an application server’s garbage collector using the Sun/Oracle JVM is the following:

export JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MaxPermSize=256m -XX:MaxNewSize=448m -XX:NewSize=448m -XX:SurvivorRatio=6 -XX:+UseConcMarkSweepGC"

I found that this configuration works quite well out of the box for JBoss 7.1.x and GlassFish 3. It provides enough memory for typical Java EE applications, keeps garbage collections times low and garbage collections pauses are short and happen at a higher frequency. Load tests using JMeter show a very consistent heap usage and no big spikes and pauses like basic configurations.

I don’t want to go too deep into the topic because there’s lots and lots of literature on tuning the JVM and JVMs are changing too. Note however, that increasing the heap far beyond 2GB may impact desired qualities on Oracle JVMs even in 64 bit machines. Use the VisualGC tool to monitor garbage collector performance.

Think about running multiple JBoss or GlassFish instances on the same machine in their on environment. Using domain-driven design get a clean structure, message-based integration (instead of a shared database) and sticking to highly cohesive applications (Entity, Control, Boundary) usually presents lots of opportunities to decouple applications.

If you really need vast amounts of heap give other JVMs a try. AZUL Systems hast a very interesting JVM called Zing and claims to have 40x better response time than a tunes Oracle JVM. According to the company their JVM usually runs with 100 to 200GB of heap. If your servers run with 144GB RAM configurations this may be a good investment.

Advertisements

Typing and Binding and why static Type-Checking is a free, automated Test

[Meyer97] contains a neat chapter with definitions that makes it a lot easier to discuss about programming languages when it comes to typing. Here are the basics.

We should agree on the basic construct of object-oriented computation: the feature call or for SmallTalkers “passing a message to an object” and for Java guys and gals “invoking a method”.

The Basic Construct (feature call)

x.f(arg); // [0..n] arguments

(Meyer97, p.610)

Think of a non-trivial class-hierarchy of visual components, a classic example. There is an interface or an deferred (abstract) base class that requires descendants to provide a feature (method) named paint(context). What happens if the compiler does not check that every concrete class has an implementation? We get a type violation at run-time.

Definition: type violation

A run-time type violation (or just type violation for short) occurs in the execution of a call x.f(arg), where x is attached to an object OBJ, if either

(V1) There is no feature corresponding to f and applicable to OBJ.

(V2) There is such a feature, but arg is not an acceptable argument for it.

(Meyer97, p.612)

Object-oriented typing problem

When do we know whether the execution of an object-oriented system may produce a type violation?

(Meyer97, p.612)

In SmallTalk, the compiler does not check if every instance that declare “I’m a VisualComponent” does have an implementation of the method “paint()”. The developer can only verify the expected operation of the system by exercising the code in tests or production or by manually checking all classes.

Definition: statically typed language

An object-oriented language is statically typed if it is equipped with a set of consistency rules, enforceable by compilers, whose observance by a system text guarantees that no execution of the system can cause a type violation.

Doesn’t every organization crave for a look in the future? (Hint: If you are using a certain system called Oracle you know the answer 🙂 ). Using a statically typed language is basically a look into the future for free. You can see if your system is bound to fail at run-time. Giving that away doesn’t seem too smart.

Here are the characteristic properties when it comes to demixing your preferred language type-wise:

Typing and binding

  • Typing question: When do we know for sure that at run-time there will be an operation corresponding to f and applicable to the object attached to x (with the argument arg)?

  • Binding question: Which operation will the call execute?

(Meyer97, p.621)

Given that early detection of errors results in the lowest fixing costs it is desirable to know the answer to the question “when do we know we have a feature?” at “the earliest possible time”, determined by static type checking at compile time.

The answer to “what feature do we use?” should be “the right feature” – determined by dynamic binding at run-time.

Think of type checking a statically typed language text as an automated test you do not have to write because it is build into the system. I like that because it leaves more quality time to write tests that cannot be created by a machine :-)!

[Meyer97]    Meyer, Bertrand: “Object-Oriented Software Construction, Second Edition”, Prentice Hall, 1997.

The Test Tool Tutorial that was not Tested

If you happen to follow the JBoss Arquillian Getting Started tutorial (revision Dec 01, 2012) the first thing you’ll notice when running the example is: It doesn’t work :-). Dependency Injection just fails because of a bug in a dependency (probably ARQ-814):

 <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
            <version>1.0.0.CR3</version>
            <scope>test</scope>
  </dependency>

fails, but

 <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-weld-se-embedded-1.1</artifactId>
            <version>1.0.0.CR3</version>
            <scope>test</scope>
 </dependency>

succeeds with injection — note the small difference between se and ee. Obviously nobody took care to run the examples again after updating the text. I was using Java 7 and Maven 3.0.4 by the way.

It’s ironic that the tutorial example of a test tool fails in its core functionality because it’s not properly tested. I would expect an automated test to run the example as part of the Continuous Integration or Delivery process and generate the code examples from those.

Arquillian itself is very useful for some tests, I used it in the past but without the Weld CDI container. But be prepared – there are more, trickier bugs of course ;-).

A little reminder for me on how to quickly setup Jenkins on Ubuntu

Installation (from Jenkins installation guide)

wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

The package creates the user jenkins. Interesting locations are:

  • Settings (HTTP port!) are at: /etc/default/jenkins
  • Jenkins daemon startup: /etc/init.d/jenkins
  • Log file: /var/log/jenkins/jenkins.log

I prefer a different HTTP port than the 8080 default one, so I am going to change the default settings:

sudo vi /etc/default/jenkins

Find the value HTTP_PORT and change it to a free port (don’t forget to document in your Wiki!), for example 8282. Restart jenkins:

$ sudo service jenkins restart

Future updates are fetched by apt-get like any other package:

sudo apt-get update
sudo apt-get install jenkins

Missing Apple MacBook Keys: How to map the INSERT key in Linux/VirtualBox

The Alt+Insert shortcut is literally the key to the code generation menu in the NetBeans IDE. Using a PC keyboard in office this does not impose a problem but Apple’s MacBook line of notebooks does not have an insert key so development when sitting in a train is awkward.

Instead of changing the key in NetBeans I was looking for a way to map a rarely used key as the Insert key, using the X11 key mapping facility. I chose the circumflex ^, as I cannot remember when I needed it the last time. An alternative may be the to use the shifted key (keycode 50) that is mapped to ° by default.

Here’s a nice description on how to change keys in X11 that helped a lot. First I checked the keycodes using the xev tool which prints X11 event information using a console window:

xev

Then I added a new mapping expression:

 xmodmap -e "keycode 49 = Insert Insert"

I created a custom mapping file,

$ xmodmap -pke > ~/.Xmodmap

that is loaded in ~/.xinitrc:

#!/bin/sh
if [ -f $HOME/.Xmodmap ]; then
  /usr/bin/xmodmap $HOME/.Xmodmap
fi

Currently I am very happy with this solution, as it does not require custom bindings in NetBeans, provides the Insert key in all applications and does not get in the way when using a full-size MF-II keyboard.

Using standard OO techniques instead of Property Files for I18N and L10N

Using property files / message bundles for I18N / L10N and configuration purposes is problematic. Here’s why:

  • Property files are not refactoring safe.
  • They are in fact interfaces but rarely treated a such.
  • They are often a dump for everything that needed to be configurable a day before the iteration ends.
  • They’re often not well enough documented or not documented at all because documenting property files is a hassle (no standards, no javadoc)
  • …or they consist entirely of comments and commented out statements.
  • They make testing harder than necessary.
  • Often properties are created ad-hoc.
  • Validation logic and default handling inside the application is error-prone.
  • Missing definitions lead to runtime errors, undetected errors or awkward messages like “Error: No {0} in {1} found”.
  • Sometimes the file is not loaded because someone cleaned up src/main/resources.
  • Most property files are loaded on startup or only once.

How can we get rid of property files? I’d like to show you a straight forward solution in Java that will work well if you are not afraid of recompilation. Let me give you an example. This is what is common practice in Java:

# Find dialog
dialog.find.title=Suchen
dialog.find.findlabel.text=Suchen nach
dialog.find.findbutton.text=A very long text that needs to be wrapped but the developer does not know that it's possible - this really happens!
...

Most applications I’ve seen have endless definitions of properties for the UI. I swear I have never ever seen a non-developer change these property files!

The alternative is so simple I’m almost afraid to show it, but it has been extremely useful.

Define a name for each value and add it as a simple read-only property to an interface. Provide concrete implementations for each required language / locale.

 

package com.acme.myapp.presentation.find;

public interface FindDialogResources {
     public String getDialogTitle();
     public String getFindLabelText();
     public String getFindButtonText();
     public String getFindNextButtonText();
     public String getCancelButtonText();
     public String getIgnoreCaseText();
}

// Implementation in myapp-ui-resources-de_DE.jar

package com.acme.myapp.resources;

public class FindDialogResoucesBundle implements FindDialogResources {
    public String getDialogTitle() { return "Suchen"; }
    public String getFindLabelText() { return "Suchen nach";  }
    ....
}

// alternative to enable dynamic change of language:

public class FindDialogResources_de_DE implements ...

public class FindDialogResources_en_US implements ...

Resources that are subject to L18N and I10N must be externalized. But the way of externalization should conform to good software engineering practice.

I like the approach of linking a different resource JAR to smart client applications but you can also load classes by package- or name prefix to enable dynamic switching of languages (for web apps).

Advantages over property files:

  • Clean, minimal, intention-revealing interface (obviously).
  • Refactoring safe.
  • Statically typed and automatically linked by the JVM.
  • Missing definitions are compile-time errors, missing values are easily detected using reflection-based tests.
  • No assumptions about the final implementation.
  • Self-documenting
  • Interface defined in the same module.
  • Implementations can be delivered in other modules or (OSGi) fragments / language packs.

The builder that creates a UI entity requires a concrete implementation of this specific interface as a dependency. This principle can be applied to web applications as well, for example my exposing the resources as a managed bean. Declaring values in Java-Beans style comes in handy for auto-completion in Facelet templates.

public class SwingFindDialogFactory {
    private final FindDialogResources resources;

    public SwingFindDialogFactory (FindDialogResourceBundle resources) {
        requireNonNull(resources); // precondition
        this.resources = resources;
    }

    public FindDialog createInstance(...) {

        ...
        final JLabel findLabel = new JLabel(resources.getFindLabelText());
        final FindButtonAction findAction = new FindButtonAction(resources.getFindButtonText(), resources.getFindNextButtonText());
        ...
    }
}

...

// web app with JSF 2:

@Model
public class Resources implements FindDialogResources {
 private FindDialogResources delegate;

 @PostConstruct
 public initResources() {
     resources = application.getLocalizedFindDialogResourcesForPrincpipal();
 }

 public String getDialogTitle() {
     return delegate.getDialogTitle();
 }

// usage in facelet definition

<h:form>
 ...
 <h:outputText value="{resources.nameLabelText"} />
 <h:inputText value="{myUseCaseForm.name} />
 ...
</h:form>

As a bonus, you can:

  • Fallback to a default language (i.e. EN_us) if translation is not yet complete using a decorator.
  • Automatically validate each ResourceBundle implementation in the CI pipeline for completeness. For example by invoking all methods reflectively and checking results for non-empty values (a pretty good indicator if someone got a call during translation…).
  • You can easily generate and update the manual using simple programs written in Java as I’ve shown in other posts.
  • You can even wrap property files or other data sources if this is required by company policy.

Things you probably never tried with Java

Use a specific language for specific problems they say. Who’s they? A well-engineered general purpose language is often all you need for both small and large projects.

There are some good reasons for focussing on one language/environment:

  • You will get better and more creative in your main language.
  • Reuse the same tools for the final product and your infrastructure.
  • There’s not one specialist for “the ugly legacy build system we cannot get rid off”.
  • Apply the same rules on  code quality and design to scripts, build programs and other tools.

Scripting

Ever waded through historically grown, procedural Unix shell scripts? Let’s face it: BASH does not scale well. Write your scripts in Java. An example for a start script of a fictional application server.

#!/bin/jscript -Xmx1g

import com.acme.appserver.*;
public class StartAppServerWithTestSetup extends GenericAppServerStartup {

    public static final Port HTTP_PORT_TEST_ENVIRONMENT = new Port(4242);
    [...]

    public static void main(String[] args) {
         final AppServerConfigurationBuilder builder = new AppServerConfigurationBuilder(args);
         builder.changeHotDeploymentPath(TEST_PATH.resolve("integrationtest-deployments"));
         builder.changeHttpPort(HTTP_PORT_TEST_ENVIRONMENT);
         builder.changeDefaultDataSource(DATA_SOURCE_TEST_ENVIRONMENT);
         builder.changeDefaultLoggingDirectory(TEST_PATH.resolve("test-logs"));
         final AppServerConfiguration configuration = builder.build();

         final AppServer appServer = new AppServer(configuration);
         appServer.run();
    }
}

What are the basic requirements for the jscript application?

  • Extract Java code to identifiable directory.
  • Set up classpath for compiler (dependency:build-classpath might be of help).
  • Compile code to a designated repository using javac.
  • Prepare VM with classpath including script class and execute.

The only thing needed is a script or C application to prepare the code and bootstrap the JVM.

Build Process

Building Java systems in an enterprise environment is mostly done with Maven or Ant. Ant can do anything but it easily gets out of hand because of duplication. Maven tries to accomplish a lot of things, but who tried to implement a Continuous Delivery has noticed that Maven isn’t quite the fit.

Do you need to go down the so-called Groovy-way with Gradle? Give Java a try. Simple JAR modules can be build with a generic process, integration test steps may profit from the expressiveness of Java as an OO language. The Java Compiler API is a bit tricky but anybody should be able to compile Java files within an hour. Writing a JUnit adapter is a very good exercise to learn and think about class loading.

public class MyComponentTestBuildStep implements BuildStep {
   private final Pipeline pipeline;

   ...

   private final Path testSources;

   private BuildResult buildResult;

   @Override
   public void executeBuildStep() {
        final CompilerPlugin compilerPlugin = new CompilerPlugin(this, pipeline.getClassPathForTestScope());
        compilerPlugin.compiler(testSources);
        if(!compilerPlugin.wasSuccessful()) {
            markAsNotSuccessful(compilerPlugin);
            return;
        }

        final JUnitPlugin testRunnerPlugin = new JUnitPlugin(this,pipeline.getClassPathForTestScope());
        testRunnerPlugin.runTests(compiler.getPathOfCompiledClasses());

        final SurefireTypeReportGeneratorPlugin testReportPlugIn = new SurefireTypeReportGeneratorPlugin(this);
        testReportPlugIn.publishTestReports(testRunnerPlugin);

        if(testRunnerPlugin.wasSuccessful()) {
            markAsNotSuccessful(testRunnerPlugin);
            return;
        }

        markAsSuccess();

   }

   public void markAsNotSuccessful(final BuildPlugin buildPlugin) {
        Preconditions.require(!buildPlugin.wasSuccessful());
        buildResult = buildPlugin.getBuildResult();

   public void markAsSuccessful() {
       buildResult = null;
   }

   public boolean wasSuccessful() {
     return buildResult == null;
   }

   public BuildResult getBuildResult() {
      Preconditions.require(!wasSuccessful());
      return buildResult;
   }
}

This is just a little example to give you an impression how a build program may look like. If you don’t do continuous delivery you might not use the pipeline metaphor to structure your code.

It gets interesting when your Maven build(s) includes lots of specific plug-ins that are not well-maintained or hard to extend. A regular example is the generation of JAXB sources where there are several plug-ins that show awkward behaviour.

You can apply the same quality standards and testing principles for your build process as you do with production code. I have seen projects where several tests where not run on the build server because the tests did not end with Test.

Leverage the power of Java type checking and IDE code completion

XML or JSON are fine for some applications, but for some kinds of applications encoding data in Java classes is much more elegant, especially when you have a more flexible and dynamic way of structuring your modules than Maven and automatic updating. Here’s an example of how to encode Maven dependencies for a Java based build system:

public class ABuildProcess {
   ...

   // <dependencies>
   //   <dependency> ...
   public void setUpDependencies() {
      DependenciesBuilder builder = new DependenciesBuilder();
      builder.addDependency(org.apache.hadoop.hadoop_client.JAR.v1_1_2);
      builder.addDependency(org.apache.hadoop.hadoop_examples.JAR.v1_1_2);
      changeDependencies(builder.getDependencies());
   }
}

I wrote a little tool that provides a Maven repository in parts or as a whole as code-completion friendly Java classes. In most projects not all dependencies change at the same rate. Third-party dependencies are usually static throughout longer periods. You can use your IDEs global search to find all references to hadoop_client.JAR.v1_1_2 and either change the manually or streamline the usage by refactoring away unwanted duplication. A lot of tasks become much simpler when using a Java domain model compared to internal Maven representation of its POM.

Hints

A build process is a program and project of its own. You will probably notice that at first, that the degree of freedom is at least irritating or even hurtful in big projects. But once set up and well-maintained, fine tuning as well as significant changes and refactorings of the build process are much simpler than with declarative tools such as Maven or Ant. Eclipse JDT is all you need. Customizing a Maven plug-in calls for duplicated information and changes that ripple through the build.