[
https://issues.jboss.org/browse/WFLY-3527?page=com.atlassian.jira.plugin....
]
Randahl Fink Isaksen commented on WFLY-3527:
--------------------------------------------
Hi David. Thank you very much for getting back to me. I am not sure what you mean by
"serialized as a regular class", but what is happening is this:
1. I am receiving user input client side.
2. To validate this user input, I am sending a String to an EJB on WildFly, specifically
this method:
public Validation validateVerificationCode(EmailAddress emailAddress, String code) {
3. The server responds by sending back an instance of a Validation, a class which I am
appending below.
4. The error only occurs when I am returning Validation.INVALID, which is probably caused
by the fact that I use readResolve to turn all instances of Validation.VALID into the same
instance.
If you have any suggestions on how I can work around this bug until it is solved, I am all
ears – I am on a deadline, and this bug is a killer.
public class Validation implements Identified<String>, Serializable {
private static final Settings DEFAULT_SETTINGS = Settings.create(
Validation.class,
new Setting<>("invalid", "Not correct", ENGLISH),
new Setting<>("invalid", "Ikke korrekt", DANISH),
new Setting<>("validating", "Validating...", ENGLISH),
new Setting<>("validating", "Undersøger...", DANISH)
);
public static final Validation VALID = new Validation();
public static final Validation VALIDATING = new Validation(DEFAULT_SETTINGS,
"validating");
public static final Validation INVALID = new Validation(DEFAULT_SETTINGS,
"invalid");
private Settings defaultSettings;
private String id;
private List<Parameter> parameters;
private Validity validity;
private Validation() {
this.validity = Validity.VALID;
}
public Validation(Settings defaultSettings, String id, Parameter... parameters) {
this(Validity.INVALID, defaultSettings, id, parameters);
}
public Validation(Validity validity, Settings defaultSettings, String id, Parameter...
parameters) {
Guardian.notNull("validity", validity);
Guardian.notNull("settings", defaultSettings);
Guardian.notNull("id", id);
this.validity = validity;
this.defaultSettings = defaultSettings;
this.id = id;
this.parameters = Arrays.asList(parameters);
}
@Override
public String toString() {
if(this == VALID)
return "";
return defaultSettings.getString(id, (Parameter[]) parameters.toArray());
}
@Override
public String getId() {
return id;
}
public List<Parameter> getParameters() {
return parameters;
}
public Settings getDefaultSettings() {
return defaultSettings;
}
public Validity getValidity() {
return validity;
}
public boolean isValid() {
return validity == Validity.VALID;
}
private Object readResolve() throws ObjectStreamException {
if(isValid())
return VALID;
else return this;
}
}
Improper noargs constructor assumption leads to NullPointerException
--------------------------------------------------------------------
Key: WFLY-3527
URL:
https://issues.jboss.org/browse/WFLY-3527
Project: WildFly
Issue Type: Bug
Security Level: Public(Everyone can see)
Affects Versions: 8.0.0.Final
Reporter: Randahl Fink Isaksen
Assignee: David Lloyd
Priority: Critical
As shown in the stack trace below, I have received a NullPointerException from Wildfly.
Looking at the Wildfly code, it seems to me that the class
org.jboss.marshalling.reflect.SerializableClass improperly requires serializable classes
to have a noargs constructor.
The NullPointerException occurs in line 514:
514: return constructor.newInstance(args);
so the reason for the NullPointerException is that the parameter constructor is null.
Now, if you look at line 488, you see that the constructor parameter stems from the
method invokation
488: return invokeConstructorNoException(nonInitConstructor);
so the question is: When is nonInitConstructor defined, and why is it null?
The answer can be found in line 160
160: nonInitConstructor = lookupNonInitConstructor(subject);
and that method starts in line 550
550 private static <T> Constructor<T> More ...lookupNonInitConstructor(final
…
555 topConstructor = current.getDeclaredConstructor();
556 } catch (NoSuchMethodException e) {
557 return null;
558 }
…
563 }
As you can see here, the method getDeclaredConstructor is invoked with no args, so
Wildfly expects to find a noargs constructor. If non such constructor exists the
NoSuchMethodException is thrown, caught, and null is returned.
All in all I conclude, that creating a perfectly valid, serializable class with no noargs
constructor makes Wildfly crash, and I believe this is a serious bug.
CLASS WHICH MAKES WILDFLY FAIL
public enum Validity {
VALID(true),
QUESTIONABLE(true),
INVALID(false);
private boolean valid;
private Validity(boolean valid) {
this.valid = valid;
}
public boolean isValid() {
return valid;
}
}
Note: Any enum is also Serializable
STACK TRACE
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intuism.ui.validation.validator.ValidationTask.call(ValidationTask.java:49)
at com.intuism.ui.validation.validator.ValidationTask.call(ValidationTask.java:23)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1426)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NullPointerException
at
org.jboss.marshalling.reflect.SerializableClass.invokeConstructorNoException(SerializableClass.java:514)
at
org.jboss.marshalling.reflect.SerializableClass.callNonInitConstructor(SerializableClass.java:488)
at
org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1270)
at
org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:276)
at
org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:213)
at
org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1715)
at
org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1631)
at
org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1273)
at
org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:276)
at
org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:213)
at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:45)
at
org.jboss.ejb.client.remoting.MethodInvocationResponseHandler$MethodInvocationResultProducer.getResult(MethodInvocationResponseHandler.java:103)
at
org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:272)
at
org.jboss.ejb.client.EJBObjectInterceptor.handleInvocationResult(EJBObjectInterceptor.java:64)
at
org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:274)
at
org.jboss.ejb.client.EJBHomeInterceptor.handleInvocationResult(EJBHomeInterceptor.java:88)
at
org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:274)
at
org.jboss.ejb.client.TransactionInterceptor.handleInvocationResult(TransactionInterceptor.java:46)
at
org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:274)
at
org.jboss.ejb.client.ReceiverInterceptor.handleInvocationResult(ReceiverInterceptor.java:129)
at
org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:262)
at
org.jboss.ejb.client.EJBClientInvocationContext.awaitResponse(EJBClientInvocationContext.java:437)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:202)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:181)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:144)
at com.sun.proxy.$Proxy4.validateVerificationCode(Unknown Source)
... 13 more
Caused by: an exception which occurred:
in object of type com.intuism.core.settings.EmbeddedSettings
in field defaultSettings
in object of type com.intuism.ui.validation.Validation
--
This message was sent by Atlassian JIRA
(v6.2.6#6264)