2

I'm generating a jaxws client based on webservice. Jaxb will generate booleans using the java.lang.Boolean instead of the primitive type. In addition to this, it will generate the is() naming convention for beans.

However if I try to link the boolean (e.g. isOptional()) to a checkbox, it will throw the following exception:

value="#{property.optional}": Property 'optional' not readable on type java.lang.Boolean

My google skills have informed me that jsf works fine with:

 boolean isOptional()
 boolean getOptional()
 Boolean getOptional()

But not with

Boolean isOptional()

However it is not feasible to update the beans manually due to the size and amount of the webservices, so is there any way to make jsf use the java.lang.Boolean isOptional() properly? Or can I somehow define a property in the jaxb bindings file at generation time which magically generates "getOptional()"?

On a sidenote, the following does work:

<h:selectBooleanCheckbox value="#{property.isOptional()}"/>

However I can't actually update the value presumably because it can't find the setter.

EDIT: I'm running the latest jdk 7, the output of "java -version":

java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) Client VM (build 23.1-b03, mixed mode, sharing)

The output of "wsimport -version":

JAX-WS RI 2.2.4-b01

Generated code:

public Boolean isOptional() {
    return optional;
}
nablex
  • 4,319
  • 4
  • 29
  • 48

2 Answers2

4

Jaxb will generate booleans using the java.lang.Boolean instead of the primitive type. In addition to this, it will generate the is() naming convention for beans.

Using the is getter prefix for java.lang.Boolean was a known major mistake of JAXB. It has been fixed in version 2.1.13 which was released April 2010 already. Keep your libraries up to date.

See also this blog article for some background.

The Great JAXB API Blunder

September 15, 2006

You've got to hand it to Sun for screwing this one up. It's one thing to write software that doesn't adhere to a specification when the documentation is as thick as a textbook. Take, for example, just about anything created by the W3C. However, it's really bad when it is your own spec that you can't follow, especially when it is the most well known part of it. That's right, Sun missed by a mile on their own spec when they created the JAXB 2.0 API. The JAXB 2.0 compiler (XJC) incorrectly uses the prefix "is" rather than "get" when generating the getter method for a java.lang.Boolean property. While the JavaBean spec states that read methods for primitive booleans can use the alternate "is" prefix, this flexibility does not extend to its boolean wrapper counterpart.

8.3.2 Boolean Properties

In addition, for boolean properties, we allow a getter method to match the pattern:

public boolean is();

This "is" method may be provided instead of a "get" method, or it may be provided in addition to a "get" method. In either case, if the "is" method is present for a boolean property then we will use the "is" method to read the property value.

An example boolean property might be:

public boolean isMarsupial();
public void setMarsupial(boolean m);

Given that JAXB is a code generation framework, and the idea behind code generation frameworks is that the code is to be used "as is" and not modified thereafter, this is a pretty big "oops". While this issue has been reported, the response from Sun is "sorry, its too late".

This behavior is governed by the spec, and unfortunately it's just too late for the spec to change now.

In terms of the user experience, thanks to auto-boxing, I don't think this will be a real issue for people. Is the problem that you are using Introspector and it's missing the property? Too late? Not a real issue? It's BROKEN. FIX IT! I also don't like the naive statement that it probably won't affect frameworks. Um, yes it will, considering other projects did happen to adhere to the spec (hibernate, spring, myfaces, etc.)

UPDATE: Stevo Slavic informed me that this has been fixed in JAXB 2.1.13. See JAXB-131 for details. Yeah!

JSF/EL is not at fault here. It's doing its job properly conform the JavaBeans spec.

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • 1
    I'm running wsimport on jdk 7 which should have the proper jaxb library right? See original question for more information. – nablex Jun 25 '12 at 05:11
3

I'm not sure why the latest and greatest JAXB version still generates the wrong method but I finally fixed it by adding "-B-enableIntrospection" (as per http://jaxb.java.net/2.2.4/docs/xjc.html) to the wsimport call. This results in:

public Boolean getOptional() {
    return optional;
}
nablex
  • 4,319
  • 4
  • 29
  • 48