JNI incorrect conversion of C long to Java long (aka Re: SableVM on ARM fails to run HelloWorld)

Chris Develder <[email protected]> Tue, 29 Nov 2005 18:44:23 +0100
Newsgroups gmane.comp.java.vm.sablevm.general
Message-ID <[email protected]>
The root cause of getting sablevm-1.12 working on our ARM device seems 
to be that a long value in C is not converted correctly to a Java long 
(via a JNI jlong, ie. a C long long).

I verified that Java_java_io_VMFile_length 
(sablevm-classpath-1.12/native/jni/java-io/java_io_VMFile.c) correctly 
reads the file length as a long (794 for my HelloWorld.class). But 
conversion to jlong (defined in jni_md.h as long long) seems to go 
wrong: when inspecting the value in File.length() 
(sablevm-classpath-1.12java/io/File.java), it turns out to be 0.

Thus, something seems to go wrong when passing the long long from C to a 
Java long through JNI... Any suggestions?

- Chris

Chris Develder wrote:
> The class loader _is_ looking in the current directory (as I said, this 
> was obvious from strace'ing).
> 
> The difference between putting the file in the sablevm-classpath and 
> some other working dir is indeed that in the latter case, the class 
> loading is initiated by java.lang.ClassLoader.loadClass rather than the 
> bootstrap class loader directly.
> 
> By debugging I noticed that in 
> sablevm-classpath-1.12/java/net/URLClassLoader.java, the FileResource 
> that is created at the beginning of URLClassLoader.findClass returns a 
> resource.getLength() == 0. Which I think is not what to expect (this 
> length == 0 results in the failure of _svmh_parse_class_file (in 
> sablevm-1.12/src/libsablevm/class_file_parser.c).
> 
> Adding System.out.println statements, I found that File.length() does 
> not produce the same result when called upon multiple times.
> I ended up trying to verify VMFile.length(), but printf() statements in 
> sablevm-classpath-1.12/native/jni/java-io/java_io_VMFile.c resulted in 
> segfaults...
> 
> - Chris
> 
> Etienne Gagnon wrote:
> 
>> Hi Chris,
>>
>> OK, so this confirms that the problem is class-library related.  The
>> internal bootstrap class loader seems to be working fine.  This can
>> greatly simplify your search for the bug.
>>
>> For one thing, it seems that the System class loader is either:
>> 1- not working at all, or
>> 2- not looking in the current directory.
>>
>> I suspect that "1-" is the case, here.  By putting the file in
>> <install-dir>/share/sablevm-classpath, the class was probably loaded by
>> the bootstrap class loader (i.e. sablevm's internal class loader).
>>
>> You should start your investigation at
>> ClassLoader.defaultGetSystemClassLoader() in sablevm-classpath.
>>
>> As this happens out of the bootstrap cycle, you can probably add
>> "System.out.println()" statements to track down execution without
>> hitting chicken-egg bootstrap problems.  In last resort, SableVM
>> provides java.lang package-specific VirualMachine.println() statements
>> which require no bootstrap support.
>>
>> Have fun!
>>
>> Etienne
>>
>>
>>
>> Chris Develder wrote:
>>
>>> I found that copying the HelloWorld.class file to
>>> <install-dir>/share/sablevm-classpath (alongside the jars) makes
>>> 'sablevm HelloWorld' work.
>>>
>>> This lead me to believe that the current working directory was not
>>> checked when looking for HelloWorld.class. Yet, without the .class file
>>> in <install-dir>/share/sablevm-classpath, I did find (using strace) that
>>> the file in the pwd was looked for and opened... But then the
>>> java.lang.ClassFormatError occurs.
>>>
>>> Apparently files in the classpath and pwd are not treated in the same 
>>> way?
>>>
>>>
>>>> Can you check what happens when mmap() is used to read the class file
>>>> insrc/libsablevm/class_loader.c (or src/libsablevm/zip_file_reader.c).
>>>
>>>
>>> As for mmap: I added printfs before all mmap calls, but they were never
>>> reached.  I did notice failing open() calls using strace, where attempts
>>> are made to acces files that are actually in the jars in the classpath.
>>> (Making/installing sablevm-classpath uncompressed makes the open() calls
>>> work)  I guess that it is normal that in case of sablevm-classpath with
>>> compressed classfiles _svmf_bootcl_internal_load_ondisk_class_file is
>>> called and fails (for the .class files are in the jar)?
>>
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> SableVM-user mailing list
>> [email protected]
>> http://sablevm.org/lists/control/listinfo/sablevm-user
> 
>