WELD-862 and Seam Cron
by Peter Royle
Hi,
I'm aiming to make a release of Seam Cron available within the next two weeks. Currently there is an outstanding issue (https://issues.jboss.org/browse/WELD-862) which prevents Cron from running properly with Weld. I have been able to carry on developing Cron by testing it against OpenWebBeans, but obviously if we are to release a Seam module it should work against Weld.
It would be nice if WELD-862 could be fixed as soon a possible so that all future versions will work well with Cron.
But more importantly I also probably need to do something special in Cron so that it will work with the version of Weld already deployed in JBoss AS and Glassfish, which will contain the bug. The workaround mentioned in the bug report is to deep copy the InvocationContext. I attempted to do this by serialising and unserialising the InvocationContext but couldn't due to UnserializableExceptions. Does anyone have any advice for me about how I might be able to work around this bug to support existing versions of Weld?
Cheers,
Pete R
3 days, 12 hours
ProxyFactory#getProxyName() question
by Laird Nelson
Hello; it's me again, deep/close reading ProxyFactory.java to understand
everything I can about proxies in Weld.
I think the proxy name produced by getProxyName() is based on the (quite
possibly indeterminate) ordering of the Set of types that happens to be
passed to it. This would mean that even subsequent calls to this method
with the same Set might yield different and surprising results. Is this
correct?
For example, in a test that I wrote to further understand how proxy names
are constructed:
final Method getProxyName =
ProxyFactory.class.getDeclaredMethod("getProxyName", String.class,
Class.class, Set.class, Bean.class);
getProxyName.setAccessible(true);
final Set<Type> typeSet = new LinkedHashSet<>();
// Let's add two disparate interfaces in an arbitrary, but predictable,
order.
typeSet.add(Serializable.class);
typeSet.add(Cloneable.class);
final String proxyName = (String)getProxyName.invoke(null, null,
Object.class, typeSet, null);
assertEquals("java.io.Cloneable$Serializable$$Proxy$", proxyName); // ?!
Whoa. Not what I expected.
proxyName contains "java.io.Cloneable$Serializable$$Proxy$". Is that by
design? Or is the "java.io.Cloneable" part a mistake?
And are the double dollar signs ($$) in this case intentional as well?
(There are certainly paths through this method that won't result in double
dollar signs, so I'm not sure if this is a bug or a feature.) To my eyes,
this is suspicious:
https://github.com/weld/core/blob/10a1d11af8c815a2a4a8fc5a4061698215e602b...
Shouldn't that happen only if there aren't any more interface names to
add? So are the two dollar signs just a symptom of a bug?
By contrast, in case it matters, my naïve expectation, following what seems
to me the intended logic of the method, would have been for proxyName to
contain "java.lang.Cloneable$Serializable$Proxy$".
Best,
Laird
5 years, 10 months
Proxies.TypeInfo.getSuperInterface() question
by Laird Nelson
I am reading Weld code to understand deeply how proxies work.
While doing this, I ran across the Proxies.TypeInfo class. It has a method
called getSuperInterface().
This method iterates over a set of interfaces and selects the most specific
one (somewhat surprisingly to me; I would have expected the most general
one).
The method is very short so here it is in its entirety, reformatted:
public Class<?> getSuperInterface() {
if (interfaces.isEmpty()) {
return null;
}
Iterator<Class<?>> it = interfaces.iterator();
Class<?> superclass = it.next();
while (it.hasNext()) {
Class<?> clazz = it.next();
if (superclass.isAssignableFrom(clazz)) { // XXX Is this backwards?
superclass = clazz;
}
}
return superclass;
}
For example, if there are exactly two interfaces in the set, Square.class
and Rectangle.class, and Square extends Rectangle, it would seem that
Square.class will be selected.
(My reading: Pretend Square.class is the first item in the iterator. It
gets assigned to superclass. Then clazz gets the next (and last) item,
Rectangle.class. Then we check to see if (effectively)
Square.class.isAssignableFrom(Rectangle.class), which will return false.
So superclass remains Square.class and is returned.
(Or pretend that Rectangle.class was the first item in the iterator. It
gets assigned to superclass. Then clazz gets Square.class. Then we check
to see if Rectangle.class.isAssignableFrom(Square.class), which returns true,
so superclass gets reassigned to Square.class, and is then returned. Hence
Square.class, the most *specific* subtype in the set, is returned in both
cases.)
The reason this surprised me is the name of this method implies that it
should select the most *general*, e.g. Rectangle.class in my example.
That's usually what "super" means.
See
https://github.com/weld/core/blob/10a1d11af8c815a2a4a8fc5a4061698215e602b...
.
Is that line "backwards"? Or is it just a badly-named method (should it
have been named getMostSpecificInterface())? Or…?
I understand this code is old and works and so my apologies if I'm being
stupid in some way. I just like to understand things.
Best,
Laird
5 years, 10 months