2013/9/19 Lukasz Lenart [lukaszlen...@apache.org]:
2013/9/18 Patrick Savage patrick.sav...@3pillarglobal.com:
We are using XWork's @Inject in Struts 2.3.1.2 to inject a
DefaultObjectTypeDeterminer into a custom type converter. Since upgrading
from Java 1.6.0_33 to 1.7.0_25, this injection does not occur about half the
time. The other @Inject we use (injecting a ValidatorFactory into a custom
ActionValidatorManager configured by struts.actionValidatorManager in
struts.xml) is still always working. There are no log messages at any log
level that indicate a problem. The container successfully creates the custom
type converter bean as evidenced by the log message
java.util.List:com.candyland.web.converters.CandylandCollectionConverter
[treated as TypeConverter
com.candyland.web.converters.CandylandCollectionConverter@245f96b0].
Is it possible that this problem occurs because the getDeclaredMethods
method in Java 7 no longer returns methods in a consistent order
(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7023180)?. Per
https://groups.google.com/forum/#!topic/google-guice/rQD5L2O-Po8, this
causes Guice to inject objects in an inconsistent order so presumably the
Struts container would do the same, but I don't know if that would have any
negative effects.
This is strange ... as @Inject is used all over the framework and works fine.
This is the relevant code:
xwork-conversion.properties:
java.util.List=com.candyland.web.converters.CandylandCollectionConverter
...
CandylandCollectionConverter.java:
public class CandylandCollectionConverter extends
XWorkBasicConverter {
private ObjectTypeDeterminer objectTypeDeterminer;
@Inject
public void setObjectTypeDeterminer(ObjectTypeDeterminer
det) {
this.objectTypeDeterminer = det;
super.setObjectTypeDeterminer(det);
}
...
}
As a workaround, we lazily get the DefaultObjectTypeDeterminer by calling
Dispatcher.getInstance().getContainer().getInstance(ObjectTypeDeterminer.cla
ss). This seems to be a reasonable workaround, but is there a way to fix the
injection?
Maybe direct reference to Container would be better solution? And then
lazy obtain reference to ObjectTypeDeterminer?
@Inject
public void setContainer(Container container) {
objectTypeDeterminer = container.getInstance(ObjectTypeDeterminer.class);
}
I think the problem is in setter overriding.
What version of Struts do you use? Sometime ago I have split
XWorkBasicConverter into bunch of small converters which you can
re-implement and redeclare. Or maybe instead inheritance you can use
composition?
public class CandylandCollectionConverter implements TypeConverter {
@Inject
XWorkBasicConverter
@Inject
ObjectTypeDeterminer
}
I don't think the setter overridding is the problem because I have also tried
injecting into a different method (setObjectTypeDeterminerOverride) which
didn't work either. Injecting the container doesn't work either because all
injections into CandylandCollectionConverter are skipped (I have already tried
injecting an ObjectFactory, ReflectionProvider, and a XWorkConverter). I also
have already tried composition although the containing converter still
inherited from XWorkBasicConverter.
I'm using Struts 2.3.1.2 so I don't have your WW-3762 change in 2.3.3 that
split XWorkBasicConverter into smaller converters. But we are planning to
upgrade to the latest version soon so I will try that then.
Is our current workaround which lazily calls
Dispatcher.getInstance().getContainer().getInstance(ObjectTypeDeterminer.class)
a reasonable long-term solution?
Martin, I know the Struts DI container is not Guice, but it is based on an old
version of Guice which is why I suspected that Java 7 change could be related.
--
Patrick
-
To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org