Sunday, 27 July 2014

Configuring integration tests in Scala Play project

I struggled, for several days I have to admit, to configure integration test to a Scala Play project.
With Maven it is usually a relatively trivial, well documented step. SBT also does have excellent article, but it does not work for Play project without tweaking. All I found on Web so far were not working, partial, usually poorly commented posts, often for outdated versions of SBT or Play.

I succeed so I am sharing. I share a full complete solution, with plentiful comments, tested and known to work with recent, summer 2014, versions of Scala, Play and SBT; that is 2.10.x for Scala, 2.2.x for Play Framework, 13.x for SBT.

Goal

Configure special group of tests, let’s call them integration tests, so they are run separately, on a special command only, not as a part of a normal build.

  • Integration tests to be in additional, separate source directory.
    For Play projects it is suggested “it” placed directly under project root, so let’s follow it.
  • Integration tests are not run in normal build, with ordinary tests.
    They will not run as a part on Jenkins (CI platform) project build.
  • Integration tests are run only on a special Play command (equivalent to Maven Profiles facility)
    Useful to have them as a separate Jenkins task.
  • No special test tagging, or file naming pattern is required
  • Special complication - integration tests are dependent on unit test, some helper classes are be shared, so integration test settings has to be aware of ordinary test sources.
  • Try to reuse library dependencies already defined for ordinary tests, so no extra dependencies configuration is required.

Commands

Play console:

it:compile

..to compile just integration tests

it:test

..run just integration tests

test

..run unit tests as usual

Useful: Re-run idea so IntelliJ recognises “it” as an additional test source directory so it can
syntax coloring etc is available and integration tests can be run from IDE.

Build.scala

import sbt._
import sbt.Keys._
import play.Project._

object ApplicationBuild extends Build {

  val appName         = "fooapp"
  val appVersion      = "1.0-SNAPSHOT"

  val appDependencies = Seq(
    "joda-time" % "joda-time" % "2.1",
    "org.scalatest" % "scalatest_2.10" % "2.0" % "test, it",
    "org.mockito" % "mockito-core" % "1.9.5" % "test, it"
  )

Dependencies were shortened.

Note the the test, it qualifier! It is essential, just test is not enough. And no qualifier would indeed cause mixing test with production dependencies.

Define additional source directory for integration tests. This tests are not run in normal build, with unit tests.

  /** integration test settings */
  def itSettings = {
    sourceDirectories in IntegrationTest <+= baseDirectory( _ / "it")
    sourceDirectory in IntegrationTest <<= baseDirectory( _ / "it")
    scalaSource in IntegrationTest <<= baseDirectory( _ / "it")
  }

Perhaps setting both sourceDirectories and sourceDirectory is not essential and only one would do. Explicitly setting scalaSource however is essential.

To define paths now using expression baseDirectory / "it" - is deprecated in SBT 13.x, the baseDirectory( _ / "it") or baseDirectory { _ / "it" } is recommended.

  lazy val IntegrationTestAltConf = config("it") extend(Test)

Based on original Play IntegrationTest. The difference is it is dow derived from Test (unit test) configuration and not Runtime configuration. The original definition is lazy val IntegrationTest = config("it") extend(Runtime) in sbt.Configurations but this way it was not it:compile does not recognize test classes, like TestHelpers used in my test. It is essential for projects where integration tests are not independent but depends on some shared test classes with other tests.

  lazy val main = play.Project(appName, appVersion, appDependencies)
    .settings(javaOptions in Test ++= Seq(
      "-XX:MaxPermSize=512M",
      "-Xms256M",
      "-Xmx512M",
      "-Xss1M"
    ))
    .settings(testOptions in Test += Tests.Argument("-oF"))

..and many other usual Scala project setting. Shortened. Here goes integration test setup:

    .configs(IntegrationTestAltConf)

It is a must, otherwise it will not recognize main sources and main libs. If the integration test were fully independent, shared nothing with unit tests, then standard IntegrationTest could be used.

    .settings(Defaults.itSettings : _*)

This makes command like it:compile and it:run possible from Play console

    .settings(itSettings)

Set additional separate directory for integration tests, see itSettings() method above.

}

That should be it. Don’t forget to run

reload

in Play console to check the new Build.scala validity

Useful: Re-run idea so IntelliJ recognises “it” as an additional test source directory so it can
syntax coloring etc is available and integration tests can be run from IDE.

I found it very useful to have SBT sources attached to my Play project. Sources are attached to binary library dependencies by Play command:

idea with-sources=yes

But this does not include SBT libraries. In my struggle with integration test configuration I had to check sources very often as documentation and examples are still rare or outdated. I’m not sure with Play but underlaying SBT can be persuaded to download its sources and link them to your Build.scala. Type in Play console:

update-sbt-classifiers
gen-idea sbt-classifiers

Source: http://stackoverflow.com/questions/17127367/sbt-sources-in-idea
The article is written for Sbt, but works for Play project without tweaks

Downside is, any subsequent re-run of idea or idea with-sources=yes will break the link to sources.

Written with StackEdit.

Wednesday, 3 July 2013

When one JVM process is not enough

I have just released to public domain batch of few interesting exercises in process spawning (fork) in Java, JVM process discovery, inter process communication, MBeans, JMX, Jvmstat, Java Attach API and handling child process output.

https://bitbucket.org/espinosa/a-java-playground/src/321b1c2f1c04b30ba7810ea76b89101091a931cf/src/main/java/my/code/a003/process?at=master

Have you ever wonder how JDK tools like VisualVM , JPS and JConsole discover all local running applications? How they manage to get hold of that internal information about them?

Featured exercises 

Unfinished

Get full command line for current and (external) target JVM process the same way VisualVM gets them. I'm nearly there, just unfinished due to lack of time. Simple sun.java.command system property provides only basic arguments like main class name and following arguments but not JVM attributes, like -D... or tuning -X: and -XX:
See: A021PrintActualExecutedCommandUsingSystemProperty.java and A022PrintActualExecutedCommandUsingRuntimeMXBean.java.

Lessons learned

There is no generic pure Java way how to get PID of started child process. If it is non JVM process then you are out of luck.

There is no straightforward way how to get PID of started child JVM process, however if it is a JVM application, one can use monitoring and attaching API from tools.jar distributed with JDK, but not JRE. tools.jar cannot be obtained from Maven, it has to come from the Java distribution.

There is no generic way how to kill non-java process. If it is a child process and you still hold reference to process, you can use Process#destroy() If it is not and the target process in not JVM, you are out of luck.

There is not easy straightforward way how to kill a process even if it is JVM application. There is no API call for that, be it Jvmstat or Attach or JMXBean. the only chance is to inject extra behaviour, using Java Agents, like MBean capable of shutting application down and capable of being operated remotely.

There is no easy, straightforward, way how to connect to a JVM application using JMX if you know the PID of the target application. To establish JMX connection PID has to be converted to Local Connector Address, then converted to JMXServiceURL. To get Local Connector Address from PID is tricky and involves loading management agent to target application (management-agent.jar) using Attach API. Agent then exposes com.sun.management.jmxremote.localConnectorAddress. A bit hackish but it is the official way recommended by Oracle (in Bugzilla).

There was no easy way how to redirect child process output to current stdout prior Java 7.

In Java 6+ applications you don't have to set up JMXBean server, it is capable of discovery and response to client JMXBean calls. You can get a lot of runtime information this way. To expose more part of running JVM app you have to load Java Agent, like management-agent.jar. Yep, you are loading new behaviour to unsuspected application!

Stopping child process, even when you have Process reference to it, and using standard Process#destroy() can still fail if the spawned child process spawned process another process itself (that is grand-children process). This may be issues at least on some (Windows) platforms.
See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092.

Java Agents carry a great potential. You can instrument application to do things not originally supposed to do, not only using special startup parameters, like with AOP LTW (Load Time Weaving), but also for already running application, completely unsuspecting JVM process! What are the security implications?

Useful links

I would get nowhere if those guys has not shared their wisdom, (in random order) :

VisualVM sources
  • com.sun.tools.visualvm.application.jvm.Jvm#ApplicationSupport#createCurrentApplication()
  • com.sun.tools.visualvm.jvmstat.application.JvmstatApplicationProvider#processNewApplicationsByPids()}
  • com.sun.tools.visualvm.jvmstat.application.JvmstatApplicationProvider#registerJvmstatConnection()
JPS sources

Friday, 28 June 2013

How to get Process ID for any JVM application?

How to get Process ID for any JVM application? How to get PID for current process?

There is plenty of solutions on Stackoverflow, mostly involving operating system hacks [1], or libraries with native code [2] or ManagementFactory.getRuntimeMXBean() based solutions [3], limited to current process only.

I would like to introduce another solution, JConsole, and potentially jps and VisualVM uses. It is based on classes from sun.jvmstat.monitor.* package, from tool.jar.

Jvmstat solution

This simple program gets list of all running JVMs on localhost, with their PIDs, and then extracting their main their classes comparing them to given main class name, returning PID when they match.

import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.VmIdentifier;


public class GetOwnPid {

    public static void main(String[] args) {
        new GetOwnPid().run();
    }

    public void run() {
        System.out.println(getPid(this.getClass()));
    }

    public Integer getPid(Class<?> mainClass) {
        MonitoredHost monitoredHost;
        Set<Integer> activeVmPids;
        try {
            monitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null));
            activeVmPids = monitoredHost.activeVms();
            MonitoredVm mvm = null;
            for (Integer vmPid : activeVmPids) {
                try {
                    mvm = monitoredHost.getMonitoredVm(new VmIdentifier(vmPid.toString()));
                    String mvmMainClass = MonitoredVmUtil.mainClass(mvm, true);
                    if (mainClass.getName().equals(mvmMainClass)) {
                        return vmPid;
                    }
                } finally {
                    if (mvm != null) {
                        mvm.detach();
                    }
                }
            }
        } catch (java.net.URISyntaxException e) {
            throw new InternalError(e.getMessage());
        } catch (MonitorException e) {
            throw new InternalError(e.getMessage());
        }
        return null;
    }
}

There are few catches:
  • The tool.jar is a library distributed with Oracle JDK but not JRE!
  • You cannot get tool.jar from Maven repo; configure it with Maven is a bit tricky, see [6].
  • The tool.jar probably contains platform dependent (native?) code so it is not easily distributable
  • It runs under assumption that all (local) running JVM apps are "monitorable". It looks like that from Java 6 all apps generally are (unless you actively configure opposite)
  • It probably works only for Java 6+
  • Eclipse does not publish main class, so you will not get Eclipse PID easily. It is probably because Eclipse is a JVM application, but is launched as eclipse.exe, a native executable somehow encapsulating JVM. You yould have to employ more sophisticated measures, like VisualVM does, to recognize Eclipse like checking characteristic JVM properties.

Comments on another questionable but popular solution

There is one more popular solution, mentioned for example here [4], and that is to use Process implementation class and get PID from its internal private data. 
Process process = Runtime.getRuntime().exec(command);
and then check returned implementation; allegedly on Unix it is java.lang.UnixProcess which has a private field called pid. But on Windows Process implementation returned is java.lang.ProcessImpl and it has no such field, no notion of PID. This is not a cross platform solution, besides relying on forcefully accessed private fields is always hackish and can stop working in the next Java release.

 Links

[1] http://www.jroller.com/santhosh/entry/get_current_java_process_id
[2] https://support.hyperic.com/display/SIGAR/Home
[3] http://stackoverflow.com/questions/35842/how-can-a-java-program-get-its-own-process-id
[4] http://stackoverflow.com/a/4750632/1185845
[6] http://stackoverflow.com/questions/3080437/jdk-tools-jar-as-maven-dependency  

Friday, 14 June 2013

GWT + Maven + Eclipse - alternative project setup

Mission

Create alternative GWT project template ideal for multiple small applications, multiple EntryPoints, a playground project setup, where one click on EntryPoint class will launch browser will run that EntryPoint and only that EntryPoint.

Project sources

Goals

  • Developers friendly setup
  • Provide project template for test, playground and technical spike style projects.
  • Perfect for ultra short modify-execute development cycles. Change is reflected immediately and browser opens with the right content.
  • Focus only on Client Side code (Java to JS) - create environment perfect for simple testing of things like positioning, events, DOM manipulation, visual stuff,..
  • Maven only based setup. Rely only on Maven provided libraries. No GWT and Web project plugin dependencies. Preven library duplication often introduced when using combined Maven and GWT plugin.
  • Rely only on Code Server on-the-fly compilation from Java to JS. It is light fast this way! Changes to Java sources are reflected immediately. Avoid slow full Java to JS compilation, either by Maven or Eclipse GWT plugin, in build time.
  • Avoid need of Eclipse launchers. With currently necessary to add client source directories to classpath)
  • start GWT app as easily as possible and as quickly as possible.
  • support large number of GWT apps easily in one project. Support one application == one class == one click to run. Ideal for testing or demonstrating specific topics in isolation. Vanilla GWT setup is not very helpful in that.
  • Have more control on app start process. Be able to influence any part of the process, be able to debug Code Server or Http Server. Expose what is under the hood of individual components.
  • This setup is not intended for production code. Default setup created by Maven GWT plugin or Eclipse GWT is perfect for production indented project, stick with it.
  • No need to touch GWT module descriptor when adding new EntryPoint.

How to run it

  • Clone project from my Git repository.
  • Run usual mvn clean install.
    • Do it from command line or, if you have Eclipse Maven plugin e2m installed, there is a menu for it.
    • Ideally, you would need to run Maven build just once, on the beginning, to set up everything.
  • Write your entry EntryPoint class
    • It can be an entry to a bigger application or a mini application in one class
    • Write as many EntryPoints as you wish
    • Class must be placed in the client code package (currently my.code.client)
    • Check provided Sample1.java.
  • Write app runner class, a class with main method, and one line of code
    • Its a class with main() method making it directly runnable class in all IDE, not only Eclipse. It that main() method is one call; it will check if servers are running and opens browser on the right URL for you
    • It is not required, it is a recommended convenience
    • See Sample1Run.java. More or less a copy and paste.
  • Run HttpServer (RunHttpServe.java)
  • Run GWT CodeRerver (RunCodeServer.java)
    • If you forget to run any of the required servers you will be kindly reminded, detection mechanism is in place. Keep this server running between individual your EntryPoint application runs.
  • Run your application
    • your EntryPoint, ideally with the prepared runner. Runner conveniently opens browser for you on the right URL, like this one http://localhost:8080/my.code.client.Sample3.do?gwt.codesvr=localhost:9998
    • Your Entry Point class is immediately executed and you are presented with results in a new browser tab or window.
    • Edit your code, re-run your launcher, it should immediately reflect your changes.
    • Recompilation is fully transparent, courtesy of running Code Server, it is incremental, and is fast.
    • Edit, rerun, again, and again, and again..
    • And new EntryPoint. There is no need to touch GWT module descriptor (*.gwt.xml).

How to run it - alternative

  • Creating a runner class for your Entry Point class is not essential but convenient. You can run you app by entering URL directly, the format is:
    http://localhost:8080/[qualified entry class point class name].do?gwt.codesvr=localhost:9998 

Screenshot of the template in action. Note, no GWT plugin is installed, just plain Eclipse and Maven Eclipse plugin (M2E), all relevant directories are unfolded:
For comparison an original setup, note several apparent issues, like multiple version of GWT libraries and necessity to use launcher to add sources to classpath (highlighted items):
 

TODOs and leftovers

  • I am working on a YouTube show case video
  • I am considering to make the whole web app a project resource. That is everything there, html files, css files, etc, will end up on classpath.
    Benefits: any change to CSS would be immediately reflected in application; no need to call Maven. New servlet would be needed - ExposeResourceDirectoryServlet (based on ExposeDirectoryServlet)
  • Check Maven resource definition, perhaps too restrictive excludes/includes.
  • gwt-dev should not be in the classpath. It contains potentially conflicting classes, like Apache IOUtils. The whole library is mess! But where else I can get Code Server classes! (DevMode, ..)
  • Adding tools.jar is not without troubles. This library is not in any Maven repository, it is part of JDK installation. The only way how to make it Maven dependency is to use SystemPath dependency type, otherwise strongly discouraged. There are known issues with OSX systems having non-standard location and name of tools.jar, and openJDK allegedly have tools.jar already in the classpath. Classes from tools.jar are used to monitor if required servers are running.
  • Much of the set up infrastructure has not been widely tested. It is just on "works for me" basis. It has been tested on Windows and Linux, but not on OS X.
  • Code Server prints annoying useless (?) exception when browser is closed com.google.gwt.dev.shell.BrowserChannel$RemoteDeathError: Remote connection lost.
    I don’t know how to suppress this, but is is harmless.

Monday, 13 May 2013

Solutions for mixed type Object equals() in Java

Equals have OOP inheritance have an uneasy relationship. Joshua Bloch famously stated that "there is no way to extend an instantiable class and add a value component while preserving the equals contract" (page 38, Effective Java, item 8). He suggests as the only solution always using Composition over Inheritance. But what if you have to stick Inheritance?
I am going to introduce you 5 (!) different solution for convenient comparison. To demonstrate the principles notorious classes Color and ColorPoint are used. You find them in Joshua Bloch's book, in official Java Language Specification or in Martin Odersky's blog so you should be familiar with them. Full implementation source code of all solutions in ready to use examples and unit tests can be found in my Bitbucket Git repo.
Where is the problem with inheritance and equals()? It is difficult to reconcile mixed type equality comparisons where subclass adds extra key fields. Problem is Point does not know about extra field in ColorPoint, so from its perspective they are equal, but from ColorPoint they are not - broken symmetry.
To demonstrate the problem I have prepared this two examples:
  • A1EqualsAndInheritanceUntreatedCodeBreaksSymmetry. This example presents implementation of equals() based on instaceof class comparison and test it on mixed type comparisons of Point and ColorPoint. This breaks symmetry when extra field
  • A2EqualsAndInheritanceUntreatedCodeBreaksLSP. Presents implementation of equals() provided by generators from famous IDEs like Eclipse or IntelliJ Idea based on strict class comparison – this.getClass().equals(other.getClass()). While it solves problem with broken symmetry and adheres fully to equals() contract, it blocks any mixed type comparisons, even between compatible classes like Point and PointAdapter. This breaks Liskov Substitution Principle!
For most people, even experienced developers, even for me it ended here – not possible, use composition. However on recent project, Hibernate based, we had several discussions about equals() in general and more importantly we were stuck with Entities heavily dependent on inheriting common fields. I did some research, most valuable appeared to be this StackOverflow discussion which set my direction. I have conveniently prepared all distinct solutions I found to discuss them with you.

Restricted mixed type equals() solutions

Solutions for Mixed Type equals() where Point genuinely cannot be equal to ColorPoint (extra field), but can be equal to PointAdapter (no extra fields).
  • Tal Cohen's blindlyEquals solution. It is included mainly because is often cited. It is the least effective solution but it is most intuitive and therefore good to start with.
    It is named after a required helper method – blindlyEquals. This method contains what equals() normally contains but it not bound with equals() contract. The equality is then established when both parties agree that they are blindly equal to each other. It is a sort of two phase commit. This obviously ensures symmetry. The drawbacks are obvious too. The equals() is in fact called twice, all fields has to be checked twice, for every direction.
    See A3EqualsAndInheritanceTalCohenSolution.
  • Rene Smith's getEquivalenceClass solution - as a reaction to Tal Cohen. Every class specify by overriding or not overriding helper method getEquivalenceClass() what class is relevant type comparison, what is the minimal required type. For Point it is Point, for ColorPoint it is ColorPoint, so far boring routine but here it comes, for ColorPointDecorator is is still ColorPoint because it does not override the helper method. This way equality between ColorPoint and Point is blocked, symmetrically blocked, but allowed for decorator class bringing no extra key fields.
    See A4EqualsAndInheritanceReneSmitSolution.
  • Martin Odersky's canEqual solution - where canEquals() is a helper method. It is in fact just a variant of previous example. This time helper method canEquals() does the whole class type comparison inside, it specifies minimal required class type internally, returning result as boolean.
    See A5EqualsAndInheritanceMartinOderskySolution.
  • Simple Reversing solution. My own implementation, based on suggestions in Angelika Langer article. I strongly suggest this solution. It does not require any helper method as do previously mentioned solutions. It is basically as simple as adding just 2 short lines to a standard equals() implementation everyone is familiar with.
    See A6EqualsAndInheritanceSimpleReversingSolution.

    Simple Reversing solution goes in two variants. Second variant uses repeated reversion blocking flag. Then we can afford revert direction even for same classes, dropping need for that extra check. It makes some thins simpler, and perhaps is a bit more performant, but it requires helper method - flagged version of equals().
    See A6EqualsAndInheritanceSimpleReversingSolutionAlt.

Unrestricted mixed type equals() solution

Solutions for mixed type equals() where Point genuinely can be equal to ColorPoint. In this case Point is considered a point with unspecified color, that is default color, let's say it is colorless by default, and therefore it can be compared to ColorPoint.
This approach assume every key field has a specified default value. If only one field cannot be assigned a default value then types are deemed incompatible for mixed type comparison.
There can be more than one default value per field but let's not complicate it for now.

Angelika Langer's Traverse Hierarchy solution

It is the only solution of all listed here, capable of comparing classes across different inheritance branches. You can compare Point3D with ColorPoint3D with ColorPoint or with root Point. This solution is fully and unarguably and 100% Liskov Substitution Principle compliant. It is also the most complex and difficult to understand solution.
Key points of Angelica Langer's solution are:
  • Every key field has defined default value
  • Hierarchy traversal is recursive process.
  • Hierarchy is traversed from the most specific subcass to more general class, that is bottom up principle. Equals is then conducted only in one direction – guarantees symmetry.
  • Order of comparison is reversed if (more specific) subclass is detected to achieve bottom up principle.
  • Comparison can continue up in the hierarchy only when all specific fields have default values.
  • 2 helper methods are required: navigateClassHierarchy(other, direction) and compareFields(other). Equals method can be defined at the root class, subclasses can safely inherit it. Helper methods have to be implemented in every class having extra key fields.
  • Equal ensures that both compared instances are part of same class hierarchy, that is they both extend Point, and fails early when they do not. Otherwise equals() is just a kick starter of hierarchy navigation and plays no further role.
  • If compared classes are on different hierarchy branches, comparison goes up (subclass to superclass) comparing fields on the way against the defaults, until common class root is found, then order is reversed to the direction from compared object class, it goes up the hierarchy again, comparing fields against the defaults, until it reaches common root again, it continues up again, comparing fields against each other, because we are on the same base class finally; until it reaches absolute root – Point in our case. If it reached this point, all the way down, from possibly two hierarchy branch leaves, we can finally certify them as equal.
  • The flag reverseOrder prevents traversal from sliding back to the first branch again when reaching common root from second branch. This would resulting in endless recursion. Flag reverseOrder can change value just once. From false to true, or not at all.
For the dear reader's convenience I have split Angelika Langer's implementation into two files, two gradual steps. First A7EqualsAndInheritanceAngelikaLangerSolution contains full implementation with same set of test as in previous examples, for easy comparison. Attached unit tests show that now ColorPoint can be equal to Point if the point has default color (that it is colorless) and symmetry is not broken.
But to demonstrate full power of Angelika Langer's hierarchy traversing solution I have to add extra sample classes and couple of new tests. The new classes are Point3D and ColorPoint3D; Point3D extends Point directly and ColorPoint3D, as the name suggests, extends ColorPoint. Two separate hierarchy branches formed here. Despite this extra complication we are able to match them equal when common fields are equal and specific fields having default values. That is ColorPoint3D(2, 3, 0, Color.TRANSPARENT) is equal ColorPoint(2, 3, Color.TRANSPARENT) or Point(2,3) or Point3D(2,3,0).

If you had the patience...

If you had the patience to read through this you are welcome. I spent some time researching on the subject, challenging paradigms is uplifting task. I prepared all 4 solutions I was able to find, plus one of my own provenance, for easy comparison, and I am happy to share the with you.
Inheritance issue with object equals() is often overlooked problem and even if you don't use any
If you thing you know better distinct solution, don't keep it for yourself and let other know.
If you are undecided which solution to use I recommend to stick with restricted mixed type equals(). In most cases you can rather argue that ColotPoint is not the same as Point and they should never equal. And from the restricted mixed type equals() I recommend Simple Reversing solution.
It is pretty much about copy and pasting 2 short lines to your existing code.

Side Notes

  • Unit testing in my examples is by no means extensive, its main purpose is to demonstrate the presented principle and provide ready to debug code for relevant cases.
  • For demonstration purposes I include whole code for discussed case into one file. Tests are mixed with tested implementation. This is not recommended for regular unit test an real projects. It is not my normal way of unit testing!
  • Java instanceof operator checks for null automatically, explicit testing is unnecessary. Use if (!(other instanceof Point)) is NPE safe. Expression null instanceof Point returns false. Yet I commonly see unnecessary constructs like:
    if (other == null) return false;if (!(other instanceof Point)) return false;

Thursday, 25 April 2013

Difference between Adapter, Decorator, Proxy and Facade design patterns

My take on four widely used and often confused design patterns - Adapter, Decorator, Proxy and Facade Patter – where are similarities and where they differ.

All four patterns have a lot in common, all four are sometimes informally called wrappers, or wrapper patterns. All use composition, wrapping subject and delegating the execution to the subject at some point, do mapping one method call to another one.

They spare client the necessity of having to construct a different object and copy over all relevant data. If used wisely, they save memory and processor.

By promoting loose coupling they make once stable code less exposed to inevitable changes and better readable for fellow developers.

Adapter

Adapter adapts subject (adaptee) class to a different interface. This way we can add object be placed to a collection of nominally different types. This way an object can be used as a parameter to a method call accepting nominally different types. An ordinary computation method can be made to run in parallel threads by a crafted Runnable Adapter or Future Adapter. All this without a single change in adaptee or client classes.

Adapter expose only relevant methods to client, can restrict all others, revealing usage intents for particular contexts. Adapters can both adapt 3rd party libraries, make them appear less general and more focused on core application business; or they can adapt our code for different needs of eternal clients. Adapters increase readability and self description of our code.

Adapters shields one team from volatile code from other teams, see Anticorruption Layer [Evans, DDD]. A life saviour tool when dealing with offshore teams :-)

Less mentioned purpose it to prevent the subject class from excess of annotations. With so many frameworks based on annotations this becomes more important usage then ever. Such annotations are often context or technology specific. On one POJO class you can end up having JAXB annotations, JPA annotations, UI annotations. They are convenient, but often breaks separation of concerns design principle.

Adapter helps to get around Java limitation of only single inheritance. It can combine several adaptees under one envelope giving impression of multiple inheritance. Adaptees in this case represents sort of Traits (as known from Scala).

Code wise, Adapter is “thin”. It should not add much code to the adaptee class, besides simply calling the adaptee method and occasional data conversions necessary to make such calls. The method mapping may not be one to one, sometimes one adapter call has to be split into several adaptee calls.

There are not many good adapter examples in JDK or basic libraries. They are common in real applications. Why? Because developers have often have to adapt 3rd party library class to do what it was not supposed to do, adapt it to custom, often very specific, application interfaces.

Decorator

Decorator not only delegates, not only maps one method to another, they do more, they modify behaviour of some subject methods. Decorator can decide not call subject method at all, but delegate the call to a different object. We call it adding a responsibility to object.

Decorators typically add (transparently) functionality to wrapped object like logging, encryption, formatting, or compression to subject. This New functionality may bring a lot of new code. Hence, decorators are usually much “fatter” then Adapters.

Decorator must be a sub-class wrapper class or interface. They can be used transparently instead of its subjects. See BufferedOutputStream, it is still OutputStream and can be used as such. That is a major technical difference from Adapters.

Decorator has the same UML diagram as Adapter, because it also wraps and delegates, but internally they do differ.

Text book examples of whole decorators family are readily in JDK - the Java IO. All classes like BufferedOutputStream, FilteredOutputStream and ObjectOutputStream are decorators of OutputStream. They can be onion layered, where one one decorator is decorated again, adding more functionality.

Proxy

Proxy is not a typical wrapper. The wrapped object, the proxy subject, may not yet exist at the time of proxy creation. Proxy often creates it internally. It may be a heavy object created on demand, or it is remote object in different JVM or different network node and even a non-Java object, a component in native code. It does not have to necessary wrap or delegate to another object at all.

Relationship between a Proxy and the real subject is typically set at compile time, Proxy instantiates it in some way, whereas Decorator or Adapter are assigned to the subject at runtime, knowing only subject's interface (see this blog).

Most typical examples are remote proxies, heavy object initializers and access proxies.

  • Remote Proxy – subject is on remote server, different JVM or even non Java system.
    Proxy translates object, makes RMI, REST calls, web calls, whatever is needed, shielding client from exposure to underlying technology.
  • Lazy Load Proxy – fully initialize object only the first usage, first intensive usage, especially when expensive resources are involved. This type proxy is handy where simple approach of lazy initialization holder class idiom [Joshua Bloch, Effective Java, Item 71] is not enough.
  • Remote image loader (see Head First Patterns) where image can be manipulated while it is not yet fully downloaded. Object can be used even when not fully initialized.
  • Access Proxy – control access to subject. For same subject can exist several access proxies for different contexts, like applets, server, local, different modules.
  • Synchronisation Proxy – see [Joshua Bloch's Effective Java, Item 78]. A bit unusual proxy in its form – a nested class – and by not really delegating or wrapping, but it is proxy nevertheless, a variant of security proxy, to prevent malicious code injection when deserializing an object.

Facade

Facade is closely associated with design Principle of Least Knowledge, also known as Law of Demeter, or simply as talk to you nearest friends only.

Facade is very similar to Adapter. They both wrap, they both map one object to another, but they differ in the intent. Facade flattens complex structure of a subject, complex object graph, simplifying access to a complex structure.

Facade wraps a complex structure, providing a flat interface to it. This prevents client object from being exposed to inner relations in subject structure hence promoting loose coupling.
Often listed as an Enterprise Pattern (link).

Bridge

More complex variant of Adapter pattern where not only implementation varies but also abstraction.
It adds one more indirection to the delegation. The extra delegation is the bridge. It decouples Adapter even from adapting interface. It increases complexity more then any other of the other wrapping patterns, so apply with care.

Differences in constructors

Patter differences are well obvious when looking at their constructors.
  • Proxy is not wrapping an existing object. There is no subject in constructor.
    Scheduler scheduler = new SchedulerRemoteProxy(); 
     
  • Decorator and Adapter does wrap already existing object and such is typically provided in the constructor:
    OutputStream fileOutput = new BufferedOutputStream(fileOutputStream); FooJaxbAdapter fooAdapter = new FooJaxbAdapter(foo);

  • Facade constructor takes root element of a whole object graph, otherwise it looks same as Adapter.

Real life example – Marshalling Adapter

Real life can confuse them and classification can be arguable. Look at my serialization JAXB Adapter example. Purpose of this adapter is mapping of a simple flat class to more complex structure required externally and to prevent "polluting" subject class with excessive annotations.

There may be other adapters soon, for the same subject class, for different marshalling systems and formats, like Jackson, binary object stream, with its own annotations, with peculiar requirements of technical nature. This is separation of concerns principle in action.

Because of its prime intent, it is Adapter. But one can argue it also maps simple structure to a more complex structure, something facade does. However in this particular case it is Reversed Facade. Normally Facade does mapping complex to simpler, in my particular case it is on contrary, adaptee is simple structure, specific to application, but required output is part of general standard, so it is more structured.

Also it has some traits of proxy as it creates some objects on the fly, when and if required, job normally associated with proxy, however, it creates them just for technical necessity, just to be able to fulfil it's main purpose – mapping.

Links

  • Original discussion on Stack Overflow – web link.
  • Head First Design Patterns, Eric Freeman & Elisabeth Freeman (book)
  • Joshua Bloch, Effective Java (book)
  • Eric Evans, Domain Driven Design (book)
  • Five's Weblog, The differences between Decorator Pattern and Proxy Pattern - web link.