From: Jimmy M. <jim...@gm...> - 2016-05-22 17:09:54
|
After further investigation of my code, I've discovered that the issue appears to be on the interpreter and how it is importing the class entity. Thanks to your advice, I did a direct comparison on what the interpreter imported from the script and the class entity I passed directly as a constructor argument. I.E: made the following edits on the following two files: com.dirty.plugin.simple_jython_plugin.App //line 34 PyObject pyInstance = pyClass.__call__(Py.javas2pys("SampleTestInput", PyInterface.class); PyInterfaceImpl.py def __init__(self, yourInput, classComparison): print PyInterface == classComparison Upon first creation, the evaluation returns true. However, on subsequent creations, this always returns false. The observation I'm seeing is that the interpreter is not pulling the classloader's version and pulling another version entirely. The import statement in the App.class is pulling the version I wish to work with, but the interpreter is pulling the wrong version. I don't understand why this is occurring despite during the interpreter initialization, I'm providing a system state with the specified classloader to use. With that in mind, I resolved a workaround by instead creating the interpreter via PythonInterpreter.threadLocalStateInterpreter() and passing in a map with the class simple name as a key and all the relevant classes as values. This allowed me to now properly do casting in Java. This solution though appears tedious as if the jar has a dependency on libraries it packages with itself, I must ensure that I build their namespace as well. For small subapps, this isn't a lot of work, but this can be a relatively large undertaking if the libraries they import are massive. Is it possible to get the interpreter to respect the classloader's classes provided inside the attached PyStstemState and resolve with this one first before attempting to retrieve from parent classloaders? On Fri, May 20, 2016 at 11:23 AM, John Hubbard <jhu...@no...> wrote: > On 05/19/2016 05:22 PM, Jimmy Mauri wrote: > > For context, see sample project in: > https://github.com/ElCubanoPoderoso/jython-classloader-issue > > I have a use-case where I must support dynamically loaded .jar files as > hot-deployable subapplications. I was having trouble in instances where if > the .jar file was redeployed (say I made a code change and need to update > the environment), Jython starts to break down with class casting. Upon the > first deployment, the application is able to properly load the .jar file, > instantiate the main class which creates the interpreter with the packaged > URLClassLoader into the PySystemState object, interprets the script and > creates the class object with the appropriate java interface cast to it. > > However, the second invocation of said project causes the casting to fail > on subsequent executions, converting the object to a PySingleton and > rejecting the cast. I'm having trouble understanding what I need to do to > resolve my issue. Not being able to properly coerce the object to the > expected java interface is causing forced workarounds to add wrapper > objects to utilize them in Java code. > > Note: This is only observed when trying to cast to interfaces that reside > inside the .jar file and not in the system classloader. > > The sample GitHub project linked was simplified to generate a > proof-of-concept that can be invoked via JUnit to reproduce the error. > > My question is: what is wrong with my current implementation that is > causing this issue? As part of the requirement, I must be able to redeploy > without shutting down the JVM. Any help in this matter would be > appreciated. > > > I'm not sure if this is your issue but remember that in Java two > instantiations of the same class from two different class loaders are for > all intents and purposes not the same class. Given an object of class C > loaded by class loader A and another object of class C loaded by class > loader B you cannot cast from the first to the second. Jython's duck > typing protects you from some of this (e.g. within the Jythin interpreter > you can call all methods on either instantiation of C), however if you try > to pass a C instantiated by CL A to a any class loaded in CL B that will > fail. > > If this sounds like your issue let me know and I can tell you more about > how we deal with this in our application (which uses multiple instances of > a custom classloader to isolate different components). Its been a while > since I've seen it but I seem to recall that the hint that I'd run into > this from within our application was getting a ClassCastException with a > message something like: 'cannot cast a foo.bar to foo.bar'. > > > > -- > -john > > To be or not to be, that is the question > 2b || !2b > (0b10)*(0b1100010) || !(0b10)*(0b1100010) > 0b11000100 || !0b11000100 > 0b11000100 || 0b00111011 > 0b11111111 > 255, that is the answer. > > > > > ------------------------------------------------------------------------------ > Mobile security can be enabling, not merely restricting. Employees who > bring their own devices (BYOD) to work are irked by the imposition of MDM > restrictions. Mobile Device Manager Plus allows you to control only the > apps on BYO-devices by containerizing them, leaving personal data > untouched! > https://ad.doubleclick.net/ddm/clk/304595813;131938128;j > _______________________________________________ > Jython-users mailing list > Jyt...@li... > https://lists.sourceforge.net/lists/listinfo/jython-users > > |