padreati / rapaio-jupyter-kernel

Java jupyter kernel
MIT License
53 stars 7 forks source link

Maybe use shaded jar to avoid issues with dependencies? #67

Closed dsyer closed 2 months ago

dsyer commented 3 months ago

Notebooks that want to use the same dependencies as the Jupyter kernel can easily break because of the way the classpath is structured. Shaded jars are problematic for other reasons but it is quite a well-known technique and it could avoid clashes between the kernel and the notebook classpath.

Example:

screen

Summary: the method is not found because the Gson in the parent loader is an older version.

dsyer commented 3 months ago

FWIW I tried building and installing with this instead of the assembly plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <configuration>
      <keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>
      <createDependencyReducedPom>true</createDependencyReducedPom>
      <filters>
        <filter>
          <artifact>*:*</artifact>
          <excludes>
            <exclude>META-INF/*.SF</exclude>
            <exclude>META-INF/*.DSA</exclude>
            <exclude>META-INF/*.RSA</exclude>
          </excludes>
        </filter>
      </filters>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
        <configuration>
          <relocations>
            <relocation>
                <pattern>org.slf4j</pattern>
                <shadedPattern>org.rapaio.shaded.org.slf4j</shadedPattern>
            </relocation>
            <relocation>
                <pattern>com</pattern>
                <shadedPattern>org.rapaio.shaded.com</shadedPattern>
            </relocation>
          </relocations>
          <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
              <mainClass>org.rapaio.jupyter.kernel.MainApp</mainClass>
            </transformer>
          </transformers>
        </configuration>
      </execution>
    </executions>
  </plugin>

Obviously doesn't cover all the dependencies, but it worked.

padreati commented 3 months ago

Shaded jars are a solution indeed. There is another one, which needs examination.

I need to test it, but I suppose one of the reasons why it clashes is that I made available the kernel as a module to the classpath from JShell in order to make available by default some methods which could be called from Java code like display, updateDisplay. I think that if I do not make available by default them, the problems will disappear. In order to make them available, one could import the kernel project as a normal dependency and dependency resolution could help avoid that. To make that easier, I can create a magic command which loads the kernel also. All of that needs to be tested, but this could be another alternative. If is possible which one do you believe to be preferable?

dsyer commented 3 months ago

I don’t have a preference, as long as I can use other “normal” tools in a cell. It remains to be seen if the module system can deliver on that. I’d be quite interested to see.

padreati commented 3 months ago

I followed your way with shaded modules. It seems to work and still been able to provide the other normal Java tools the kernel offers. I will push a new release with that.