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