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;
}
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.
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;
}
Related
I'm learning android studio 4.1 using Kotlin from a 2020 book. In one of the examples they are using a MutableLiveData object. When I try to use code completion with this line:
result.setValue(value.toFloat()*usd_to_eu_rate)
the only option is the setter result.value tough result.setValue does work just fine. So I was wondering what the difference is between the two and why value does not show up in code compleation.
Thanks to this link - kotlinlang.org/docs/reference/java-interop.html#getters-and-setters - provided by #IR42 and other information by other contributors whos comments were unfortunately deleted I found my answer:
MutableLiveData is a Java class and Kotlin will infer a property when the Java class has methods that follow the Java conventions for getters and setters (no-argument methods with names starting with get and single-argument methods with names starting with set)
Code completion will not suggest the Java getter methods (i.e. getValue and setValue) but it will suggest the Kotlin inferred property (i.e. value)
You can still use the Java getter/setter methods but this is discouraged.
I have created a class implementing GenericHandler to use in .handle() method. I have setters for the class, but if i have more than 1 setter with same argument type, i am getting "Found Ambiguous parameter type".
Why there is such restriction?
That's just because ServiceActivatingHandler is based on the MessagingMethodInvokerHelper logic on background to determine the appropriate messaging method. And setters are candidate for that purpose.
So, if you really hae several of them with the same param type, we end up with ambiguity issue.
To fix your case, I suggest mark your Object handle(P payload, Map<String, Object> headers); implementation with #ServiceActivator.
From other side I agree that it is not so good as we expect from Framework. So, feel free to raise a JIRA issue on the matter and we will fix .handle() to be more strict and rely only on the handle() method from the GenericHandler implementation.
I faced the same problem while using Spring integration while using a service adaptor. Could not define multiple properties of type java.lang.String - I would get a IllegalArgumentException claiming "ambiguous parameters".
After finding no solution to the issue, decided to just create a class to encapsulate those properties, configure this as a bean, and then inject it into the spring-integration config.
I replaced all of my JNDI lookups with JNDI.lookup() method because it seemed convenient, dealt with dynamic return types, etc. All was great...but now I just noticed that the checked exceptions that I had to catch before are no longer there.
I assumed this was because it would have just returned null if the JNDI variable didn't exist but it doesn't. It now just throws an unchecked exception.
Any idea why? Is there a way of just returning null for non-existant variables instead?
I created a bug for this on the omnifaces website: https://github.com/omnifaces/omnifaces/issues/141
Not sure if this is intended behavior or not.
Is there a way of just returning null for non-existant variables instead?
It does that for NameNotFoundException. The problem was here not in OmniFaces, but in the environment, which was GlassFish 4.1 in your specific case. It unexpectedly wrapped the NameNotFoundException in another NamingException, hereby causing the underlying NameNotFoundException to slip through and bypass the return null condition.
This has been fixed with help of Exceptions#is() utility method as per this comment. It will be available in OmniFaces 2.2.
I'm in the process of trying to migrate a R# extension project from R# 6 to R# 8. (I've taken over a project that someone wrote, and I'm new to writing extensions.)
In the existing v6 project there is a class that derives from RenameWorkflow, and the constructor used to look like this;
public class RenameStepWorkflow : RenameWorkflow
{
public RenameStepWorkflow(ISolution Solution, string ActionId)
: base(Solution, ActionId)
{
}
This used to work in R# SDK v 6, but now in V8, RenameWorkflow no longer has a constructor that takes Solution and actionId. The new constructor signature now looks like this;
public RenameWorkflow(
IShellLocks locks,
SearchDomainFactory searchDomainFactory,
RenameRefactoringService renameRefactoringService,
ISolution solution,
string actionId);
now heres my problem that I need help with (I think)
I've copied the constructor, and now the constructor of this class has to satisfy these new dependancies. Through some digging I've managed to find a way to satisfy all the dependencies, except for 'SearchDomainFactory'. The closest I can come to instantiating via the updated constructor is as follows;
new RenameStepWorkflow(Solution.Locks, JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance, RenameRefactoringService.Instance, this.Solution, null)
All looks good, except that JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance is marked as Obsolete, and gives me a compile error that I cannot work around, even using #pragma does not allow me to compile the code. The exact error message I get when I compile is Error 16 'JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance' is obsolete: 'Inject me!'
Obvious next question..ok, how? How do I 'inject you'? I cannot find any documentation over this new breaking change, in fact, I cannot find any documentation (or sample projects) that even mentions DrivenRefactoringWorkflow or RenameWorkflow, (the classes that now require the new SearchDomainFactory), or any information on SearchDomainFactory.Instance suddenly now obsolete and how to satisfy the need to 'inject' it.
Any help would be most appreciated! Thank you,
regards
Alan
ReSharper has its own IoC container, which is responsible for creating instances of classes, and "injecting" dependencies as constructor parameters. Classes marked with attributes such as [ShellComponent] or [SolutionComponent] are handled by the container, created when the application starts or a solution is loaded, respectively.
Dependencies should be injected as constructor parameters, rather than using methods like GetComponent<TDependency> or static Instance properties, as this allows the container to control dependency lifetime, and ensure you're depending on appropriate components, and not creating leaks - a shell component cannot depend on a solution component for instance, it won't exist when the shell component is being created.
ReSharper introduced the IoC container a few releases ago, and a large proportion of the codebase has been updated to use it correctly, but there are a few hold-outs, where things are still done in a less than ideal manner - static Instance properties and calls to GetComponent. This is what you've encountered. You should be able to get an instance of SearchDomainFactory by putting it as a constructor parameter in your component.
You can find out more about the Component Model (the IoC container and related functionality) in the devguide: https://www.jetbrains.com/resharper/devguide/Platform/ComponentModel.html
So I've been away from Java EE for six months and I'm now back and migrating an application to Java EE 7 and I am noticing that JSR-341/ the EL 3.0 spec. contains changes in the section Type Conversion (now, section 1.23; formerly, section 1.18).
In section 1.23, the very first rule in all of the various types except String is that if X is null and Y is not a primitive return null. This is a much welcome change.
So my first question is: with regard to section 1.23.3 Coerce A to Number type N,
In EL 2.1:
If A is null or "", return 0.
In EL 3.0:
If A is null and N is not a primitive type, return null.
Else if A is null or "", return 0.
Is it now no longer necessary to set the system property org.apache.el.parser.COERCE_TO_ZERO=false?
Next, there are a couple of other changes that beg questions:
In the very first subsection, section 1.23.1 (formerly 1.18.1) To Coerce a Value X to Type Y, the rule for the general case is given. Now, a new bullet has been added (emphasis mine):
If X is null and Y is not a primitive type and also not a String, return null.
In section 1.23.2 Coerce A to String the first two bullets have been flipped around. They are now in the following order:
If A is null: return “”
Otherwise, if A is String: return A
It appears that whereas before a null String remained a null String after coercion, now a null String is coerced to an empty String. So my second question is: am I reading this correctly, that the String is now treated differently than the other kinds of objects with respect to coercion? If so, why?
Such a change seems counterintuitive because as we all know null has special meaning. Moreover, such a change is alarming because it can adversely affect the code that I'm migrating, which was was originally written against an older spec.
And, finally, my third question is: what about bean validation? Does this mean that now #NotNull annotations on Strings in backing beans are useless because coerced String values can never be null? I doubt it, but I'd like to know how the new changes all work together.
Is it now no longer necessary to set the system property org.apache.el.parser.COERCE_TO_ZERO=false?
When you're using Apache EL parser (as used in among others Tomcat), that's correct. In other words, they have indeed finally implemented my own request on that.
Given that you're using Wildfly, that should however not really be applicable in your particular case, as it doesn't use Apache EL, but just EL RI (like as in GlassFish) which had this part already right from the beginning on. This was just a minor oversight in the EL spec and Tomcat guys were just very picky on this (they had this part right too until Tomcat 6.0.16 and then mangled it in order to "comply" the oversight in the spec and after a lot of complaints they added this system property in 6.0.17 in order to be able to turn it off).
am I reading this correctly, that the String is now treated differently than the other kinds of objects with respect to coercion?
Nope. The ordering shouldn't matter, result would be the same all time. null is not a String anyway. The ordering has likely been changed for clarity and simplification of the implementation.
In JSF perspective, this EL spec section only concerns writing results of EL expressions to HTML output (which is of String type), not updating model values with submitted/coerced/converted/validated values, as you seemed to expect. For that, you still need the following web.xml context parameter to let JSF interpret empty string submitted values as null:
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
This part has not changed as compared to JSF 2.0/2.1.