{"id":1089,"date":"2009-08-12T09:03:24","date_gmt":"2009-08-12T08:03:24","guid":{"rendered":"http:\/\/fiber-space.de\/wordpress\/?p=1089"},"modified":"2009-08-12T12:24:34","modified_gmt":"2009-08-12T11:24:34","slug":"jynx-03-how-to-fix-custom-class-loaders-for-use-with-jython","status":"publish","type":"post","link":"http:\/\/fiber-space.de\/wordpress\/2009\/08\/12\/jynx-03-how-to-fix-custom-class-loaders-for-use-with-jython\/","title":{"rendered":"Jynx 0.3 &#8211; how to fix custom class loaders for use with Jython"},"content":{"rendered":"<h3>Broken class loaders<\/h3>\n<p>Jynx 0.2 contained an ugly workaround for a bug I couldn&#8217;t fix for quite a while. The bug can be described as follows: suppose you defined code of a Java class `A` and compiled it dynamically:<\/p>\n<pre lang=\"python\">A = JavaCompiler().createClass(\"A\", A_source)<\/pre>\n<p>When you attempt to build a subclass<\/p>\n<pre>class B(A): pass<\/pre>\n<p>a `NoClassDefFoundError` exception was raised:<\/p>\n<pre lang=\"python\">Traceback (most recent call last):\r\n  File \"C:\\lang\\Jython\\jcompile.py\", line 185, in &lt;module&gt;\r\n    class B(A):pass\r\n    at java.lang.ClassLoader.defineClass1(Native Method)\r\n    at java.lang.ClassLoader.defineClass(ClassLoader.java:621)\r\n    at java.lang.ClassLoader.defineClass(ClassLoader.java:466)\r\n    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\r\n    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\r\n    at java.lang.reflect.Method.invoke(Method.java:597)\r\njava.lang.NoClassDefFoundError: org\/python\/core\/PyProxy (wrong name: A)<\/pre>\n<p>In that case the Jython runtime failed to create a proxy class for `B` while locating `PyProxy` which is a Jython core interface. From the traceback it wasn&#8217;t clear how to locate the error and I started to debug into Jython from Netbeans.<\/p>\n<p>This is what happened: Jynx defines a `ByteClassLoader` class which is custom class loader for dynamic compilation of `A`. When `A` is loaded with `loadClass` a `findClass` method is called to locate `A` and this method had to be overwritten. The `ByteClassLoader` was bound to `A` automatically and used by Jython to locate interfaces such as `org.python.core.PyProxy`. This didn&#8217;t work and explains the failure. A possible fix is to respond to classes which cannot be dealt with from `ByteClassLoader` and delegate a `findClass` call to the parent class loader.<\/p>\n<p>Curiously Jython stopped using `ByteClassLoader` after I changed the inheritance hierarchy from<\/p>\n<pre lang=\"python\">class ByteClassLoader(ClassLoader):\r\n    def __init__(self, code):\r\n        super(ByteClassLoader, self).__init__(ClassLoader.getClassLoader())\r\n        ...<\/pre>\n<p>to<\/p>\n<pre lang=\"python\">class ByteClassLoader(URLClassLoader):\r\n    def __init__(self, code):\r\n        super(ByteClassLoader, self).__init__([], ClassLoader.getSystemClassLoader())\r\n        ...<\/pre>\n<p>The `URLClassLoader` provides the opportunity to add `URLs` at runtime and therefore modifying the `CLASSPATH` dynamically.<\/p>\n<h3>No disk dumps in Jynx 0.3<\/h3>\n<p>Prior to <a href=\"http:\/\/code.google.com\/p\/jynx\/\">Jynx 0.3<\/a> a workaround has been dumping `A` to disk and load the class from there. We discussed the subtle nuances of selecting the right class loader and loading `A` from disk moved the machinery into a correct state. This wasn&#8217;t only cumbersome but a hurdle when a programmer intended to work within a Java sandbox. With Jynx 0.3 I feel prepared to explore Java integration with Jynx on GAE-J.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Broken class loaders Jynx 0.2 contained an ugly workaround for a bug I couldn&#8217;t fix for quite a while. The bug can be described as follows: suppose you defined code of a Java class `A` and compiled it dynamically: A &hellip; <a href=\"http:\/\/fiber-space.de\/wordpress\/2009\/08\/12\/jynx-03-how-to-fix-custom-class-loaders-for-use-with-jython\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[26,25],"tags":[],"_links":{"self":[{"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/posts\/1089"}],"collection":[{"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/comments?post=1089"}],"version-history":[{"count":9,"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/posts\/1089\/revisions"}],"predecessor-version":[{"id":1097,"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/posts\/1089\/revisions\/1097"}],"wp:attachment":[{"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/media?parent=1089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/categories?post=1089"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/fiber-space.de\/wordpress\/wp-json\/wp\/v2\/tags?post=1089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}