Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method Handles ends up with java.util.ConcurrentModificationException #3695

Closed
dainiusjocas opened this issue Aug 18, 2021 · 5 comments
Closed
Assignees

Comments

@dainiusjocas
Copy link

When compiled with the native-image the concurrent invocation of the Lovins stemmer sometimes fails with an exception (see below).
It seems that the GraalVM method handles implementation causes the exception.
When running in the JVM the same code never fails.

Steps to reproduce the issue
Please include both build steps as well as run steps

  1. git clone https://github.com/dainiusjocas/lucene-grep.git
  2. cd lucene-grep
  3. git checkout bug/lovins-stemmer-concurrent-modification-exception
  4. make build
  5. ./lmgrep test/resources/test.txt --only-analyze --analysis="$(cat test/resources/binary/tokenfilters/lovinssnowballstem.json)" > /dev/null;

An alternative for the last step to invoke the same code in JVM would be:

clojure -M -m lmgrep.core test/resources/test.txt --only-analyze --analysis="$(cat test/resources/binary/tokenfilters/lovinssnowballstem.json)"

Describe GraalVM and your environment:

  • GraalVM version (latest snapshot builds can be found here), or commit id if built from source: graalvm-ce-java11-21.2.0
  • JDK major version: 11
  • OS: Ubuntu 21.04, Fedora 34
  • Architecture: AMD64
  • Clojure version: 1.10.3.814

Installing Clojure as described here https://clojure.org/guides/getting_started

        at java.util.HashMap.computeIfAbsent(HashMap.java:1134)
        at com.oracle.svm.methodhandles.MethodHandleIntrinsicImpl.intrinsic(MethodHandleIntrinsicImpl.java:143)
        at com.oracle.svm.methodhandles.MethodHandleIntrinsicImpl.intrinsic(MethodHandleIntrinsicImpl.java:147)
        at com.oracle.svm.methodhandles.MethodHandleIntrinsicImpl.resolve(MethodHandleIntrinsicImpl.java:430)
        at com.oracle.svm.methodhandles.Util_java_lang_invoke_MethodHandleNatives.resolve(Target_java_lang_invoke_MethodHandleNatives.java:307)
        at java.lang.invoke.MethodHandleNatives.resolve(MethodHandleNatives.java:214)
        at com.oracle.svm.methodhandles.Util_java_lang_invoke_MethodHandle.invokeInternal(Target_java_lang_invoke_MethodHandle.java:139)
        at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:79)
        at java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments(LambdaForm.java:76)
        at java.lang.invoke.LambdaForm.interpretName(LambdaForm.java:981)
        at java.lang.invoke.LambdaForm.interpretWithArguments(LambdaForm.java:958)
        at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:85)
        at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:0)
        at java.lang.invoke.LambdaForm$MH/1713965096.invokeExact_MT(LambdaForm$MH)
        at org.tartarus.snowball.SnowballProgram.find_among_b(SnowballProgram.java:382)
        at org.tartarus.snowball.ext.LovinsStemmer.r_endings(LovinsStemmer.java:1526)
        at org.tartarus.snowball.ext.LovinsStemmer.stem(LovinsStemmer.java:1886)
        at org.apache.lucene.analysis.snowball.SnowballFilter.incrementToken(SnowballFilter.java:95)
        at lmgrep.lucene.text_analysis$text__GT_token_strings.invokeStatic(text_analysis.clj:16)
        at lmgrep.lucene.text_analysis$text__GT_token_strings.invoke(text_analysis.clj:9)
        at lmgrep.only_analyze$ordered_analysis$analyze_fn__9504.invoke(only_analyze.clj:99)
        at clojure.core$map$fn__5880$fn__5881.invoke(core.clj:2746)
        at clojure.core.async.impl.channels$chan$fn__1031.invoke(channels.clj:300)
        at clojure.core.async.impl.channels.ManyToManyChannel.put_BANG_(channels.clj:143)
        at clojure.core.async$fn__6243.invokeStatic(async.clj:172)
        at clojure.core.async$fn__6243.invoke(async.clj:164)
        at clojure.core.async$pipeline_STAR_$process__6427.invoke(async.clj:534)
        at clojure.core.async$pipeline_STAR_$fn__6556.invoke(async.clj:549)
        at clojure.core.async$thread_call$fn__6350.invoke(async.clj:484)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.lang.Thread.run(Thread.java:829)
        at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:567)
        at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:192)
@munishchouhan
Copy link
Contributor

@dainiusjocas Thanks for reporting the issue, we will check it out and get back to you

@munishchouhan
Copy link
Contributor

@dainiusjocas I have tried using graalvm-ce-java11-21.3.0-dev
you can download it from here : https://github.com/graalvm/graalvm-ce-dev-builds/releases/tag/21.3.0-dev-20210826_0017

export GRAALVM_HOME=/home/munish/graalvm-ce-java11-21.3.0-dev
~/github/3695/lucene-grep$ make build
clojure -Spom
Skipping paths: resources
clojure -X:uberjar :jar target/lmgrep-uber.jar :main-class lmgrep.core
Compiling lmgrep.core ...
Building uber jar: target/lmgrep-uber.jar
Processing pom.xml for {lucene-grep/lucene-grep {:mvn/version "0.1.0"}}
script/compile
x^[`Warning: Ignoring server-mode native-image argument --no-server.
[lmgrep:490]    classlist:   4,333.03 ms,  0.96 GB
--initialize-at-build-time without arguments has been deprecated when not using --diagnostics-mode. With GraalVM 22.0.0. --initialize-at-build-time will only work with --diagnostics-mode for debugging purposes.
The reason for deprecation is that --initalize-at-build-time does not compose, i.e., a single library can make assumptions that the whole classpath can be safely initialized at build time; that assumption is often incorrect.
[lmgrep:490]        (cap):   4,468.57 ms,  0.96 GB
[lmgrep:490]        setup:   7,436.05 ms,  0.96 GB
[lmgrep:490]     (clinit):     501.39 ms,  5.62 GB
[lmgrep:490]   (typeflow):  13,885.58 ms,  5.62 GB
[lmgrep:490]    (objects):  23,308.71 ms,  5.62 GB
[lmgrep:490]   (features):   2,480.23 ms,  5.62 GB
[lmgrep:490]     analysis:  41,318.41 ms,  5.62 GB
[lmgrep:490]     universe:   1,817.71 ms,  5.43 GB
[lmgrep:490]      (parse):   1,635.82 ms,  5.43 GB
[lmgrep:490]     (inline):   3,975.81 ms,  5.56 GB
[lmgrep:490]    (compile):  17,429.18 ms,  5.56 GB
[lmgrep:490]      compile:  24,831.03 ms,  5.56 GB
[lmgrep:490]        image:   4,177.82 ms,  5.60 GB
[lmgrep:490]        write:   6,322.25 ms,  5.60 GB
[lmgrep:490]      [total]:  90,923.57 ms,  5.60 GB
# Printing build artifacts to: /home/munish/github/3695/lucene-grep/lmgrep.build_artifacts.txt
~/github/3695/lucene-grep$ ./lmgrep test/resources/test.txt --only-analyze --analysis="$(cat test/resources/binary/tokenfilters/lovinssnowballstem.json)" > /dev/null;

@dainiusjocas
Copy link
Author

dainiusjocas commented Aug 26, 2021

@mcraj017 I've downloaded and installed that version graalvm-ce-java11-21.3.0-dev

Good thing is that the previous exception doesn't happen anymore.

Bad thing is that after several retries I'm getting a different exception which is also related to the method handles. I believe that it might be a problem due to the generated code on the Lucene side, but still might be of interest for the GraalVM team:

➜  lucene-grep git:(bug/lovins-stemmer-concurrent-modification-exception) ✗ ./lmgrep test/resources/test.txt --only-analyze --analysis="$(cat test/resources/binary/tokenfilters/lovinssnowballstem.json)" > /dev/null;
java.lang.reflect.UndeclaredThrowableException
        at org.tartarus.snowball.SnowballProgram.find_among_b(SnowballProgram.java:386)
        at org.tartarus.snowball.ext.LovinsStemmer.r_endings(LovinsStemmer.java:1526)
        at org.tartarus.snowball.ext.LovinsStemmer.stem(LovinsStemmer.java:1886)
        at org.apache.lucene.analysis.snowball.SnowballFilter.incrementToken(SnowballFilter.java:95)
        at lmgrep.lucene.text_analysis$text__GT_token_strings.invokeStatic(text_analysis.clj:16)
        at lmgrep.lucene.text_analysis$text__GT_token_strings.invoke(text_analysis.clj:9)
        at lmgrep.only_analyze$ordered_analysis$analyze_fn__9504.invoke(only_analyze.clj:99)
        at clojure.core$map$fn__5880$fn__5881.invoke(core.clj:2746)
        at clojure.core.async.impl.channels$chan$fn__1031.invoke(channels.clj:300)
        at clojure.core.async.impl.channels.ManyToManyChannel.put_BANG_(channels.clj:143)
        at clojure.core.async$fn__6243.invokeStatic(async.clj:172)
        at clojure.core.async$fn__6243.invoke(async.clj:164)
        at clojure.core.async$pipeline_STAR_$process__6427.invoke(async.clj:534)
        at clojure.core.async$pipeline_STAR_$fn__6556.invoke(async.clj:549)
        at clojure.core.async$thread_call$fn__6350.invoke(async.clj:484)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.lang.Thread.run(Thread.java:829)
        at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:567)
        at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:192)
Caused by: java.lang.IllegalAccessException: class com.oracle.svm.methodhandles.Util_java_lang_invoke_MethodHandle cannot access a member of class org.tartarus.snowball.ext.LovinsStemmer with modifiers "private"
        at jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
        at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:591)
        at java.lang.reflect.Method.invoke(Method.java:558)
        at com.oracle.svm.methodhandles.Util_java_lang_invoke_MethodHandle.invokeInternal(Target_java_lang_invoke_MethodHandle.java:222)
        at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:81)
        at com.oracle.svm.methodhandles.MethodHandleIntrinsicImpl.execute(MethodHandleIntrinsicImpl.java:180)
        at com.oracle.svm.methodhandles.Util_java_lang_invoke_MethodHandle.invokeInternal(Target_java_lang_invoke_MethodHandle.java:147)
        at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:81)
        at java.lang.invoke.LambdaForm$NamedFunction.invokeWithArguments(LambdaForm.java:76)
        at java.lang.invoke.LambdaForm.interpretName(LambdaForm.java:981)
        at java.lang.invoke.LambdaForm.interpretWithArguments(LambdaForm.java:958)
        at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:87)
        at java.lang.invoke.MethodHandle.invokeBasic(MethodHandle.java:0)
        at java.lang.invoke.LambdaForm$MH/1957746443.invokeExact_MT(LambdaForm$MH)
        at org.tartarus.snowball.SnowballProgram.find_among_b(SnowballProgram.java:382)
        ... 20 more
➜  lucene-grep git:(bug/lovins-stemmer-concurrent-modification-exception) ✗ ./lmgrep test/resources/test.txt --only-analyze --analysis="$(cat test/resources/binary/tokenfilters/lovinssnowballstem.json)" > /dev/null;
➜  lucene-grep git:(bug/lovins-stemmer-concurrent-modification-exception) ✗ echo $GRAALVM_HOME                                                                                                                                                     
/home/dj/dev/tools/graalvm-ce-java11-21.3.0-dev 
➜  lucene-grep git:(bug/lovins-stemmer-concurrent-modification-exception) ✗ which native-image
/home/dj/dev/tools/graalvm-ce-java11-21.3.0-dev/bin/native-image

Since the problem happens sometimes I've put the call into a loop:

for i in {1..1000}; do ./lmgrep test/resources/test.txt --only-analyze --analysis="$(cat test/resources/binary/tokenfilters/lovinssnowballstem.json)" > /dev/null; done

@munishchouhan
Copy link
Contributor

munishchouhan commented Aug 27, 2021

@dainiusjocas I did executed with loop[ but still no error:

:~/github/3695$ cd lucene-grep/
:~/github/3695/lucene-grep$ for i in {1..1000}; do ./lmgrep test/resources/test.txt --only-analyze --analysis="$(cat test/resources/binary/tokenfilters/lovinssnowballstem.json)" > /dev/null; done
:~/github/3695/lucene-grep$ ls
CHANGELOG.md  Dockerfile  LICENSE  Makefile  README.md  binary-test.sh  deps.edn  docs  examples  graalvm  lmgrep  lmgrep.build_artifacts.txt  pom.xml  resources  script  src  target  test

@munishchouhan
Copy link
Contributor

Closing this issue as there is no activity in last 30 daysa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants