This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: kawa 1.14 causes java.lang.IllegalAccessException
- From: Per Bothner <per at bothner dot com>
- To: Ito Kazumitsu <kaz at maczuka dot gcd dot org>
- Cc: "kawa at sourceware dot org" <kawa at sourceware dot org>
- Date: Mon, 07 Oct 2013 10:16:49 -0700
- Subject: Re: kawa 1.14 causes java.lang.IllegalAccessException
- Authentication-results: sourceware.org; auth=none
- References: <20131007 dot 163602 dot 155917228 dot kaz at maczuka dot gcd dot org>
On 10/07/2013 12:36 AM, Ito Kazumitsu wrote:
Could you explain this phenomenon?
$ java -cp kawa-1.13.jar kawa.repl test.scm
abc
$ java -cp kawa-1.13.jar kawa.repl --script test.scm
test.scm:2:1: warning - no known slot 'append' in java.lang.Object
test.scm:3:1: warning - no known slot 'setLength' in java.lang.Object
abc
This part is easy to explain: In the first case, test.scm is
processed in "whole-module mode" - the entire file is read and
processed as a unit. Therefore the Kawa compiler knows that sb
has no other assignments except the initial 'define', so Kawa can
easily infer the type to be java.lang.StringBuilder.
When using the --script flag (or the -f flag) then test.scm is
processed in "line-at-a-time mode". Each command is individually
read, analyzed, and executed. In that case the Kawa compiler
can't know there won't be later:
(set! sb "foo")
Therefore Kawa has to defer method resolution until runtime,
and call the method using runtime reflection.
True, when it comes to the calls to append and setLength is it
easy to see that sb must still have its initial value and type.
But what if the call to append is inside a function - which might
get called after sb has been re-assigned? It becomes compliucated,
especially if also want to handle loops, which are inlined function
calls.
Two ways to fix the problem (not counting using whole-module mode):
(1) Specify that sb is constant:
(define-constant sb (java.lang.StringBuilder))
(2) Specify an explicit type:
(define sb ::java.lang.StringBuilder (java.lang.StringBuilder))
Even if we're using run-time reflection, we shouldn't be getting
the IllegalAccessException. The problem is that setLength is actually
defined in AbstractStringBuilder, which is a package-private superclass
to both StringBuilder and StringBuffer. I'm not clear on how to avoid
the problem, but I'll dig into it. Even more puzzling is what changed
between 1.13 and 1.14 to break it.
--
--Per Bothner
per@bothner.com http://per.bothner.com/