SpencerPark / IJava

A Jupyter kernel for executing Java code.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NoSuchMethodError with Gson

JohannesLichtenberger opened this issue · comments

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.

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?

./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
|    ...

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

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.

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

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
  1. 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