org.scijava:pom-jython-shaded

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

License

License

Jython Software License
GroupId

GroupId

org.scijava
ArtifactId

ArtifactId

pom-jython-shaded
Last Version

Last Version

2.7.1.1
Release Date

Release Date

Type

Type

pom
Description

Description

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.
Project URL

Project URL

http://www.jython.org/
Project Organization

Project Organization

SciJava
Source Code Management

Source Code Management

https://github.com/scijava/jython-shaded

Download pom-jython-shaded

How to add to project

<!-- https://jarcasting.com/artifacts/org.scijava/pom-jython-shaded/ -->
<dependency>
    <groupId>org.scijava</groupId>
    <artifactId>pom-jython-shaded</artifactId>
    <version>2.7.1.1</version>
    <type>pom</type>
</dependency>
// https://jarcasting.com/artifacts/org.scijava/pom-jython-shaded/
implementation 'org.scijava:pom-jython-shaded:2.7.1.1'
// https://jarcasting.com/artifacts/org.scijava/pom-jython-shaded/
implementation ("org.scijava:pom-jython-shaded:2.7.1.1")
'org.scijava:pom-jython-shaded:pom:2.7.1.1'
<dependency org="org.scijava" name="pom-jython-shaded" rev="2.7.1.1">
  <artifact name="pom-jython-shaded" type="pom" />
</dependency>
@Grapes(
@Grab(group='org.scijava', module='pom-jython-shaded', version='2.7.1.1')
)
libraryDependencies += "org.scijava" % "pom-jython-shaded" % "2.7.1.1"
[org.scijava/pom-jython-shaded "2.7.1.1"]

Dependencies

There are no dependencies for this project. It is a standalone project that does not depend on any other jars.

Project Modules

  • deps
  • shaded

Update 2019-11-04: As of jython 2.7.2b2, a new artifact org.python:jython-slim now exists with proper modular dependency structure, which makes this jython-shaded project obsolete. 🎉 See #7 for details.

This project provides a rebundled version of the Jython library (specifically: org.python:jython-standalone) with shaded (i.e., renamed) dependencies.

You can use it as follows:

<dependency>
	<groupId>org.scijava</groupId>
	<artifactId>jython-shaded</artifactId>
	<version>2.7.1.1</version>
</dependency>

With this approach, dependencies of Jython are renamed to have a package prefix of org.scijava.jython.shaded. So all of Jython "just works" without interfering with other consumers of JFFI or other dependencies you might have on your classpath.

It leverages the Maven Shade Plugin to do it.

Background

The Jython project is awesome. But it has a critical problem: the binary artifacts available from Maven Central are unshaded uberjars, and hence not usable in large projects. In particular, both Jython and JRuby depend on the JFFI library, but at different and incompatible versions thereof.

The naive way to add a Jython dependency is:

<dependency>
	<groupId>org.python</groupId>
	<artifactId>jython</artifactId>
	<version>2.7.1</version>
</dependency>

But that artifact does not include the critical Lib/ directory with all of the native Python libraries necessary for many functions to work (e.g., os.path.isdir).

So another artifact is available which includes those libraries:

<dependency>
	<groupId>org.python</groupId>
	<artifactId>jython-standalone</artifactId>
	<version>2.7.1</version>
</dependency>

But both jython and jython-standalone are uberjars, meaning they bundle the dependencies of the project inside the JAR itself. And they are both unshaded, meaning they don't rename the package prefixes of those dependencies. So if you need to use a different version of those dependencies (e.g., because JRuby needs a different version of JFFI), then you are out of luck.

Example

Here is an example Jython script that produces an exception when attempting to run it using Jython 2.5.3 when JRuby 1.7.12 and dependencies (including JFFI 1.2.7) are also on the classpath:

import os
print os.path.isdir('/')

The exception which occurs is:

Traceback (most recent call last):
	File "test.py", line 2, in <module>
	File ".../jython-standalone-2.5.3.jar/Lib/posixpath.py", line 195, in isdir
	File ".../jython-standalone-2.5.3.jar/Lib/posixpath.py", line 195, in isdir
java.lang.IncompatibleClassChangeError: Found class com.kenai.jffi.InvocationBuffer, but interface was expected
	at com.kenai.jaffl.provider.jffi.AsmRuntime.marshal(AsmRuntime.java:167)
	at org.python.posix.LibC$jaffl$0.stat$raw(Unknown Source)
	at org.python.posix.LibC$jaffl$0.stat(Unknown Source)
	at org.python.posix.BaseNativePOSIX.stat(BaseNativePOSIX.java:200)
	at org.python.posix.LazyPOSIX.stat(LazyPOSIX.java:207)
	at org.python.modules.posix.PosixModule$StatFunction.__call__(PosixModule.java:954)
	at org.python.core.PyObject.__call__(PyObject.java:391)
	at posixpath$py.isdir$17(/Applications/Science/Fiji.app/jars/jython-standalone-2.5.3.jar/Lib/posixpath.py:198)
	at posixpath$py.call_function(/Applications/Science/Fiji.app/jars/jython-standalone-2.5.3.jar/Lib/posixpath.py)
	at org.python.core.PyTableCode.call(PyTableCode.java:165)
	at org.python.core.PyBaseCode.call(PyBaseCode.java:134)
	at org.python.core.PyFunction.__call__(PyFunction.java:317)
	at org.python.pycode._pyx0.f$0(New_.py:2)
	at org.python.pycode._pyx0.call_function(New_.py)
	at org.python.core.PyTableCode.call(PyTableCode.java:165)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1275)
  ...

When running with jython-shaded on the classpath instead of jython-standalone, the above script works as expected.

FAQ

Q: Why is this structured as a multi-module project?

A: Due to a bug in ASM (the library that maven-shade-plugin uses to rewrite the Java bytecode with the shaded package names), many of the <foo>$py.class files cannot be processed properly. Fortunately, these classes do not actually need to be rewritten, since they themselves do not directly reference any of Jython's dependencies. So this project works around the issue by using the Shade plugin twice: once to build a JAR of shaded dependencies without the <foo>.py classes, and a second time to mix them back in to the final artifact.

org.scijava

SciJava

Scientific libraries in Java

Versions

Version
2.7.1.1
2.7.1
2.7.0
2.5.3