lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Carlos (and other interested parties),

Here is a potential bug that I found in LuaJava that I know how to 
workaround in Java2 but not with older versions of Java.  
Given the following code:

h = javaNewInstance("java.util.Hashtable")
h:put("0", "zero")
h:put("1", "one")
e = h:keys()
while(e:hasMoreElements()) do
	print(e:nextElement())
end

I get the following error under JDK1.1.8 and JDK1.2.2 (you can ignore
the Lua stack trace, BTW):

lua error: java.util.HashtableEnumerator.hasMoreElements:
java/util/HashtableEnumerator
Active Stack:
  (C code)
  main of file `badHash.lua' at line 5
  function `dofile' [(C code)]
  function <54:file `startup.lua'> at line 54
  function `foreachi' [(C code)]
  main of file `startup.lua' at line 54

Not very helpful, is it?  Under JDK1.3 I get the following:

lua error: java.util.Hashtable$Enumerator.hasMoreElements:
java.lang.IllegalAccessException
Active Stack:
  (C code)
  main of file `badHash.lua' at line 5
  function `dofile' [(C code)]
  function <54:file `startup.lua'> at line 54
  function `foreachi' [(C code)]
  main of file `startup.lua' at line 54

Which is a bit more helpful.  It looks like the problem is that we 
cannot call the hasMoreElements() method using the invoke() method
provided by the Method reflection class.  The problem seems to be 
that, while the method is public, the Enumeration implementation 
class is private to the Hashtable class and Java won't let one invoke 
a method in a private class via the Method object.  

This problem is evident even in simple Java-only programs (doing
the same thing).  

This may be a Java bug, I am not sure.  In any case, using Java2,
I have found a workaround.  We can make the following changes in 
lua/ToLua.java (from 2.10 release):

// Insert BEFORE line 698 which reads
// Object result = last_used_method.invoke(obj,params);
		  int modifiers = last_used_method.getModifiers();
		  if (Modifier.isPublic(modifiers))
			  last_used_method.setAccessible(true);

This makes the method accessible.  The check for a public modifier
is to ensure that LuaJava doesn't allow one to call private, protected,
or package methods.  The only problem is that the setAccessible()
method is not available prior to Java2.

With this change, I see the following output (using JDK1.2.2 or 1.3):

1
0

I don't know how to fix this for JDK1.1.  If the workaround is used,
it may be desirable to check the version before calling the method.
At least then the behaviour won't change (to the inability to find a
setAccessible method).

ajk

-- 
Aaron Kamienski <aaronk@snaptwo.com>
SNAP2 Corporation