You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Philip Martin <ph...@wandisco.com> on 2015/10/22 22:05:23 UTC
Binary incompatibility in JavaHL runtime version check
JavaHL uses JNI to load Subversion shared libraries and it includes a
runtime version check to ensure that the loaded library is the right
version. A program built with 1.8 would report an error if it loaded
1.7 at runtime. It seems we have introduced a binary incompatibility in
1.9 that causes the JVM to SEGV rather than report an error.
A simple Java program:
$ cat xx.java
import org.apache.subversion.javahl.*;
public class xx {
public static void main(String argv[]) {
System.out.println("hello");
ISVNRepos repos = new SVNRepos();
}
};
Build with 1.8 and run with 1.7:
$ javac -g -extdirs /usr/local/subversion-1.8/lib/svn-javahl xx.java
$ java -Djava.library.path=/usr/local/subversion-1.7/lib -cp /usr/local/subversion-1.8/lib/svn-javahl/svn-javahl.jar:. xx
hello
Exception in thread "main" java.lang.LinkageError: Native library version must be at least 1.8.0, but is only 1.7.23-dev (under development)
at org.apache.subversion.javahl.NativeResources.init(NativeResources.java:136)
at org.apache.subversion.javahl.NativeResources.loadNativeLibrary(NativeResources.java:99)
at org.apache.subversion.javahl.SVNRepos.<clinit>(SVNRepos.java:46)
at xx.main(xx.java:5)
Build with 1.9 and run with 1.8:
$ javac -g -extdirs /usr/local/subversion/lib/svn-javahl xx.java
$ java -Djava.library.path=/usr/local/subversion-1.8/lib -cp /usr/local/subversion/lib/svn-javahl/svn-javahl.jar:. xx
hello
Aborted
The stack trace shows:
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libapr-1.so.0+0x27b54] apr_threadkey_private_get+0x4
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.apache.subversion.javahl.types.Version.getMajor()I+0
j org.apache.subversion.javahl.types.Version.isAtLeast(III)Z+1
j org.apache.subversion.javahl.NativeResources.init()V+17
j org.apache.subversion.javahl.NativeResources.loadNativeLibrary()V+71
j org.apache.subversion.javahl.types.Version.<clinit>()V+0
--
Philip Martin
WANdisco
Re: Binary incompatibility in JavaHL runtime version check
Posted by Philip Martin <ph...@wandisco.com>.
Branko Čibej <br...@apache.org> writes:
> Try again with 1710104? It should be a trivial backport to 1.9.x, too.
Yes, that works and now gives the correct error:
Exception in thread "main" java.lang.LinkageError: Native library version must be at least 1.10.0, but is only 1.8.15-dev (under development)
--
Philip Martin
WANdisco
Re: Binary incompatibility in JavaHL runtime version check
Posted by Branko Čibej <br...@apache.org>.
On 22.10.2015 22:58, Branko Čibej wrote:
> On 22.10.2015 22:05, Philip Martin wrote:
>> JavaHL uses JNI to load Subversion shared libraries and it includes a
>> runtime version check to ensure that the loaded library is the right
>> version. A program built with 1.8 would report an error if it loaded
>> 1.7 at runtime. It seems we have introduced a binary incompatibility in
>> 1.9 that causes the JVM to SEGV rather than report an error.
>>
>> A simple Java program:
>>
>> $ cat xx.java
>> import org.apache.subversion.javahl.*;
>> public class xx {
>> public static void main(String argv[]) {
>> System.out.println("hello");
>> ISVNRepos repos = new SVNRepos();
>> }
>> };
>>
>> Build with 1.8 and run with 1.7:
>>
>> $ javac -g -extdirs /usr/local/subversion-1.8/lib/svn-javahl xx.java
>> $ java -Djava.library.path=/usr/local/subversion-1.7/lib -cp /usr/local/subversion-1.8/lib/svn-javahl/svn-javahl.jar:. xx
>> hello
>> Exception in thread "main" java.lang.LinkageError: Native library version must be at least 1.8.0, but is only 1.7.23-dev (under development)
>> at org.apache.subversion.javahl.NativeResources.init(NativeResources.java:136)
>> at org.apache.subversion.javahl.NativeResources.loadNativeLibrary(NativeResources.java:99)
>> at org.apache.subversion.javahl.SVNRepos.<clinit>(SVNRepos.java:46)
>> at xx.main(xx.java:5)
>>
>> Build with 1.9 and run with 1.8:
>>
>> $ javac -g -extdirs /usr/local/subversion/lib/svn-javahl xx.java
>> $ java -Djava.library.path=/usr/local/subversion-1.8/lib -cp /usr/local/subversion/lib/svn-javahl/svn-javahl.jar:. xx
>> hello
>> Aborted
>>
>> The stack trace shows:
>>
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
>> C [libapr-1.so.0+0x27b54] apr_threadkey_private_get+0x4
> I removed JNIThreadData.h/.cpp in r1533804, that's where the
> thread-private keys were used. The thread-specific data was no longer
> needed, because in 1.9 we have a guaranteed single-threaded context for
> initializing the native libraries.
>
> But I don't think this can be the source of the issue ... looking ...
>
> Ah, I think I have it ... I also removed
>
> private static native void initNativeLibrary();
>
> which is called from NativeResources.init in 1.8 and isn't called at all
> (of course) in 1.9. Oh sheesh.
>
> I'll fix this; it's a trivial matter of resurrecting a deleted file and
> making the function no-op.
>
Try again with 1710104? It should be a trivial backport to 1.9.x, too.
-- Brane
Re: Binary incompatibility in JavaHL runtime version check
Posted by Branko Čibej <br...@apache.org>.
On 22.10.2015 22:05, Philip Martin wrote:
> JavaHL uses JNI to load Subversion shared libraries and it includes a
> runtime version check to ensure that the loaded library is the right
> version. A program built with 1.8 would report an error if it loaded
> 1.7 at runtime. It seems we have introduced a binary incompatibility in
> 1.9 that causes the JVM to SEGV rather than report an error.
>
> A simple Java program:
>
> $ cat xx.java
> import org.apache.subversion.javahl.*;
> public class xx {
> public static void main(String argv[]) {
> System.out.println("hello");
> ISVNRepos repos = new SVNRepos();
> }
> };
>
> Build with 1.8 and run with 1.7:
>
> $ javac -g -extdirs /usr/local/subversion-1.8/lib/svn-javahl xx.java
> $ java -Djava.library.path=/usr/local/subversion-1.7/lib -cp /usr/local/subversion-1.8/lib/svn-javahl/svn-javahl.jar:. xx
> hello
> Exception in thread "main" java.lang.LinkageError: Native library version must be at least 1.8.0, but is only 1.7.23-dev (under development)
> at org.apache.subversion.javahl.NativeResources.init(NativeResources.java:136)
> at org.apache.subversion.javahl.NativeResources.loadNativeLibrary(NativeResources.java:99)
> at org.apache.subversion.javahl.SVNRepos.<clinit>(SVNRepos.java:46)
> at xx.main(xx.java:5)
>
> Build with 1.9 and run with 1.8:
>
> $ javac -g -extdirs /usr/local/subversion/lib/svn-javahl xx.java
> $ java -Djava.library.path=/usr/local/subversion-1.8/lib -cp /usr/local/subversion/lib/svn-javahl/svn-javahl.jar:. xx
> hello
> Aborted
>
> The stack trace shows:
>
> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
> C [libapr-1.so.0+0x27b54] apr_threadkey_private_get+0x4
I removed JNIThreadData.h/.cpp in r1533804, that's where the
thread-private keys were used. The thread-specific data was no longer
needed, because in 1.9 we have a guaranteed single-threaded context for
initializing the native libraries.
But I don't think this can be the source of the issue ... looking ...
Ah, I think I have it ... I also removed
private static native void initNativeLibrary();
which is called from NativeResources.init in 1.8 and isn't called at all
(of course) in 1.9. Oh sheesh.
I'll fix this; it's a trivial matter of resurrecting a deleted file and
making the function no-op.
-- Brane