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

Find a way to use Reach/Eidos jars simultaneously #394

Closed
bgyori opened this issue Feb 16, 2018 · 6 comments · Fixed by #405
Closed

Find a way to use Reach/Eidos jars simultaneously #394

bgyori opened this issue Feb 16, 2018 · 6 comments · Fixed by #405

Comments

@bgyori
Copy link
Member

bgyori commented Feb 16, 2018

Currently the fat jars for Reach and Eidos can't simultaneously be on the CLASSPATH because they pack conflicting dependencies that lead to errors. This has prevented me from adding tests for Eidos without breaking Travis builds. A solution would be to introduce REACHPATH and EIDOSPATH variables that are added to the CLASSPATH from within the respective APIs to make sure the right one is on the CLASSPATH at the right time.

@jmuhlich
Copy link
Member

I think you can use separate explicit class loaders in Java to manage this, rather than using the default class loader.

https://stackoverflow.com/a/6108133
https://en.wikipedia.org/wiki/Java_Classloader#JAR_hell

@bgyori
Copy link
Member Author

bgyori commented Feb 16, 2018

That stackoverflow suggestion is good but that piece of code would have to be integrated into pyjnius to work (since pyjnius is the one that actually ends up loading a class you specify). I'll have to dig into it a bit more.

@bgyori
Copy link
Member Author

bgyori commented Feb 26, 2018

The issue is that as soon as autoclass is imported, the Java VM is started (which reads the CLASSPATH in whatever state it is in when autoclass loads) and it's not possible to effectively change the CLASSPATH afterwards to use JARs that weren't initially on it. This is also discussed in kivy/pyjnius#316, and there doesn't seem to be a solution yet.

@ctrueden
Copy link

ctrueden commented Nov 8, 2019

it's not possible to effectively change the CLASSPATH afterwards to use JARs that weren't initially on it.

If all you want is to add JARs to the classpath of a running Java, apparently that is possible; see kivy/pyjnius#434 (comment). Not sure if changes would be needed on the pyjnius side, though.

@bgyori
Copy link
Member Author

bgyori commented Nov 8, 2019

Thanks, @ctrueden, I guess the issue is that I would need to both add and remove paths from the CLASSPATH during runtime (see kivy/pyjnius#411 (comment)) to solve this issue.

@ctrueden
Copy link

ctrueden commented Nov 8, 2019

@bgyori Ah, yeah, in that case you'd need to use custom class loaders on the Java side. And you can't wrap those dynamically loaded classes on the Python side (see kivy/pyjnius#316); if you try you'll see something like:

Traceback (most recent call last):
  File "jnius/jnius_export_class.pxi", line 766, in jnius.JavaMethod.__call__
  File "jnius/jnius_export_class.pxi", line 845, in jnius.JavaMethod.call_method
  File "jnius/jnius_conversion.pxi", line 212, in jnius.convert_jobject_to_python
  File ".../jnius/reflect.py", line 159, in autoclass
    c = find_javaclass(clsname)
  File "jnius/jnius_export_func.pxi", line 26, in jnius.find_javaclass
jnius.JavaException: Class not found b'my/package/MyClass'

But you can work with dynamically loaded classes on the Java side... as long as they don't leak to Python as return values or whatnot.

If you're looking for an easy way to dynamically load classpath elements, you could check out the Groovy scripting language and its @Grab annotation.

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

Successfully merging a pull request may close this issue.

3 participants