languagetool icon indicating copy to clipboard operation
languagetool copied to clipboard

Unable to run the LanguageTool Server on arm64

Open iMonZ opened this issue 3 years ago • 17 comments

The LanguageTool Server is checking for a 64bit x86 machine which at the end means that it's unable to run on 64bit arm devices!

Using the LanguageTool Server with this docker image: erikvl87/LanguageTool

The following configuration is passed to LanguageTool:
pipelinePrewarming=true 
+ java -Xms1g -Xmx2g -cp languagetool-server.jar org.languagetool.server.HTTPServer --port 8010 --public --allow-origin '*' --config config.properties
2021-03-04 09:17:56 +0000 INFO  org.languagetool.server.DatabaseAccess Not setting up database access, dbDriver is not configured
2021-03-04 09:17:56 +0000 WARNING: running in HTTP mode, consider running LanguageTool behind a reverse proxy that takes care of encryption (HTTPS)
2021-03-04 09:17:56 +0000 WARNING: running in public mode, LanguageTool API can be accessed without restrictions!
2021-03-04 09:17:58 +0000 INFO  org.languagetool.server.TextChecker Prewarming pipelines...
java.lang.RuntimeException: Failed to initialize BridJ (java.lang.UnsatisfiedLinkError: /tmp/BridJExtractedLibraries8644161130760227625/libbridj.so: Error relocating /tmp/BridJExtractedLibraries
8644161130760227625/libbridj.so: unsupported relocation type 7 (Possible cause: can't load AMD 64-bit .so on a AARCH64-bit platform))
        at org.bridj.Platform.initLibrary(Platform.java:444)
        at org.bridj.Platform.<clinit>(Platform.java:228)
        at org.bridj.Pointer.<clinit>(Pointer.java:208)
        at org.languagetool.rules.spelling.hunspell.Hunspell.<init>(Hunspell.java:43)
        at org.languagetool.rules.spelling.hunspell.Hunspell.getInstance(Hunspell.java:62)
        at org.languagetool.rules.spelling.hunspell.HunspellRule.init(HunspellRule.java:368)
        at org.languagetool.rules.de.GermanSpellerRule.init(GermanSpellerRule.java:1065)
        at org.languagetool.rules.spelling.hunspell.HunspellRule.ensureInitialized(HunspellRule.java:342)
        at org.languagetool.rules.spelling.hunspell.HunspellRule.match(HunspellRule.java:122)
        at org.languagetool.JLanguageTool.checkAnalyzedSentence(JLanguageTool.java:1255)
        at org.languagetool.JLanguageTool$TextCheckCallable.getOtherRuleMatches(JLanguageTool.java:1803)
        at org.languagetool.JLanguageTool$TextCheckCallable.call(JLanguageTool.java:1724)
        at org.languagetool.JLanguageTool$TextCheckCallable.call(JLanguageTool.java:1696)
        at org.languagetool.JLanguageTool.performCheck(JLanguageTool.java:1182)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:930)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:884)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:871)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:861)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:843)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:800)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:784)
      at org.languagetool.server.TextChecker.prewarmPipelinePool(TextChecker.java:183)
        at org.languagetool.server.TextChecker.<init>(TextChecker.java:136)
        at org.languagetool.server.V2TextChecker.<init>(V2TextChecker.java:44)
        at org.languagetool.server.LanguageToolHttpHandler.<init>(LanguageToolHttpHandler.java:74)
        at org.languagetool.server.HTTPServer.<init>(HTTPServer.java:105)
        at org.languagetool.server.HTTPServer.main(HTTPServer.java:147)
Caused by: java.lang.UnsatisfiedLinkError: /tmp/BridJExtractedLibraries8644161130760227625/libbridj.so: Error relocating /tmp/BridJExtractedLibraries8644161130760227625/libbridj.so: unsupported relocation type 7 (Possible cause: can't load AMD 64-bit .so on a AARCH64-bit platform)
        at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
        at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)
        at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2498)
        at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2694)
        at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2627)
        at java.base/java.lang.Runtime.load0(Runtime.java:768)
        at java.base/java.lang.System.load(System.java:1837)
        at org.bridj.Platform.initLibrary(Platform.java:420)
        ... 26 more
Exception in thread "main" java.lang.RuntimeException: Could not start LanguageTool HTTP server on localhost, port 8010
        at org.languagetool.server.HTTPServer.main(HTTPServer.java:153)
Caused by: org.languagetool.server.PortBindingException: LanguageTool HTTP server could not be started on host "null", port 8010.
Maybe something else is running on that port already?
        at org.languagetool.server.HTTPServer.<init>(HTTPServer.java:119)
        at org.languagetool.server.HTTPServer.main(HTTPServer.java:147)
Caused by: java.lang.RuntimeException: Error while prewarming pipelines
        at org.languagetool.server.TextChecker.prewarmPipelinePool(TextChecker.java:191)
        at org.languagetool.server.TextChecker.<init>(TextChecker.java:136)
        at org.languagetool.server.V2TextChecker.<init>(V2TextChecker.java:44)
        at org.languagetool.server.LanguageToolHttpHandler.<init>(LanguageToolHttpHandler.java:74)
        at org.languagetool.server.HTTPServer.<init>(HTTPServer.java:105)
        ... 1 more
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: Could not check sentence (language: German (Germany)): <sentcontent>LanguageTool</sentcontent>
        at org.languagetool.JLanguageTool.performCheck(JLanguageTool.java:1186)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:930)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:884)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:871)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:861)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:843)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:800)
        at org.languagetool.JLanguageTool.check(JLanguageTool.java:784)
        at org.languagetool.server.TextChecker.prewarmPipelinePool(TextChecker.java:183)
        ... 5 more
Caused by: java.lang.RuntimeException: Could not check sentence (language: German (Germany)): <sentcontent>LanguageTool</sentcontent>
        at org.languagetool.JLanguageTool$TextCheckCallable.getOtherRuleMatches(JLanguageTool.java:1830)
        at org.languagetool.JLanguageTool$TextCheckCallable.call(JLanguageTool.java:1724)
        at org.languagetool.JLanguageTool$TextCheckCallable.call(JLanguageTool.java:1696)
        at org.languagetool.JLanguageTool.performCheck(JLanguageTool.java:1182)
        ... 13 more
Caused by: java.lang.RuntimeException: Could not create hunspell instance. Please note that LanguageTool supports only 64-bit platforms (Linux, Windows, Mac) and that it requires a 64-bit JVM (Java).
        at org.languagetool.rules.spelling.hunspell.Hunspell.<init>(Hunspell.java:51)
        at org.languagetool.rules.spelling.hunspell.Hunspell.getInstance(Hunspell.java:62)
        at org.languagetool.rules.spelling.hunspell.HunspellRule.init(HunspellRule.java:368)
        at org.languagetool.rules.de.GermanSpellerRule.init(GermanSpellerRule.java:1065)
        at org.languagetool.rules.spelling.hunspell.HunspellRule.ensureInitialized(HunspellRule.java:342)
        at org.languagetool.rules.spelling.hunspell.HunspellRule.match(HunspellRule.java:122)
        at org.languagetool.JLanguageTool.checkAnalyzedSentence(JLanguageTool.java:1255)
        at org.languagetool.JLanguageTool$TextCheckCallable.getOtherRuleMatches(JLanguageTool.java:1803)
        ... 16 more
Caused by: java.lang.UnsatisfiedLinkError: 'int org.bridj.Platform.sizeOf_ptrdiff_t()'
        at org.bridj.Platform.sizeOf_ptrdiff_t(Native Method)
        at org.bridj.Platform.<clinit>(Platform.java:232)
        at org.bridj.Pointer.<clinit>(Pointer.java:208)
        at org.languagetool.rules.spelling.hunspell.Hunspell.<init>(Hunspell.java:43)
        ... 23 more

iMonZ avatar Mar 04 '21 09:03 iMonZ

I have a languagetool server running on my Raspberry Pi (arm64). It took some effort to get it running.

I'm using the standalone version distributed via https://dev.languagetool.org/http-server and I'm currently using the 5.2 version (not upgraded to 5.3 yet).

The gist is that there are two libraries that are not compiled with arm architectures:

  • libs/hunspell.jar
  • libs/bridj.har

hunspell is easy to replace since there will usually be a version compiled for arm64 for your distribution. You could, e.g., visit https://packages.debian.org/search?keywords=hunspell and download the package and take the hunspell.jar from there.

bridj.jar is harder, because https://github.com/nativelibs4java/BridJ seems abandoned or has at least no arm64 build. So you need to do it yourself. This is also the part where I am not so sure what I have done to get it compiled.

This is my git status: https://gist.github.com/eseiler/45d2c6447d3e1a1c72adb17337cf9549 This is my git diff: https://gist.github.com/eseiler/98490dc05e39c36abedec64d4e50e9ae

I remember the changes in BuildNative and pom.xml being important, and I think the rest happens through some build scripts. I also downloaded an up-to-date and arm64 compatible version of dyncall and put it into the dyncall directory.

After reading the license of BridJ, I'm apparently allowed to distribute the binary as long as I include the license file, so here you go: bridj_arm64.tar.gz

eseiler avatar Apr 01 '21 14:04 eseiler

After salvaging my bash history, I figured out how to compile it again. You'll need maven and java JDK.

export JAVA_HOME=/usr/lib/jvm/java-1.14.0-openjdk-arm64 # adjust the path

git clone https://github.com/nativelibs4java/BridJ
cd BridJ
# apply patch https://gist.github.com/eseiler/215a8ac37c512f7120345e2bb875b3b9
wget https://dyncall.org/r1.1/dyncall-1.1.tar.gz
tar xf dyncall-1.1.tar.gz
rm dyncall-1.1.tar.gz
mv dyncall-1.1 dyncall
./BuildNative
mvn clean install -DskipTests -Dmaven.install.skip=true -e

This will build some stuff, next you can verify that something for arm64 was built:

jar tf target/bridj-0.7.1-SNAPSHOT.jar | grep so # Expecting org/bridj/lib/linux_aarch64/libbridj.so

Because languagetool (?) will look in the linux_x64 folder for the object file, we need to put the one for arm64 there:

mkdir rezip
cd rezip/
cp ../target/bridj-0.7.1-SNAPSHOT.jar .
unzip bridj-0.7.1-SNAPSHOT.jar
rm bridj-0.7.1-SNAPSHOT.jar
cd org/bridj/lib/
cp linux_aarch64/libbridj.so linux_x64/
cd ../../..
zip -r bridj.jar META-INF/ org/

The resulting bridj.jar is the one that works with arm64 and languagetool.

Maybe some stuff could be simplified, e.g., patching the BuildNative to always return something like linux_x64 may make the last step obsolete?

eseiler avatar Apr 01 '21 14:04 eseiler

Is this something that should/could be fixed by LanguageTool? I would like to be able to get Erikvl87/docker-languagetool working on ARM64 devices: https://github.com/Erikvl87/docker-languagetool/issues/15

I was trying to include the workaround of @eseiler (thank you very much for the detailed explanation and steps) but unfortunately I couldn't get it to work on debian:buster with openjdk-11-jdk-headless installed. I am stuck at building bridj during the mvn clean install -DskipTests -Dmaven.install.skip=true -e command:

...
[DEBUG] -d /BridJ/target/classes -classpath /BridJ/target/classes:/root/.m2/repository/org/ow2/asm/asm/5.0.3/asm-5.0.3.jar:/root/.m2/repository/org/osgi/org.osgi.core/6.0.0/org.osgi.core-6.0.0.jar:/root/.m2/repository/com/google/android/android/4.1.1.4/android-4.1.1.4.jar:/root/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar:/root/.m2/repository/org/apache/httpcomponents/httpclient/4.0.1/httpclient-4.0.1.jar:/root/.m2/repository/org/apache/httpcomponents/httpcore/4.0.1/httpcore-4.0.1.jar:/root/.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar:/root/.m2/repository/org/khronos/opengl-api/gl1.1-android-2.1_r1/opengl-api-gl1.1-android-2.1_r1.jar:/root/.m2/repository/xerces/xmlParserAPIs/2.6.2/xmlParserAPIs-2.6.2.jar:/root/.m2/repository/xpp3/xpp3/1.1.4c/xpp3-1.1.4c.jar:/root/.m2/repository/org/json/json/20080701/json-20080701.jar:/root/.m2/repository/com/google/android/tools/dx/1.7/dx-1.7.jar: -sourcepath /BridJ/src/main/java:/BridJ/target/generated-sources/main:/BridJ/target/generated-sources/annotations: -O -g -nowarn -target 1.5 -source 1.5 -encoding UTF-8
[DEBUG] incrementalBuildHelper#beforeRebuildExecution
[INFO] Compiling 185 source files to /BridJ/target/classes
[DEBUG] incrementalBuildHelper#afterRebuildExecution
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] Source option 5 is no longer supported. Use 6 or later.
[ERROR] Target option 1.5 is no longer supported. Use 1.6 or later.
[INFO] 2 errors
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:28 min
[INFO] Finished at: 2021-04-19T20:36:53Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.2:compile (default-compile) on project bridj: Compilation failure: Compilation failure:
[ERROR] Source option 5 is no longer supported. Use 6 or later.
[ERROR] Target option 1.5 is no longer supported. Use 1.6 or later.
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.2:compile (default-compile) on project bridj: Compilation failure
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.maven.plugin.compiler.CompilationFailureException: Compilation failure
    at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute (AbstractCompilerMojo.java:909)
    at org.apache.maven.plugin.compiler.CompilerMojo.execute (CompilerMojo.java:129)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
The command '/bin/sh -c mvn clean install -DskipTests -Dmaven.install.skip=true -e -X' returned a non-zero code: 1

Erikvl87 avatar Apr 19 '21 20:04 Erikvl87

Did you apply the patch? https://gist.github.com/eseiler/215a8ac37c512f7120345e2bb875b3b9

It should set the versions to 1.8.

eseiler avatar Apr 19 '21 22:04 eseiler

Not sure how I missed that yesterday. That indeed solves the error above. Thank you @eseiler.

Erikvl87 avatar Apr 20 '21 06:04 Erikvl87

Is this something that should/could be fixed by LanguageTool? I would like to be able to get Erikvl87/docker-languagetool working on ARM64 devices: Erikvl87/docker-languagetool#15

I'm not familiar with the languagetool codebase, but I guess they could build bridj once by themselves for all the architectures they want to support. I'd figure this would involve editing the BuildNative from my patch to actually detect arm64 instead of just hardcoding it. License-wise it should be ok since they include bridj already anyway. The other thing that would need to be changed is that languagetool looks for linux_aarch64 instead of linux_x64 in the jar depending on the architecture - not familiar with how this infrastructure works though.

Adding the aarch64 hunspell should be relatively easy too since it is a common library in linux distributions.

With Apple also switching to arm CPUs it might be nice to support arm, though I never tried to run the server on macOS and do not know if it even works with amd64 macOS.

Not sure how I missed that yesterday. That indeed solves the error above. Thank you @eseiler.

It was just a comment in the script, so it's easy to miss :)

eseiler avatar Apr 20 '21 07:04 eseiler

Thank you! I've got the bridj.jar part working now. I am still struggling with extracting the hunspell.jar file though. Could you maybe also give me some pointers on how to do that?

Hopefully someone from the LanguageTool can step in and follow up on your proposal on how to support this architecture.

Erikvl87 avatar Apr 29 '21 07:04 Erikvl87

I did it like this, I don't know what the minimum requirement is (maybe you only need to do the x64 or the aarch64 folder).

I am assuming that the working directory is languagetool, i.e. the directory with languagetool.jar, etc.

# Any package manager, we need the libhunspell-1.7.a file, which is not contained in the downloadable .deb packages
sudo apt install libhunspell-dev

cd libs/
unzip hunspell.jar -d hunspell_jar
mkdir -p hunspell_jar/org/bridj/lib/linux_aarch64
cp /usr/lib/aarch64-linux-gnu/libhunspell* hunspell_jar/org/bridj/lib/linux_aarch64
cp /usr/lib/aarch64-linux-gnu/libhunspell* hunspell_jar/org/bridj/lib/linux_x64

cd hunspell_jar
zip -r hunspell.jar dumonts META-INF/ org/
cd ..
mv hunspell_jar/hunspell.jar .
rm -dr hunspell_jar

eseiler avatar Apr 29 '21 08:04 eseiler

Would be great to have a ready to use language-server.zip which runs on M1 aarch64 without using rosetta.

opensource21 avatar Nov 30 '21 10:11 opensource21

Would be great to have a ready to use language-server.zip which runs on M1 aarch64 without using rosetta.

I agree that this would be the best solution. If docker is an option, you could try https://github.com/Erikvl87/docker-languagetool

We managed to get the container working for arm64. Would be interesting to know whether it works on M1, too. Might be that the workarounds we use need a little tweaking for M1.

eseiler avatar Nov 30 '21 11:11 eseiler

@eseiler Didn't use Docker at the m1, but I think it would make the situation worse. The languagetool runs fine with rosetta and an x86-java-vm. If I switched to docker I must use rosetta too and have more emulating layers.

If it helps you if I try it with docker, I can put it on my todo-list

opensource21 avatar Nov 30 '21 14:11 opensource21

@opensource21 Thanks for offering! But if your setup works well, I don't see any reason to experiment with docker. After all, the docker image for arm64 is just a workaround for missing upstream support.

eseiler avatar Dec 02 '21 12:12 eseiler

I got LT server running on an Ondroid-N2 machine (arm64, 4 GB, Ubuntu 20.4) following the steps @eseiler described in the post above and using his bridj.jar (great work). It is a great possibility to run an LT server on a small private network. So, I think this possibility should be supported by LT. At least all necessary steps should be documented (e.g. at the LT wiki).

FredKruse avatar Feb 21 '22 09:02 FredKruse

+1

moabits avatar Apr 12 '22 07:04 moabits

After salvaging my bash history, I figured out how to compile it again. You'll need maven and java JDK.

export JAVA_HOME=/usr/lib/jvm/java-1.14.0-openjdk-arm64 # adjust the path

git clone https://github.com/nativelibs4java/BridJ
cd BridJ
# apply patch https://gist.github.com/eseiler/215a8ac37c512f7120345e2bb875b3b9
wget https://dyncall.org/r1.1/dyncall-1.1.tar.gz
tar xf dyncall-1.1.tar.gz
rm dyncall-1.1.tar.gz
mv dyncall-1.1 dyncall
./BuildNative
mvn clean install -DskipTests -Dmaven.install.skip=true -e

This will build some stuff, next you can verify that something for arm64 was built:

jar tf target/bridj-0.7.1-SNAPSHOT.jar | grep so # Expecting org/bridj/lib/linux_aarch64/libbridj.so

Because languagetool (?) will look in the linux_x64 folder for the object file, we need to put the one for arm64 there:

mkdir rezip
cd rezip/
cp ../target/bridj-0.7.1-SNAPSHOT.jar .
unzip bridj-0.7.1-SNAPSHOT.jar
rm bridj-0.7.1-SNAPSHOT.jar
cd org/bridj/lib/
cp linux_aarch64/libbridj.so linux_x64/
cd ../../..
zip -r bridj.jar META-INF/ org/

The resulting bridj.jar is the one that works with arm64 and languagetool.

Maybe some stuff could be simplified, e.g., patching the BuildNative to always return something like linux_x64 may make the last step obsolete?

Thank you, barely working. Building good at all. But on running:

# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
# BridJ: dlopen error when loading /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so : /opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so: cannot open shared object file:        No such file or directory
java.lang.RuntimeException: Library 'OpenIMAJGrabber' was not loaded successfully from file '/opt/qnet/dc/temp/BridJExtractedLibraries6128202369788510531/OpenIMAJGrabber.so'
        at org.bridj.BridJ.getNativeLibrary(BridJ.java:1079)
        at org.bridj.BridJ.getNativeLibrary(BridJ.java:1056)
        at org.bridj.BridJ.getNativeLibrary(BridJ.java:609)
        at org.bridj.cpp.CPPRuntime.newCPPInstance(CPPRuntime.java:780)
        at org.bridj.cpp.CPPRuntime$CPPTypeInfo.initialize(CPPRuntime.java:1031)
        at org.bridj.cpp.CPPRuntime$CPPTypeInfo.initialize(CPPRuntime.java:913)
        at org.bridj.CRuntime$CTypeInfo.initialize(CRuntime.java:279)
        at org.bridj.BridJ.initialize(BridJ.java:1135)
        at org.bridj.NativeObject.<init>(NativeObject.java:49)
        at org.bridj.StructObject.<init>(StructObject.java:46)
        at org.bridj.cpp.CPPObject.<init>(CPPObject.java:50)
        at com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber.<init>(OpenIMAJGrabber.java:64)
        at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver$WebcamNewGrabberTask.handle(WebcamDefaultDriver.java:55)
        at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.run(WebcamProcessor.java:81)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:750)

What im doing wrong?

0xD8C4A475 avatar Aug 03 '22 13:08 0xD8C4A475

Sorry to see so much pain around bridj + arm64. I've resumed some maintenance of the project and the latest snapshot should hopefully work (also, native build is being simplified)

ochafik avatar Nov 09 '22 00:11 ochafik

Some side notes on running hunspell / languagetool on linux ARM, here is my simple solution

Issue: Native library (linux-aarch64/libhunspell.so) not found in resource path

[com.sun.jna.NativeLibrary] (pool-7-thread-1) Looking for library 'hunspell'
[com.sun.jna.NativeLibrary] (pool-7-thread-1) Adding paths from jna.library.path: null
[com.sun.jna.NativeLibrary] (pool-7-thread-1) Trying libhunspell.so"
[com.sun.jna.NativeLibrary] (pool-7-thread-1) Loading failed with message: libhunspell.so: cannot open shared object file: No such file or directory
[com.sun.jna.NativeLibrary] (pool-7-thread-1) Adding system paths: [/usr/lib64, /lib64, /usr/lib, /lib]
[com.sun.jna.NativeLibrary] (pool-7-thread-1) Trying libhunspell.so
[com.sun.jna.NativeLibrary] (pool-7-thread-1) Loading failed with message: libhunspell.so: cannot open shared object file: No such file or directory
[com.sun.jna.NativeLibrary] (pool-7-thread-1) Looking for version variants
[com.sun.jna.Native] (pool-7-thread-1) Looking in classpath from io.quarkus.bootstrap.runner.RunnerClassLoader@2bfc268b for hunspell
[com.sun.jna.NativeLibrary] (pool-7-thread-1) Loading failed with message: Native library (linux-aarch64/libhunspell.so) not found in resource path (/deployments/quarkus-run.jar)

I tried to decompress hunspell-2.1.2.jar and confirmed it does not contain binary for linux-aarch64, only support darwin-aarch64 (mac M1 arm)

# unzip com.gitlab.dumonts.hunspell-2.1.2.jar -d /tmp/hunspell/
Archive:  com.gitlab.dumonts.hunspell-2.1.2.jar
   creating: /tmp/hunspell/META-INF/
  inflating: /tmp/hunspell/META-INF/MANIFEST.MF
   creating: /tmp/hunspell/darwin-aarch64/
   creating: /tmp/hunspell/darwin-x86-64/
   creating: /tmp/hunspell/linux-x86-64/
   creating: /tmp/hunspell/win32-x86-64/
   creating: /tmp/hunspell/dumonts/
   creating: /tmp/hunspell/dumonts/hunspell/
   creating: /tmp/hunspell/dumonts/hunspell/bindings/
  inflating: /tmp/hunspell/darwin-aarch64/libhunspell.dylib
  inflating: /tmp/hunspell/darwin-x86-64/libhunspell.dylib
  inflating: /tmp/hunspell/linux-x86-64/libhunspell.so
  inflating: /tmp/hunspell/win32-x86-64/hunspell.dll
  inflating: /tmp/hunspell/dumonts/hunspell/Hunspell.class
  inflating: /tmp/hunspell/dumonts/hunspell/bindings/HunspellLibrary$Hunhandle.class
  inflating: /tmp/hunspell/dumonts/hunspell/bindings/HunspellLibrary.class
   creating: /tmp/hunspell/META-INF/maven/
   creating: /tmp/hunspell/META-INF/maven/com.gitlab.dumonts/
   creating: /tmp/hunspell/META-INF/maven/com.gitlab.dumonts/hunspell/
  inflating: /tmp/hunspell/META-INF/maven/com.gitlab.dumonts/hunspell/pom.xml
  inflating: /tmp/hunspell/META-INF/maven/com.gitlab.dumonts/hunspell/pom.properties

I also figured out that most of linux distro (like Redhat & Ubuntu/Debian) already compiled that binary

  • https://packages.ubuntu.com/focal/libhunspell-dev
  • https://rpmfind.net/linux/rpm2html/search.php?query=libhunspell-1.7.so.0()(64bit)

so that I decided to install libhunspell from OS distro and push this file .so back to JNA lookup directory as above, for example /usr/lib64

# microdnf repoquery hunspell

(microdnf:1970): librhsm-WARNING **: 09:16:20.740: Found 0 entitlement certificates

(microdnf:1970): librhsm-WARNING **: 09:16:20.746: Found 0 entitlement certificates
Downloading metadata...
Downloading metadata...
Downloading metadata...
hunspell-1.7.0-11.el9.aarch64

# microdnf install -y hunspell-1.7.0

# cd /usr/lib64/

# ls -lh | grep hunspell
lrwxrwxrwx  1 root   root     24 Aug 10  2021 libhunspell-1.7.so.0 -> libhunspell-1.7.so.0.0.1
-rwxr-xr-x  1 root   root   534K Aug 10  2021 libhunspell-1.7.so.0.0.1
 
# cp /usr/lib64/libhunspell-1.7.so.0.0.1 /usr/lib64/libhunspell.so

Finally, it worked

FINE  [com.sun.jna.NativeLibrary] (pool-7-thread-1) Looking for library 'hunspell'"
FINE  [com.sun.jna.NativeLibrary] (pool-7-thread-1) Adding paths from jna.library.path: null
FINE  [com.sun.jna.NativeLibrary] (pool-7-thread-1) Trying libhunspell.so
FINE  [com.sun.jna.NativeLibrary] (pool-7-thread-1) Found library 'hunspell' at libhunspell.so

Happy hacking!


P/S I tried to copy libhunspell.so into com.gitlab.dumonts.hunspell-2.1.2.jar but it not working, I don't know why.

# jar uf com.gitlab.dumonts.hunspell-2.1.2.jar linux-aarch64/libhunspell.so

hieuhtr avatar Apr 08 '24 09:04 hieuhtr