Wednesday 8 December 2010

JBoss - separating application logs without using monolithic jboss-log4j.xml

A minor irritant we've discovered in implementing applications for Jboss AS is that that the logging configuration for applications has to go through their monolithic jboss-log4j.xml file.

So we've managed to find a work-around (after some investigation of the Jboss class loaders and some trial and error).  This technique has been confirmed for jboss-eap-4.3 and jboss-4.2.3.GA but will likely work for other versions.

If you want to have split application logs and have that log4j.xml based configuration separated out (e.g. Not have it all in the jboss-log4j.xml file) then you can do the following.

1.) Your WAR/EAR must contain log4j-1.2.16.jar. It must be 1.2.16 or later as earlier versions don't work.

2.) The class loading for that WAR or EAR must have its java2ParentDelegation=false. So for example the jboss-app.xml file will look something like this:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-app PUBLIC
      "-//JBoss//DTD J2EE Application 1.4//EN"
      "http://www.jboss.org/j2ee/dtd/jboss-app_4_2.dtd">
<jboss-app>
  <loader-repository>${your domain}:archive=${your app name}.ear
    <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
  </loader-repository>
</jboss-app>

Now this means that the WAR/EAR will use the log4j-1.2.16.jar for logging within its own classloader, i.e. It will not use Jboss's log4j.jar library (and therefore the jboss-log4j.xml won't be used).

3.) In the MANIFEST.MF file in your WAR/EAR archive you need to set a Class-Path: entry that shows the location (directory) where the log4j.xml file that you want to use will reside. For example if your EAR file is deployed in the deploy directory, your Class-Path reference might be something like this:

Class-Path: ../conf/log/${application name}/

4.) Your log4j.xml file should just be an ordinary one, with no references to any special jboss classes. However, it will have an appender with the specifc name for the log file for the application you want to log for, e.g.


  <appender name="${module.name}" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="${jboss.server.home.dir}/log/${module.name}.log"/>
    <param name="Threshold" value="INFO"/>
    <param name="Append" value="true"/>
    <param name="MaxFileSize" value="2MB"/>
    <param name="MaxBackupIndex" value="20"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{yyyyMMdd HH:mm:ss.SSS} %-5p [%t] %C{1}.%M(): %x %m%n"/>
    </layout>
  </appender>

5.) OPTIONAL: You can still have all of your logging also go to the shared central $JBOSS_HOME/${instance}/log/server.log file by adding the following to your log4j.xml file:


  <appender name="all" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="${jboss.server.home.dir}/log/server.log"/>
    <param name="Threshold" value="INFO"/>
    <param name="Append" value="true"/>
    <param name="MaxFileSize" value="2MB"/>
    <param name="MaxBackupIndex" value="20"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{yyyyMMdd HH:mm:ss.SSS} %-5p [%t] %C{1}.%M(): %x %m%n"/>
    </layout>
  </appender>

I've updated the Jboss community wiki with this information (thanks for pointing out the location Jaikiran!).

Tuesday 16 November 2010

Java is dead, long live the Java developer! - Part II


Hi all,
This is an updated post based on the recent announcements and events in November, enjoy!

Well, what a few months it has been in the Java space!  It started with Oracle announcing that the best plan to move the Java language forward was to split the existing openJDK work into Java 7 (for summer 2011), followed by a Java 8 (for summer 2012?).  You can see the current feature list for JDK7 at http://openjdk.java.net/projects/jdk7/features/.  Now that a decision has been made I think we'll see some good progress on this front.

This of course threw our plans for the book into a bit of a spin and so Ben Evans and I are now writing "The Well-Grounded Java Developer (covers Java 7)", a subtle yet important shift in the emphasis for the book.  This has caused some material to be thrown out (bye bye Date and Time, Closures and more) and other bits to be re-written.  If you're interested in the book or what is going on with Java 7, then head on over to http://www.java7developer.com for more details!

But that of course was not all!

The Oracle vs Google lawsuit continues to gather pace with Google counter suing Oracle.  It's watch this space for everyone at the moment, but it seems that at this stage the lawyers are going to be kept rather (happily one suspects) busy.  Another recent paper filed by Google appears to be a multi-layered defence, no quick resolution here then.  You can keep an eye on this over at groklaw

Oracle also announced a partnership with IBM in terms of developing the openJDK, a bit of a coup for Oracle, but understandably there was some backlash as the Java community as a whole realised that the formerly IBM backed Apache Harmony and all it stood for (a truly open Java) was effectively doomed.  This has been well covered in the blogosphere, so I'll leave it at that (repeat after me "pragmatic").

Then came some JCP nomination and election hooha!  Some prominent people have sadly left (Doug Lea foremost amongst them) and there are also accusations flying about the JCP election process being gamed somewhat.

Apple stated that they would no longer be providing their own version of Java for Mac OS 10.7 and beyond.  However, much to the relief of the Java community they then announced that they were gifting a vast majority of their work to the OpenJDK and would help Oracle integrate that.  So although the steward has changed, it's still likely we'll get a first class Java on the Mac.  I guess I'll buy a Macbook pro after all.

Last but not least we have the Apache foundation vs Oracle battle.  Remember the bit about Apache Harmony above?  Apache wrote a public letter thanking IBM for their efforts, it was all very professional and seemed as amicable as possible. However, they then went on to bluntly tell Oracle that they would vote against the JSR for Java 7 SE unless Harmony was granted access to the TCK without restrictions.  Yo can follow the conversation roughly via the links below

Apache's opening salvo --> Oracle's response --> Apache's response

So we have IBM, Apple and Oracle all pretty much playing in the openJDK/Java 7 sandpit, with Google and Apache firmly on the outer, still some interesting times ahead.

Are we there yet?
All in all this has of course led to many pundits claiming that Java is dying if not dead already.  I disagree with that assessment, but with a bit of a twist.

On the enterprise side of things I think that Java will continue to have a strong presence, especially now that the JVM ecosystem has matured and allowed languages such as Clojure, Scala and Groovy to flourish.  This is one of the cruxes that "The Well-Grounded Java 7 Developer" falls on.

On the desktop I think that JavaFX 2.0 may have come too late to the party and certainly Swing is looking very aged as a relevant desktop client library.

Mobile?  This is probably the big one for the future, we'll have to wait and see what the Google and Oracle lawsuit brings out. Android is 'Java based' and has moved well ahead in terms of mind share (if not devices) over J2ME. If it at least remains 'Java based', then the Java language will continue to do well in this space, especially when all the new young developers continue to build software for the Android.  If not, we may see a move towards Java (& JVM langauges) being seen purely as a specialised server side language.

Java's not dead - it's just got new plumage and there's _plenty_ of excitement for the 'Java' developer :)

Monday 1 November 2010

Java is dead, long live the Java developer!

Hi all,

Well, what a few months it has been in the Java space!  It started with Oracle announcing that the best plan to move the Java language forward was to split the existing openJDK work into Java 7 (for summer 2011), followed by a Java 8 (for summer 2012?).  You can see the current feature list for JDK7 at http://openjdk.java.net/projects/jdk7/features/.  Now that a decision has been made I think we'll see some good progress on this front.

This of course threw our plans for the book into a bit of a spin and so Ben Evans and I are now writing "The Well-Grounded Java Developer (covers Java 7)", a subtle yet important shift in the emphasis for the book.  This has caused some material to be thrown out (bye bye Date and Time, Closures and more) and other bits to be re-written.  If you're interested in the book or what is going on with Java 7, then head on over to http://www.java7developer.com for more details!

But that of course was not all!

The Oracle vs Google lawsuit continues to gather pace with Google counter suing Oracle.  No quick resolution here then.  It's watch this space for everyone at the moment, but it seems that at this stage the lawyers are going to be kept rather (happily one suspects) busy.  You can keep an eye on this over at groklaw

Oracle also announced a partnership with IBM in terms of developing the openJDK, a bit of a coup for Oracle, but understandably there was some backlash as the Java community as a whole realised that the formerly IBM backed Apache Harmony and all it stood for (a truly open Java) was effectively doomed.  This has been well covered in the blogosphere, so I'll leave it at that (repeat after me "pragmatic").

Then came some JCP nomination and election hooha!  Some prominent people have sadly left (Doug Lea foremost amongst them) and there are also accusations flying about the JCP election process being gamed somewhat.

Last but not least, Apple stated that they would no longer be providing their own version of Java for Mac OS 10.7 and beyond.  Given the work that it takes to 'macify' the Java experience this may prove to be an issue for Oracle to give the same user experience with Java on the Mac.  We'll hopefully see lots of job postings for this role as I personally love developing on my Macbook Pro :).

Are we there yet?

All in all this has of course led to many pundits claiming that Java is dying if not dead already.  I disagree with that assessment, but with a bit of a twist.

On the enterprise side of things I think that Java will continue to have a strong presence, especially now that the JVM ecosystem has matured and allowed languages such as Clojure, Scala and Groovy to flourish.  This is one of the cruxes that "The Well-Grounded Java 7 Developer" falls on.

On the desktop I think that JavaFX 2.0 may have come too late to the party and certainly Swing is looking very aged as a relevant desktop client library.

Mobile?  This is probably the big one for the future, we'll have to wait and see what the Google and Oracle lawsuit brings out. Android is 'Java based' and has moved well ahead in terms of mind share (if not devices) over J2ME. If it at least remains 'Java based', then the Java language will continue to do well in this space, especially when all the new young developers continue to build software for the Android.  If not, we may see a move towards Java (& JVM langauges) being seen purely as a specialised server side language.

Java's not dead - it's just got new plumage and there's _plenty_ of excitement for the 'Java' developer :)

Monday 23 August 2010

Dependency Injection in Java 7

Hi all,


So apart from recovering from a long bout of the stomach flu, enjoying good food again at a "Come dine with me" night (our parents would be so proud) and planning a rush trip to Vegas I've managed to get out a first draft of the Dependency Injection chapter for the Well Grounded Java 7 Developer.


Java 7 unifies some of the basic standards that the various Dependency Injection frameworks (Spring, Guice, PicoContainer etc) have, making it easier for developers to move between the frameworks as needed.


A reminder of what DI is with regards to Java[1]

The javax.inject package specifies a means for obtaining objects in such a way as to maximize re-usability, testability and maintainability compared to traditional approaches such as constructors, factories, and service locators (e.g., JNDI). This process, known as Dependency Injection, is beneficial to most nontrivial applications.


So without further preamble, here's a short section from the chapter, let me know what you think!


Inject annotation

The @Inject annotation interface can be used in three places to indicate where you'd like a dependency to be injected.  Below are the types of members that can be injected, in the order that they are processed at runtime:

1.   Constructors
2.   Methods
3.   Fields

You can annotate a constructor with @Inject and expect its parameters to be provided at runtime by your configured IoC container e.g:

@Inject public MurmurMessage(Header header, Content content)
{
    this.header = header;
    this.content = content;
}

In this case both the Header and Content parameters would be injected at runtime.  The specification allows for 0+ parameters to be injected for constructors, so injecting a zero-parameter constructor is still valid.

WARNING As per the specification there can only be one constructor in a class with an @Inject annotation, this makes sense as the JRE would not be able to decide which injected constructor took precedence.

You can annotate a method with @Inject and like a constructor, expect its 0+ number of parameters to be injected at runtime.  There are some restrictions in that injected methods cannot be declared abstract and cannot declare type parameters of their own[1].  The short code sample below demonstrates the use of @Inject with a setter method, a common technique when using Dependency Injection.

@Inject public void setContent(Content content)
{
    this.content = content;
}

This technique of method parameter injection is especially powerful when it comes to providing service methods with the resources they need to do their job.  For example you could pass a DAO argument to a finder service method that was tasked to retrieve some data.

TIP It has become a default best-practice to use constructor injection for setting mandatory dependencies for a class and to used setter injection for non-mandatory dependencies, e.g. fields that already have sensible defaults.

It is also possible to inject fields (as long as they are not final), however the practice is not common.  The syntax again is quite simple.

public class MurmurMessenger
{
    @Inject private MurmurMessage murmurMessage;
    ...
}

You can read further about the @Inject annotation in the Javadoc, where you can discover some nuances about what types of values can be injected and how circular dependencies are dealt with.

Cheers,

Monday 9 August 2010

A Little Directory love

Hi all,

So my next little snippet also comes from Chapter 2 of the book where we deal with the new NIO.2 (Non-Blocking I/O 2) APIs being introduced to Java 7.  In particular I'm showing a small code snippet to showcase some of the new support for directories that Java 7 has.  The code sample certainly needs a little tidy-up by using the new Automatic Resource Management (ARM) features in Java 7, but for now the example will suffice.


Dealing with Directories

The java.nio.file.DirectoryStream interface and its implementing classes allow you to:

  • Iterate over entries in a directory.
  • Deal with large directory structures.
  • Filter entries whilst processing using regular expressions and MIME based content detection.
  • Walk the tree structure in order to perform recursive move, copy, delete operations.
A common use case here is to list entries in a directory, e.g. Java source files as shown by the listing below.

DirectoryStream stream = null;
try
{
    // Define the directory
    Path dir = Paths.get("c:\\workspace");

    // Declare a filtering stream
    stream = dir.newDirectoryStream("*.java");
    // List each .java file in that directory
    for (Path entry: stream)
    {
        System.out.println(entry.getName());
    }
}
catch (IOException e)
{
    // Poor man's exception handling
    e.printStackTrace();
}

As you can see, with the new Java 7 APIs this particular task is much simpler than it used to be and this theme is prevalent in the rest of the NIO.2 APIs.

There are several other use cases which we will show case in the "NIO.2 in action" section.as well as on our upcoming website (to be revealed later).


So are we there yet?  In terms of File and Directory interaction in Java 7 there's certainly a massive improvement, so I'll say "Yes" once Java 7 is released.

Cheers,
Martijn

Thursday 5 August 2010

The Well Grounded Java 7 Developer

Hi all,

I've obviously not posted for quite some time and here is the reason why.....

It's been a long time coming, but I'm very happy to announce that Ben Evans and I have been contracted to write "The Well  Grounded Java 7 Developer" for Manning publications.  We've been spending the last month frantically getting the first few chapters out and a whole host of other book related activities, but now that I'm in full chapter writing mode I'll be adding regular posts to this blog.

A majority of my future posts will focus on interesting areas in this book and firstly I'd like to show a reworked extract from the new Date and Time API section.

Modeling Date and Time

The new API models time as a sequence of consecutive instants separated by fixed durations[1].  Java 7 maps these concepts directly on to classes, here's a more detailed explanation:
  • The javax.time.Instant class represents a specific point on a discrete time-line e.g. January 23rd, 1996 at 09:00:00,0 UTC, the day that Java 1.0 was released.
  • The javax.time.Duration class represents a section of elapsed time in nanoseconds, e.g. The 400 nanoseconds it takes for a PIC12C672-04 Microchip to execute an instruction set.

So as you can imagine, any point of time can be modeled by simply applying a Duration (positive or negative) to a starting Instant.
...
...

Calendering

With regards to calendaring, the main Calendar is ISOChronology, but other calendars such as CopticChronology and ThaiBuddhistChronology are supported.  The Chronology interface can be extended from to provide other implementations.
...
...

Timezone support

Timezone support is also provided via three core classes:
  • LocalDateTime – Represents date/time without an offset or a time zone.
  • OffsetDateTime - Represents date/time with an offset but not time zone.
  • ZonedDateTime - Represents date/time with an offset and a time zone.
...
...


[1]               This phrase is almost 100% uplifted from an excellent early primer article by Jesse Farnham, see  http://today.java.net/pub/a/today/2008/09/18/jsr-310-new-java-date-time-api.html for details


The book will be loaded with more in depth explanations and of course plenty of code samples.  If you're interested in becoming a reviewer then please let me know!


Wednesday 9 June 2010

The Modern Java Developer

Hi all,

Here's a brief synopsis that a colleague of mine (Ben Evans) and I have been thinking about for sometime, and we're curious to hear your feedback if you think you'd like to hear about some of the themes within this synopsis at the 2nd LJC Unconference.

"The role of the Java developer is undergoing a period of immense change - challenges such as manycore processors, new approaches to concurrency and a wealth of new languages (including functional and dynamic) on the JVM are redefining the nature of Java projects. The core SE/EE APIs have been supplemented by a large and growing body of additional material and technologies which the developer must know.

Some of the upcoming new Java 7 features - including closures, invokedynamic and standardised dependency injection tackle some of these challenges.  But it's not just core language updates that matter anymore, there's also been a change in the modern Java project lifecycle with a host of common tools and practices a developer will now be expected to encounter (largely borrowed from the Agile world).  Lastly, there are new JVM languages which are gaining in popularity and which the developers may expect to encounter on future projects."

Do people agree with the synopsis above?  Are they finding their Java projects changing to a new model?

Feel free to debate as I believe we're definitely not there yet!

Wednesday 19 May 2010

Exciting projects on the go!



Hi all,

This is another mainly Java/Technology related post, although it's more of an overview of what I'm up to.  This is as much to do with getting it sorted in my head as anything else but people have asked what I'm involved in, so here goes:

1.) Reviewing an upcoming book on the Hudson Build Server (a favourite build tool of mine).  I'm definitely behind on helping out on this one, I really need a few solid hours of quiet time to review the material produced to date.

2.) Reviewing an upcoming book on Java 6 certification.  I'm trying to learn as much about the book review process as possible before hopefully co-authoring my own, so that's my main motivation for this one.  I'm still on the fence about certification, I dislike most of it but if it encourages people to study then that's not all bad.

3.) Negotiating (along with a colleague) a book deal with a big tech book publisher, we're getting closer to some sort of a deal I think!  This is the big exciting one for me, I've always wanted to try an author part of book if not an entire one so I really hope we can make this happen.

4.) Moderating on the Javaranch, which is going through a bit of an SEO overhaul at the moment.  I'm also hopefully getting my wife ("a most excellent Graphic Designer" and that's definitely not just according to me) to help give it a facelift.

5.) Community leading two open source projects (PCGen and Ikasan EIP).  These I wish I could spend a few extra regular hours on a week.  PCGen was the project that lead me into Open Source in the first place and the community spirit is just freakin awesome.  No matter how many times I take sabbaticals away from it, I always miss it far too much and just have to go back :).

Ikasan is the new kid on the block that I'm trying to turn into a "successful open source project" as part of my day job.  It's got a great deal of potential, but I need to spend a good deal more time with the community in order to realise it.

6.) Co-organising the London Java Community and the London Graduate and Undergraduate Development Community which currently involves helping organise an Unconference for the LJC and an not yet announced talk for the GDC.

7.) Writing several talks for conferences (sssh it's a secret)

With several of items above, I work with some pretty amazing and motivated people and that's why I pretty much stay involved, it's just plain fun and rewarding to boot!

So there you have it, my tech related life in a nutshell :).

Cheers,
Martijn

As an aside, I spotted the statement "If you want something done, give it to a busy person" on the web a couple of days ago while I was lying in bed nursing a bout of the man flu (which my wife was ever so patient with).  I realised that it holds pretty darn true for all of psychotically busy friends and colleagues that I know, they always seem the most organised and on to it.

Monday 19 April 2010

Our new home

Hi all,

For those of you who weren't aware, as soon as I came back from New Zealand and Australia I was forced to move as the landlord was selling the place.  We've found a great new Garden flat not too far from the old location but the lack of broadband at home is still killing me and is sadly stopping me from contributing to my favourite Open Source projects :(.  The new place is taking shape quite rapidly now and it already has that homely feel that only good company can provide.  Mind you it doesn't hurt that my wife is an extremely skilled Graphic Designer/Artist and just magically knows where things should go for maximum utility and impact (how do they do that?!).  It's a good thing that she keeps me busy manually shifting things about so I don't come up with my somewhat ill thought out ideas on interior decorating.

We also have our new Cat "Lucifer" (courtesy of our lovely flatmate) who is great company around the place, but his habit of scratching at the door and meowing at all hours of night is not quite as well received.  But we're determined to stay strong and not let him come in and purr loudly and be cute at 3am in the morning, I wonder who's going to win :)

We live in a lovely area of North London with plenty of parks and small local places/shops for local people, making it more like living in a pleasant continental European suburb than the cold concrete jungle that London can sometimes come across as.  Still, as "Yummy Mummies" with their prams, countless Dog walkers and over enthusiastic joggers go by it's hard to think what I'm quite doing in this type of neighbourhood.  Having started in the hustle, bustle and grime of East London, I find myself missing the soul and energy of that part of town.

So if you're in the North London neighbourhood then drop me a line, I happen to know of a good pub or two to while the hours away.....

Are there yet?  The big bag of unpacked clothes in our bedroom says no :)

Thursday 8 April 2010

Java Experiments

Hi all,

So I've been frantically packing and moving over the last week which means once more I have a pithy excuse to have posted as regularly as I promised, my bad!

Again this is a Java posting, so a warning to those adverse to seeing source code!

I ran across another common misunderstanding with Java for those first developing with it (and indeed for some more experienced developers!).  This was also highlighted in a recent TheDailyWTF article.  The mis-understanding is explained in the code below and is often asked about as an interview or certification question.

Thanks to Scott Selikoff, (I co-opted his code example).

package org.martijnverburg.experiments;

/**
 * This class runs experiments to prove various pass by value 
 * and pass by reference rules in the JDK
 *
 * The use of System.out.println is generally frowned 
 * upon, but I'll forgive myself in this case.
 * 
 * This probably should be a nice Unit test, many 
 * apologies!
 *
 * @author Martijn Verburg (aka karianna)
 */
public class PassByValuePassByReferenceExperiments
{

  /**
   * Fire off the experiments
   *
   * @param args - Not used
   */
  public static void main(String[] args)
  {
    PassByValuePassByReferenceExperiments test = new PassByValuePassByReferenceExperiments();
    test.changeValueOfObjectPassedIn();
  }

  /**
   * This method challenges a false assumption whereby the 
   * developer may think that when they pass an object reference 
   * into a method as an argument, then change the value of 
   * that object in the method, that the reference they hold 
   * onto in the calling method retains that changed value.
   *
   * TODO:  The explanation above isn't the clearest English, 
   * try to tidy that up later.
   *
   * If you misunderstand how this works in Java you may expect
   * to see the result as:

   * 
   * 10
   * 10
   *
   * The actual output of this experiment is:
   * 
   * 10
   * 3
   */
   private void changeValueOfObjectPassedIn()
   {
     Integer x = new Integer(3);
     changeX(x);
     System.out.println("Value of x is = [" + x + "]);
   }

  /**
   * The key concept here is the the Integer x declared 
   * in the argument list for the method is a local copy 
   * of the original reference.  So when you alter its value, 
   * you're only altering the local version, which incidentally 
   * falls out of scope when the method ends.
   */
   private void changeX(Integer x)
   {
     x = new Integer(10);
     System.out.println("Value of x is = [" + x + "]);
   }

}

So are we there yet?  Sadly no, all to often developers forget the fundamental rules like this and for new developers this concept can be especially confusing.


But although some developers might look down upon those who don't have the fundamentals memorised, I actually feel that it can be OK to be a bit forgetful or hazy, after all you can't remember it all!  I say that with the proviso that you should actively engage in improving your fundamentals knowledge, writing tiny test cases/experiments like the above code can be a very helpful aid.

Wednesday 31 March 2010

When Order of Precedence goes bad

Hi all,

Well I told a lie about posting every week, but hey I was enjoying the sunshine in the antipodean lands (Australia and NZ)! So from here on in I'll try to keep my original promise and write _something_ every week and so here we are! Warning this post is heavily aimed at the Java world, those who prefer a non technical read had best leave now :-).

So a colleague and I were tracking down a problem late last night and were looking at a particular line of code that wasn't executing in the order that the original author intended:

if (this.conditionOne() && (this.conditionTwo() || this.conditionThree()))

Basically an assumption was made that the(this.conditionTwo() || this.conditionThree()) would be evaluated first.  We were reminded that the BEDMAS rules of arithmetic do not necessarily apply to Java order of precedence when evaluating expressions. Feel free to run the experiment below if you, like us, wanted a reminder....

package org.martijnverburg.experiments;

/**
 * This class runs experiments to prove various order 
 * of Precedence rules in the JDK
 *
 * The use of System.out.println is generally frowned 
 * upon, but I'll forgive myself in this case.
 * 
 * This probably should be a nice Unit test, many 
 * apologies!
 *
 * @author Martijn Verburg (aka karianna)
 */
public class PrecedenceExperiments
{

  /**
   * Fire off the experiments
   *
   * @param args - Not used
   */
  public static void main(String[] args)
  {
    PrecedenceExperiments test = new PrecedenceExperiments();
    test.bracketedAndOrExperiment();
  }


  /**
   * This method tests an assumption that was made 
   * in any code base about the order of precedence 
   * when (x && (y || z)) gets executed 
   * as opposed when ((y || z) && x) gets 
   * executed.
   */
   private void bracketedAndOrExperiment()
   {

     // Run ((y || z) && x)
     if ((this.conditionTwo() || this.conditionThree()) 
          && this.conditionOne())
     {
       System.out.println("Completed case: ((y || z) && x)");
     }



     // Run (x && (y || z)) case
     if (this.conditionOne() && 
          (this.conditionTwo() || this.conditionThree()))
     {
       System.out.println("Completed case: (x && (y || z))");
     }

   }

   private boolean conditionOne()
   {
     System.out.println("1");
     return true;
   }

   private boolean conditionTwo()
   {
     System.out.println("2");
     return true;
   }

   private boolean conditionThree()
   {
     System.out.println("3");
     return true;
   }
}

So are we there yet?  Well I guess for the code base I'm currently working on that would be a no, we've a few more of these cases to discover and iron out.  Another musing that comes out of this is that perhaps  "maintainability" is sometimes better than code brevity, maybe writing code in the style of if (x && (y || z)) can be simplified to it's component parts.

Sometimes it's the little things.