SpencerPark / IJava

A Jupyter kernel for executing Java code.
MIT License
1.07k stars 211 forks source link

NoSuchMethodError with Gson #130

Open JohannesLichtenberger opened 2 years ago

JohannesLichtenberger commented 2 years ago

I'm getting a NoSuchMethodError when using the JsonParser.parseString(String) method from Google Gson to parse JSON:

final var jsonElement = JsonParser.parseString(Files.readString(updateOperationsFile));

I'm using this command-sequence to start the kernel and download a JAR

!apt update -q
!apt-get install -q openjdk-17-jdk-headless
!curl -L https://github.com/SpencerPark/IJava/releases/download/v1.3.0/ijava-1.3.0.zip -o ijava-kernel.zip
!unzip -o -q ijava-kernel.zip -d ijava-kernel && cd ijava-kernel && python3 install.py --sys-prefix
!jupyter kernelspec list
!curl -L https://oss.sonatype.org/content/repositories/snapshots/io/sirix/sirix-xquery/0.9.6-SNAPSHOT/sirix-xquery-0.9.6-20220209.213554-1218-all.jar -o sirix-xquery.jar

java.lang.NoSuchMethodError: 'com.google.gson.JsonElement com.google.gson.JsonParser.parseString(java.lang.String)' at org.sirix.access.trx.node.json.JsonNodeReadOnlyTrxImpl.getUpdateOperations(JsonNodeReadOnlyTrxImpl.java:113)

You can see the error in the following Notebook: https://colab.research.google.com/drive/1NNn1nwSbK6hAekzo1YbED52RI3NMqqbG#scrollTo=RwIAuN1IKtUo

Whenever you execute a cell with a jn:diff-function.

JohannesLichtenberger commented 2 years ago

The problem is that IJava has an old Gson dependeny. I can only find the import-statements however and don't know how the Gson dependency is included. Can anyone help?

paulk-asert commented 2 years ago

./gradlew dependencies shows it is an indirect dependency of jupyter-jvm-basekernel which (along with its dependencies) is shaded into the IJava jar:

runtimeClasspath - Runtime classpath of source set 'main'.
+--- io.github.spencerpark:jupyter-jvm-basekernel:2.3.0
|    +--- org.zeromq:jeromq:0.5.1
|    |    \--- eu.neilalexander:jnacl:1.0.0
|    \--- com.google.code.gson:gson:2.8.5
|    ...
JohannesLichtenberger commented 2 years ago

Can someone update the dependency and make the minor code changes necessary? Shouldn't be too much work :+1:

paulk-asert commented 2 years ago

It looks like you already have a PR over in the relevant project (jupyter-jvm-basekernel). If that project is updated, it will be easy to bump the version of that plugin here.

JohannesLichtenberger commented 2 years ago

Hm, guess the project(s) more or less unmaintained. I saw that there's also a Kotlin kernel I maybe could use instead.

kolban-google commented 1 year ago

While we wait for a proper fix, here is a horrible hack that appears to work for me.

  1. Create a tmp folder on Linux
  2. Create a file called Makefile that includes:
    
    run: copy extract gson copy-new create update
    @echo "All Done!"

copy: cp $(HOME)/.local/share/jupyter/kernels/java/ijava-1.3.0.jar .

extract: unzip -o ijava-1.3.0.jar -d ./output

gson: wget https://repo1.maven.org/maven2/com/google/code/gson/gson/2.10/gson-2.10.jar unzip -o ./gson-2.10.jar -d ./gson

copy-new: cp -r gson/com output

create: jar --create --file patched-ijava-1.3.0.jar --verbose --no-manifest -C output/ .

update: cp patched-ijava-1.3.0.jar $(HOME)/.local/share/jupyter/kernels/java/ijava-1.3.0.jar

clean: rm -rf gson output target patched-ijava-1.3.0.jar.jar gson-2.10.jar ijava-1.3.0.jar


3. With your IJava installed, run the command `make`.

What this recipe does is:
1. Copy the ijava-1.3.0.jar file to the local directory
2. Extract the contents
3. Downloads the latest gson
4. Extracts the latest gson
5. Replaces the files in the extracted ijava directory
6. Rebuilds the JAR
7. Copies it into place