ModifierInfo: enum or interface?
flavia.rainone Oct 8, 2009 6:39 PMWhen running the deployers-vfs tests against the trunk version of jboss-reflect, I stumbled accross a few failures related to ModifierInfo class.
It looks like those failures were introduced when ModifierInfo interface was transformed into an enum:
http://www.jboss.org/index.html?module=bb&op=viewtopic&t=148169&postdays=0&postorder=asc&start=30
At first, I also thought it was a good idea making ModifierInfo an enum, but now I'm not so sure. The first point is that it implies in creating a single instance of every possible combination of modifiers, and the current version of ModifierInfo lacks several of them (for example, PUBLIC_STATIC_FINAL).
Apart from that, another problem I found was that the method ModifierInfo.getNewModifier looks for an instance with the same number as the parameter modifiers:
public static ModifierInfo getNewModifier(int modifiers) { for(ModifierInfo modifier : values()) if(modifier.getModifiers() == modifiers) return modifier; throw new RuntimeException("Couldnt find Modifier for: "+modifiers); }
The problem is that sometimes the JVM (sun jdk1.6) returns numbers such as 4101, which represent the static modifier only, and are different from the modifiers value contained in the instance Modifier.STATIC, which is 1. So, when I ran accross this kind of failure, I fixed the method above, making it check against every possible modifier and building the expected equivalent modifier value:
int m = 0; if (Modifier.isStatic(modifiers)) { m += Modifier.STATIC; } if (Modifier.isAbstract(modifiers)) { m += Modifier.ABSTRACT; } if (Modifier.isFinal(modifiers)) { m += Modifier.FINAL; } if (Modifier.isInterface(modifiers)) { m += Modifier.INTERFACE; } if (Modifier.isNative(modifiers)) { m += Modifier.NATIVE; } if (Modifier.isPrivate(modifiers)) { m += Modifier.PRIVATE; } if (Modifier.isProtected(modifiers)) { m += Modifier.PROTECTED; } if (Modifier.isPublic(modifiers)) { m += Modifier.PUBLIC; } if (Modifier.isStrict(modifiers)) { m += Modifier.STRICT; } if (Modifier.isSynchronized(modifiers)) { m += Modifier.SYNCHRONIZED; } if (Modifier.isTransient(modifiers)) { m += Modifier.TRANSIENT; } if (Modifier.isVolatile(modifiers)) { m += Modifier.VOLATILE; } for(ModifierInfo modifier : values()) if(modifier.getModifiers() == m) return modifier;
IMO, that fix doesn't look very nice, and if you call MethodInfo.getModifiers().getModifers() the value you end up with may be different from the original modifiers (take, for example, the case of 4101 vs. 1 I mentioned previously). I don't know if this is an issue, but it breaks several test checks.
Even with all those fixes, I'm getting failures now on deployers-vfs tests like the one below:
Caused by: java.lang.NoSuchMethodError: org.jboss.reflect.spi.ClassInfo.getModifiers()I at org.jboss.xb.builder.runtime.CollectionPropertyHandler.<init>(CollectionPropertyHandler.java:72) at org.jboss.xb.builder.runtime.CollectionPropertyWildcardHandler.<init>(CollectionPropertyWildcardHandler.java:51) at org.jboss.xb.builder.JBossXBNoSchemaBuilder.generateType(JBossXBNoSchemaBuilder.java:1164)
Before I try to fix it, I need to know if we are going to stick with ModifierInfo enum or with ModifierInfo interface.
So, Ales, any ideas?