1 <?xml version="1.0" encoding="iso-8859-1"?> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title>javaclass/ClassFile</title> 5 <meta name="generator" content="amaya 8.1a, see http://www.w3.org/Amaya/" /> 6 <link xmlns:xlink="http://www.w3.org/1999/xlink" href="styles.css" 7 rel="stylesheet" type="text/css" /> 8 </head> 9 10 <body> 11 <h1>javaclass</h1> 12 13 <p>The javaclass collection of packages and utilities (also known as 14 ClassFile) provides a means of importing Java classes and packages directly 15 into Python, without the need for a Java virtual machine, so that the classes 16 may be instantiated, accessed, run and manipulated just like Python classes, 17 and that the resulting objects and methods can be accessed and manipulated 18 just like Python objects and methods. It should be possible to run compiled 19 Java programs with the Python interpreter and not notice that it isn't the 20 Java virtual machine being used - given sufficient library support for the 21 program concerned, of course.</p> 22 23 <h2>Quick Examples</h2> 24 25 <p>It can be quicker to see what this is about by seeing some examples.</p> 26 27 <h3>The Not Very Convincing Example</h3> 28 29 <p>You can run Java classes by finding one with a main method and executing 30 it. Here's a comparison of a freshly prepared Java class being run in Python 31 and in a Java virtual machine respectively:</p> 32 <pre class="Prompt">cd tests/</pre> 33 <pre class="Prompt">javac Value.java</pre> 34 <pre class="PromptRequest">runclass.py Value</pre> 35 <pre class="PromptResponse">v.getValue() correct: 123 36 v.getValue() correct: 456 37 v.isPositive() correct: 1 38 v.isPositive() correct: 0 39 v.compare(-790) correct: -1 40 v.compare(-788) correct: 1 41 v.compare(-789) correct: 0 42 v.getValue() == v2.getValue() correct: 0 43 v2.add(-123) correct: 0 44 v2.getValue() correct: 255</pre> 45 <pre class="PromptRequest">java Value</pre> 46 <pre class="PromptResponse">v.getValue() correct: 123 47 v.getValue() correct: 456 48 v.isPositive() correct: true 49 v.isPositive() correct: false 50 v.compare(-790) correct: -1 51 v.compare(-788) correct: 1 52 v.compare(-789) correct: 0 53 v.getValue() == v2.getValue() correct: false 54 v2.add(-123) correct: 0 55 v2.getValue() correct: 255</pre> 56 57 <h3>The Slightly More Credible Example</h3> 58 59 <p>It can be more interesting to get into Python's interactive mode and then 60 start playing around with Java classes:</p> 61 <pre class="PromptResponse">Python 2.2.2 (#2, Jan 21 2005, 16:16:57) 62 [GCC 2.96 20000731 (Red Hat Linux 7.3 2.96-112)] on linux2 63 Type "help", "copyright", "credits" or "license" for more information.</pre> 64 <pre class="PythonPrompt">import javaclass.classhook</pre> 65 <pre class="PythonPrompt">from __this__ import Value</pre> 66 <pre class="PythonPrompt">dir()</pre> 67 <pre class="PromptResponse">['Value', '__builtins__', '__doc__', '__name__', 68 'javaclass']</pre> 69 <pre class="PythonPrompt">dir(Value)</pre> 70 <pre class="PromptResponse">['__class__', '__delattr__', '__dict__', '__doc__', 71 '__getattribute__', '__hash__', '__init__', '__init______I_', '__module__', 72 '__new__', '__reduce__', '__repr__', '__setattr__', '__str__', '__weakref__', 73 'add', 'add____I_', 'compare', 'compare____I_', 'getClass', 'getClass___', 74 'getValue', 'getValue___', 'isPositive', 'isPositive___', 'main', 75 'main___java__lang__String_array_', 'newValue', 'newValue___', 'setValue', 76 'setValue____I_']</pre> 77 <pre class="PythonPrompt">v = Value(20050121)</pre> 78 <pre class="PythonPrompt">v.getValue()</pre> 79 <pre class="PromptResponse">20050121</pre> 80 <pre class="PythonPrompt">v.setValue(20050401)</pre> 81 <pre class="PythonPrompt">v.getValue()</pre> 82 <pre class="PromptResponse">20050401</pre> 83 84 <h2>Copyright and Licence</h2> 85 86 <p>The javaclass software is distributed under the terms of the GNU Lesser 87 General Public Licence (LGPL). See the file <code>COPYING.txt</code> in the 88 <code>docs</code> directory within the source code distribution.</p> 89 90 <h2>Getting Started</h2> 91 92 <p>See the <code>README.txt</code> file in the distribution directory.</p> 93 94 <h2>Motivation</h2> 95 96 <p>Pick one of the following:</p> 97 <ul> 98 <li>The need/desire to access Java libraries from Python without firing up 99 Java virtual machines or switching to Jython (and thereby losing 100 convenient access to various CPython libraries).</li> 101 <li>Mixing languages available for the Java runtime with Python.</li> 102 <li>Static typing for the Python environment, albeit achieved by writing 103 Java or other appropriate languages.</li> 104 <li>Having an open source environment from top to bottom to run Java 105 bytecode on.</li> 106 <li>Experimentation around import hooks, bytecode generation; observation 107 of different runtime and type systems interacting.</li> 108 <li>Making Python libraries available to Java programs - Tkinter for Java, 109 anyone?!</li> 110 </ul> 111 112 <h2>Limitations</h2> 113 114 <p>It isn't all great, however. Here are some reasons why this might not do 115 what you want it to:</p> 116 <ul> 117 <li>It runs on the Python runtime which does not have the security, 118 threading and just-in-time compiler features that people enjoy about Java 119 runtimes, so if what you like to do is to run one big servlet container 120 with lots of classes and threads from different people floating around, 121 this isn't going to protect them from doing all sorts of things to each 122 other and to your system. However, you may take the unfashionable view 123 that the operating system is supposed to do that kind of thing.</li> 124 <li>It works by generating Python bytecode from the Java bytecode in class 125 files (and .jar archives). Generally, anyone who is anyone in the Python 126 pantheon has largely recommended against doing anything with the 127 bytecode, despite noble efforts to make exciting things happen by 128 transforming it, optimising it, and so on. (Instead, there's been more 129 emphasis on lots of runtime baggage for things which could be done by 130 analysis of the code with modified bytecode being produced as a result, 131 and let's not get started on some of the syntax enhancements!) 132 Consequently, stability might be an issue for some configurations, 133 especially since CPython doesn't fail particularly graciously with badly 134 behaved bytecode.</li> 135 <li>Some of the translation from Java to Python bytecode takes a few 136 liberties. For example, Java exceptions are handled in ways reminiscent 137 of a 1980s microcomputer assembly language, whereas Python bytecode has 138 higher level constructs for exceptions; this translation can probably be 139 done incorrectly, triggering some kind of bytecode misbehaviour, and we 140 all know what happens then.</li> 141 <li>At the Python level, not all things seem totally right. For example, 142 Java bytecode instructions are used to instantiate and then initialise 143 exceptions just like other objects, and while Python can support this 144 with new-style objects, Python won't let you use new-style objects as 145 exceptions. Consequently, when Java exceptions appear in Python programs, 146 they will be wrapped in old-style exceptions and have to be handled 147 specially.</li> 148 <li>In order to support method dispatch properly, special names are used 149 for the translated methods which include the type information found in 150 the bytecode; things like <code>main___java__lang__String_array_</code> 151 and <code>setValue____I_</code> appear when you look inside classes and 152 objects. When implementing libraries in Python for Java programs, such 153 method naming conventions have to be used because the original code is 154 very specific about which method is being invoked, and for specialised 155 versions of <code>__init__</code> it becomes necessary to do a 156 <code>setattr</code> to add such methods into classes because of various 157 "name mangling" measures in the Python compilation process. Now, many 158 people might start advocating decorators at this point, but not everyone 159 is running the very latest stuff from python.org, and decorators won't 160 help you target a specific specialised method anyway.</li> 161 <li>Special dispatcher methods are often generated for the benefit of 162 Python access to Java classes, even though such methods are not strictly 163 necessary for the Java classes to work amongst themselves. Such methods 164 are only generated when many methods of the same name reside in a given 165 class, since where Java distinguishes between them on the basis of the 166 signatures, Python permits only one method of a given name and needs 167 additional logic to dispatch to the actual method implementations on the 168 basis of the types of the incoming values. The implementation of the 169 dispatcher method is naive and does not try to order the type checks and 170 dispatches according to the specificity of the parameter types; thus, a 171 more reliable but more verbose way of ensuring that the correct method in 172 such cases is called from a Python program may be to use the special long 173 method name (eg. <code>setValue____I_</code>).</li> 174 <li>Imported and translated bytecode is not written out or cached. This 175 means that a fair amount of work happens every time you need to import 176 Java classes, although the generation of .pyc files could be introduced 177 provided that it captured the slightly different import semantics of 178 Java; for example, you can import classes belonging to a package from 179 several places on the PYTHONPATH, and this is something that generally 180 isn't allowed/supported with the classic Python module import 181 mechanisms.</li> 182 <li>Most Java programs need standard Java library (also known as the Java 183 API) classes; indeed, with <code>java.lang.String</code> and seemingly 184 <code>java.lang.StringBuffer</code> required just for the usage of 185 strings, and with the classic <code>main</code> method having 186 <code>String[]</code> in its signature, some kind of library 187 implementation is obviously necessary. Whilst importing everything from 188 the .jar files bundled with Sun's JRE might be tempting, there may be a 189 certain amount of native calling going on in secret which would defeat 190 this approach, and anyone seriously interested in running Java code in 191 Python should really want to steer clear of such proprietary dependencies 192 anyway. It could be possible to wrap and make use of GNU Classpath or 193 some other open source Java API implementation, but the cleanest (but not 194 necessarily the least time-consuming) approach is surely to implement the 195 standard API classes in Python, and a package called <code>java</code> is 196 included which contains some fairly quick and dirty implementations to 197 get things working.</li> 198 </ul> 199 200 <h2>Suggestions for Python Improvements</h2> 201 <ul> 202 <li>Make the bytecode interpreter more robust when encountering badly 203 behaved bytecode, consider bytecode verification and other exciting 204 features.</li> 205 <li>Allow new-style objects as exceptions. Actually, just do something 206 about the whole old-style vs. new-style class thing!</li> 207 <li>Allow possible optimisation for things like statically predetermined 208 method calls. The debate about static typing intersects slightly with the 209 need to define methods with parameters of particular types, but 210 supporting Java-style method "coexistence" (or multimethods, or whatever 211 the proper name is) would presumably involve doing lots of things to the 212 language that were once thought to be highly un-Pythonic. Besides, the 213 need to interoperate with statically typed languages shouldn't dictate 214 the design of Python, especially if better type systems could be adopted 215 instead, leaving the static typing glue for strictly special 216 occasions.</li> 217 <li>Not that threaded Java programs have been run on Python yet, but with 218 Python's current threading architecture I'd expect some 219 disappointment.</li> 220 </ul> 221 </body> 222 </html>