[Skip to content]

Changes

This document describes the changes in the Java formatter engine of Jalopy 1.4 that may have an impact on formatting style (depending on your code convention).

Creator calls were wrongly wrapped

The "Wrap on-demand after left parenthesis" option did not work for method declarations parameter lists when Endline indentation was enabled.

Pleaes note that you can enforce the former behavior with the new "Avoid bare left parenthesis" option!

public void foo(String theVeryFirstParameter, |
                String para2,                 |
                com.foo.MyObject param3,      |
                Object param4,                |
                FooBar anotherOne) {          |
}                                             |

was wrongly printed as

public void foo(String theVeryFirstParameter, |
                String para2,                 |
                com.foo.MyObject param3,      |
                Object param4,                |
                FooBar anotherOne) {          |
}                                             |

Now it does (depending on your settings)

public void foo(                              |
                String theVeryFirstParameter, |
                String para2,                 |
                com.foo.MyObject param3,      |
                Object param4,                |
                FooBar anotherOne) {          |
}                                             |

Creator calls were wrongly wrapped

With the three wrapping options "Prefer wrap after assignments", "Prefer wrap after return" and "Prefer wrap after left parenthesis" disabled, creator calls after either assignments or return statements or used as method arguments lead to wrong wrapping. In some cases a line break was inserted before creators even when the maximal line length was not exceeded.

return new CDRInputStream_1_2();                                    |
                                                                    |
throw wrapper.invalidRequestPartitioningComponentValue(new Integer( |
        thePartitionToUse));                                        |

was wrongly printed as

return                                                              |
    new CDRInputStream_1_2();                                       |
                                                                    |
throw wrapper.invalidRequestPartitioningComponentValue(             |
    new Integer(thePartitionToUse))                                 |

Now it does (depending on your settings)

return new CDRInputStream_1_2();                                    |
                                                                    |
throw wrapper.invalidRequestPartitioningComponentValue(new Integer( |
        thePartitionToUse));                                        |

Maximal line length exceeded for array initializers

Array initializers as part of an array creation expression, could exceed the maximal line length.

Object[] rArgs = new Object[] {                                    |
        rParent, new Integer(nDefaultStyle)                        |
    };                                                             |

was wrongly printed as

                                                                   |
Object[] rArgs = new Object[] { rParent, new Integer(nDefaultStyle) };
                                                                   |

Now it does (depending on your settings)

Object[] rArgs = new Object[] {                                    |
        rParent, new Integer(nDefaultStyle)                        |
    };                                                             |

Line breaks around operators not kept

With "Keep line breaks for operators" enabled, line breaks for operators where not kept when the operand contained a dotted expression.

pm.LogDebug("TimeSeries response from " +    |
            ddAddr +                         |
            " ID: " +                        |
            pi.pi.IcmpID +                   |
            "; Sequence: " +                 |
            pi.IcmpSeq);                     |

was wrongly formatted as

pm.LogDebug("TimeSeries response from " +    |
            ddAddr + " ID: " + pi.pi.IcmpID +|
            "; Sequence: " + pi.IcmpSeq);    |

Now it will be printed (depending on your settings)

pm.LogDebug("TimeSeries response from " +    |
            ddAddr +                         |
            " ID: " +                        |
            pi.pi.IcmpID +                   |
            "; Sequence: " +                 |
            pi.IcmpSeq);                     |

Wrongly printed blank lines for multi-array elements

With endline indentation enabled, blank lines between elements of multi-array initializers were not correctly printed.

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX

    // Action messages
    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX

    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" },

    // Action messages
    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" },

    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

was wrongly formatted as

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX
····

    // Action messages
    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX
····
{ "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" },

    // Action messages
    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" },

{ "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

Now it will be printed (depending on your settings)

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX

    // Action messages
    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX

    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" },

    // Action messages
    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

public static Object[][] contents = {
    { "SYSTEMNAME_VARIABLE", "%SystemName%" },

    { "USERMSG_NODUPLICATES", "Please enter a unique action name." },
};

Wrongly printed multi-arrays

Multi-array initializers were wrongly printed when only one element was given in the second dimension.

public static Object[][] contents = {
    { "", "" },
};

was wrongly printed as

public static Object[][] contents = {
    { "", "" }, };

Now it is printed (depending on your settings)

public static Object[][] contents = {
    { "", "" },
};

Blank lines before comments wrongly printed

When "Keep blank lines up to" disabled, the blank lines settings for comments were ignored, which could lead to wrongly removed blank lines.

//
// The rows vector contains the actual data
//
private Vector rows = StorageFactory.getVector();

//
// The columns vector is just used for maintaining the column names
//
private Vector columns = StorageFactory.getVector();

//
// The table header for this table
//
private SortingTableHeader sortingTableHeader = null;

was wrongly formatted as

//
// The rows vector contains the actual data
//
private Vector rows = StorageFactory.getVector();
//
// The columns vector is just used for maintaining the column names
//
private Vector columns = StorageFactory.getVector();
//
// The table header for this table
//
private SortingTableHeader sortingTableHeader = null;

when the "Blank lines before single-line comments" option was set to '1'. Now it will be printed

//
// The rows vector contains the actual data
//
private Vector rows = StorageFactory.getVector();

//
// The columns vector is just used for maintaining the column names
//
private Vector columns = StorageFactory.getVector();

//
// The table header for this table
//
private SortingTableHeader sortingTableHeader = null;

Wrong indentation after array types assignment expressions

With endline indentation enabled, method declarations could become wrongly indented, when an array type assignment expression did not fit into the maximal line length.

private void hideUnavailableMonitors(Hashtable hash) {

    PreferenceMap[] preferenceMap = {
        new PreferenceMap(Preferences.MONITOR_PROFILE,
                          MonitorTypeManager.PROFILE_MONITOR)
    };
}

/* getAvailableMonitors
 * Get a list of available monitors.
 */
public Object getAvailableMonitors() {
}

was wrongly formatted as

private void hideUnavailableMonitors(Hashtable hash) {

    PreferenceMap[] preferenceMap = {
        new PreferenceMap(Preferences.MONITOR_PROFILE,
                          MonitorTypeManager.PROFILE_MONITOR)
    };
}

    /* getAvailableMonitors
 * Get a list of available monitors.
 */
    public Object getAvailableMonitors(){
}
private void hideUnavailableMonitors(Hashtable hash) {

    PreferenceMap[] preferenceMap = {
        new PreferenceMap(Preferences.MONITOR_PROFILE,
                          MonitorTypeManager.PROFILE_MONITOR)
    };
}

/* getAvailableMonitors
 * Get a list of available monitors.
 */
public Object getAvailableMonitors() {
}

Wrong obmission of logging conditional

With "Insert logging conditional" enabled, debug calls inside an if statement did not have a conditional added.

if (i == 5) {
    _test.debug("This won't be formatted!");
}

was wrongly formatted as

if (i == 5) {
    _test.debug("This won't be formatted!");
}

Now it will be printed (depending on your settings)

if (i == 5) {
    if (_test.isDebugEnabled()) {
        _test.debug("This won't be formatted!");
    }
}

Wrongly indented comments after switch statements

Comments after switch statements were not correctly indented when "Indent case from switch" was disabled.

switch (buf.charAt(i)) {
// if another line break follows, we insert the given asterix
// directly before the next line break

case 'x':
    ...
}

was wrongly formatted as

switch (buf.charAt(i)) {
    // if another line break follows, we insert the given asterix
    // directly before the next line break

case 'x':
    ...
}

Now it will be printed (depending on your settings)

switch (buf.charAt(i)) {
// if another line break follows, we insert the given asterix
// directly before the next line break

case 'x':
    ...
}

Wrongly indented comments after case and default statements

Comments after case and default statements were not correctly indented when "Indent case from switch" was disabled.

switch (c) {
...
default:
    // event type cannot be consumed
}

was wrongly formatted as

switch (c) {
...
default:
// event type cannot be consumed
}

Now it will be printed (depending on your settings)

switch (c) {
...
default:
    // event type cannot be consumed
}

Wrong alignment for comments after elements

With endline indentation enabled, comments after elements could be wrongly aligned.

public static Object[][] contents = {
    //
    // Previous Value: CONNECT_CP_SERVICE - "Trying to connect to X."
    // Current Value: CONNECT_CP_SERVICE - "Trying to connect to X."
    { "CONNECT_CP_SERVICE", "X" },
    // Previous Value: None
    // Current Value: ERR_NO_MONITORS - "No X monitor is found."
    { "ERR_NO_MONITORS", "X" },
    //
    // Previous Value: ERR_MONITOR_DELETED - "no Mon ID)."
    // Current Value: ERR_MONITOR_DELETED - "(no Mon ID)."

    { "ERR_MONITOR_DELETED", "X" },
    //
    // Previous Value: ERR_OBSOLETE_DATA - "This data is too old."
    // Current Value: ERR_OBSOLETE_DATA - "No new X data."
    { "ERR_OBSOLETE_DATA", "X" },
    //
    // Previous Value: None
    // Current Value: ERR_NO_DATA - "No data available."

    { "ERR_NO_DATA", "X" },
};

was wrongly printed as

public static Object[][] contents = {
    //
    // Previous Value: CONNECT_CP_SERVICE - "Trying to connect to X."
    // Current Value: CONNECT_CP_SERVICE - "Trying to connect to X."
    { "CONNECT_CP_SERVICE", "X" },
    // Previous Value: None
    // Current Value: ERR_NO_MONITORS - "No X monitor is found."
    { "ERR_NO_MONITORS", "X" },
//
// Previous Value: ERR_MONITOR_DELETED - "(no Mon ID)."
// Current Value: ERR_MONITOR_DELETED - "(no Mon ID)."

    { "ERR_MONITOR_DELETED", "X" },
    //
    // Previous Value: ERR_OBSOLETE_DATA - "This data is too old."
    // Current Value: ERR_OBSOLETE_DATA - "No new X data."
    { "ERR_OBSOLETE_DATA", "X" },
//
// Previous Value: None
// Current Value: ERR_NO_DATA - "No data available."

    { "ERR_NO_DATA", "X" },
};

Now it does (depending on your settings)

public static Object[][] contents = {
    //
    // Previous Value: CONNECT_CP_SERVICE - "Trying to connect to X."
    // Current Value: CONNECT_CP_SERVICE - "Trying to connect to X."
    { "CONNECT_CP_SERVICE", "X" },

    // Previous Value: None
    // Current Value: ERR_NO_MONITORS - "No X monitor is found."
    { "ERR_NO_MONITORS", "X" },
    //
    // Previous Value: ERR_MONITOR_DELETED - "(no Mon ID)."
    // Current Value: ERR_MONITOR_DELETED - "(no Mon ID)."

    { "ERR_MONITOR_DELETED", "X" },

    //
    // Previous Value: ERR_OBSOLETE_DATA - "This data is too old."
    // Current Value: ERR_OBSOLETE_DATA - "No new X data."
    { "ERR_OBSOLETE_DATA", "X" },
    //
    // Previous Value: None
    // Current Value: ERR_NO_DATA - "No data available."

    { "ERR_NO_DATA", "X" },
};

Nested HTML lists

With Javadoc formatting enabled, no line break was printed before the closing </li> tag of nested lists.

/**
 * <li>Verzeichnisse
 * <ul>
 * <li>Yahoo</li>
 * <li>Web.de</li>
 * <li>Dino-Online</li>
 * </ul>
 * </li>
 */

was formatted as

/**
 * <li>Verzeichnisse
 *   <ul>
 *     <li>Yahoo</li>
 *     <li>Web.de</li>
 *     <li>Dino-Online</li>
 *   </ul></li>
 */

Now it will be printed as

/**
 * <li>Verzeichnisse
 *   <ul>
 *     <li>Yahoo</li>
 *     <li>Web.de</li>
 *     <li>Dino-Online</li>
 *   </ul>
 * </li>
 */

Closing parentheses wrongly aligned

With endline indentation enabled, closing parentheses were not correctly aligned with the corresponding left parentheses when a line break occured before the closing parenthesis.

myMethod(
    getSomeValue(
        param1
    ),
    param2
);

was printed as

myMethod(
         getSomeValue(
                      param1
                      ),
         param2
         );

Now it will be printed (depending on your settings)

myMethod(
         getSomeValue(
                      param1
                     ),
         param2
        );

Method declaration parameters wrongly aligned

With "Align method declaration parameters" enabled, the parameters were wrongly aligned when a vararg was part of the list

public MethodDispatcher(Object   rTarget,
                        String   sMethod,
                        Class... rParamTypes) {
}

was printed as

public MethodDispatcher(Object rTarget,
                         String sMethod,
                         Class... rParamTypes) {
}

Now it will be printed (depending on your settings)

public MethodDispatcher(Object   rTarget,
                        String   sMethod,
                        Class... rParamTypes) {
}

Wrong line break after Javadoc inline tags

With Javadoc formatting enabled, a line break could be printed between the closing brace of an inline tag and a dot right after the brace.

/**                                                   |
 * <p>blahblahblahblahbahblahblah see {@link foof()}.</p>
 */                                                   |
void foo() {                                          |
}                                                     |

was wrongly formatted as

/**                                                   |
 * <p>blahblahblahblahbahblahblah see {@link foof()}  |
 * .</p>                                              |
 */                                                   |
void foo() {                                          |
}                                                     |

Now it will be printed (depending on your settings)

/**                                                   |
 * <p>blahblahblahblahbahblahblah see {@link          |
 * foof()}.</p>                                       |
 */                                                   |
void foo() {                                          |
}                                                     |

Wrong number of blank lines after reflowed comments

With either of the Reflow comment options enabled, one blank line above the specified blank line amount was printed after comments that got reflowed.

System.out.println("........"); // Strange end-line comment that    |
                                // spans several lines and islonger |
                                // than the comment in the originaldd
                                // example!                         |
return;                                                             |

With "Blank lines before control statements" set to '0', was wrongly formatted as

System.out.println("........"); // Strange end-line comment that    |
                                // spans several lines and islonge  |
                                // than the comment in the          |
                                // originaldd example!              |
                                                                    |
return;                                                             |

Now it will be printed (depending on your settings)

System.out.println("........"); // Strange end-line comment that    |
                                // spans several lines and islonge  |
                                // than the comment in the          |
                                // originaldd example!              |
return;                                                             |

Comments were not correctly associated

When no blank lines could be found between elements and comments, Jalopy always preferred to associate comments with the next element. Now it checks wether the column offsets of the preceding and following elements are different and if so adds the comment to the preceding element when their offsets match

switch (state) {
default:
    stateError();
    /* NOTREACHED */
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
    break;
}

was wrongly formatted as

switch (state) {
default:
    stateError();

/* NOTREACHED */
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
    break;
}

Now it will be printed (depending on your settings)

switch (state) {
default:
    stateError();
    /* NOTREACHED */

case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
    break;
}

Comments in front of expressions always lead to blank lines

When the commetns blank lines settings specified any positive number of blank lines before comments, comments in front of expressions had the given number of blank lines inserted before the comment.

/* test */ System.out.println();
/* test */ System.out.println();

was formatted as

/* test */ System.out.println();

/* test */ System.out.println();

Now it will be printed (depending on your settings)

/* test */ System.out.println();
/* test */ System.out.println();

Wrong number of blank lines before prefix expressions

Prefix increment or decrement expressions that appeared right after blocks and contained comments before could lead to wrong number of blank lines between block and expression.

if (!sawDecimal) {
}

// If we have seen the decimal, but no significant digits yet,
// then we account for leading zeros by decrementing the
// digits.decimalAt into negative values.
--digits.decimalAt;

was wrongly formatted as

if (!sawDecimal) {
}


// If we have seen the decimal, but no significant digits yet,
// then we account for leading zeros by decrementing the
// digits.decimalAt into negative values.
--digits.decimalAt;

Now it will be printed (depending on your settings)

if (!sawDecimal) {
}

// If we have seen the decimal, but no significant digits yet,
// then we account for leading zeros by decrementing the
// digits.decimalAt into negative values.
--digits.decimalAt;

Wrongly printed comments before right parentheses

Comments appearing before right parentheses were not correctly printed.

for (Enumeration enum = h.keys();
     enum.hasMoreElements();
    /* no increment portion */
) {
    ...
}

was wrongly formatted as

for (Enumeration enum = h.keys(); enum.hasMoreElements();/* no increment portion */
    ) {
    ...
}

Now it will be printed (depending on your settings)

for (Enumeration enum = h.keys(); enum.hasMoreElements();
    /* no increment portion */
) {
}

Wrongly printed comments after rhs of operator

Comments after the rhs of an operator enclosed with parentheses were wrongly printed after the right parenthesis.

private static final int RMASK = 
    (1 << 1 /* U_RIGHT_TO_LEFT */) |
    (1 << 5 /* U_ARABIC_NUMBER */) |
    (1 << 13 /* U_RIGHT_TO_LEFT_ARABIC */) |
    (1 << 14 /* U_RIGHT_TO_LEFT_EMBEDDING */) |
    (1 << 15 /* U_RIGHT_TO_LEFT_OVERRIDE */);

was wrongly formatted as

private static final int RMASK = (1 << 1) /* U_RIGHT_TO_LEFT */ |
    (1 << 5) /* U_ARABIC_NUMBER */ |
    (1 << 13) /* U_RIGHT_TO_LEFT_ARABIC */ |
    (1 << 14) /* U_RIGHT_TO_LEFT_EMBEDDING */ | (1 << 15) /* U_RIGHT_TO_LEFT_OVERRIDE */;

Now it will be printed (depending on your settings)

private static final int RMASK = (1 << 1 /* U_RIGHT_TO_LEFT */) |
    (1 << 5 /* U_ARABIC_NUMBER */) |
    (1 << 13 /* U_RIGHT_TO_LEFT_ARABIC */) |
    (1 << 14 /* U_RIGHT_TO_LEFT_EMBEDDING */) |
    (1 << 15 /* U_RIGHT_TO_LEFT_OVERRIDE */);

Trailing white space after Javadoc inline tags

With Javadoc formatting enabled, trailing white space after Javadoc inline tags was not removed.

/**                                                        |
 *~@return~~list~of~attached~annotations~(of~type~{@link~  |
 *~~~~~~~~~~com.foo.Annotation~<Annotation>}).             |
 */                                                        |

was wrongly formatted as

/**                                                        |
 *~@return~~list~of~attached~annotations~(of~type~{@link~  |
 *~~~~~~~~~~com.foo.Annotation~<Annotation>}).             |
 */                                                        |

Now it will be printed (depending on your settings)

/**                                                        |
 *~@return~~list~of~attached~annotations~(of~type~{@link   |
 *~~~~~~~~~~com.foo.Annotation~<Annotation>}).             |
 */                                                        |

Chained methods calls

When wrapping for chained method calls were forced, a line break was always printed before the first chain link. Now a line break before the first chain link gets only printed when an identifier appears before the method or the method contains qualification.

foo().toString().test();

was formatted as

foo()
    .toString()
    .test();

Now it will be printed (depending on your settings)

foo().toString()
     .test();

Expressions wrongly wrapped

With "Insert expression parentheses" disabled, expressions could be wrongly wrapped.

if (m.aMargins[0] == 0 && m.aMargins[1] == 0 &&   |
    m.aMargins[2] == 0) {                         |
    ...                                           |
}                                                 |

was wrongly formatted as

if (m.aMargins[0] == 0 && m.aMargins[1] == 0 && m |
     .aMargins[21] == 0) {                        |
    ...                                           | 
}                                                 |

Now it will be printed (depending on your settings)

if (m.aMargins[0] == 0 && m.aMargins[1] == 0 &&   |
    m.aMargins[2] == 0) {                         |
    ...                                           | 
}                                                 |

Missing parentheses around instanceof operator

With "Insert expression parentheses" enabled, no parentheses was added for the instanceof operator.

The following contrived (?) code

if (null != owner && owner instanceof org.w3c.dom.Node) {
}

was wrongly formatted as

if ((null != owner) && owner instanceof org.w3c.dom.Node) {
}

Now it will be printed (depending on your settings)

if ((null != owner) && (owner instanceof org.w3c.dom.Node)) {
}

What is Jalopy?

Jalopy is a world-class source code formatter for Java. It automates and enforces all aspects of source code layout—to meet a certain coding style without putting any burden on individual developers.

Learn more

Who needs it?

Jalopy is for everyone involved with source code editing. It scales from single developer usage to large scale enterprise deployment and seamlessly integrates with your favorite Java IDE or build tool.

Go and see yourself

I want some!

Concentrate on your problem domain and don’t waste time shuffling characters around. Pricing starts at USD $40 for a single-user license. Buy now using secure online purchase or wire transfer.

What are you waiting for?

Learn the details

Deploy, configure and use the software to best meet your needs. Download the printable user’s guide and learn everything there is to know to put Jalopy’s capabilities to full use.

Download (.pdf - 8.3MB)