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>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 </ul> 183 184 <h2>Suggestions for Python Improvements</h2> 185 <ul> 186 <li>Make the bytecode interpreter more robust when encountering badly 187 behaved bytecode, consider bytecode verification and other exciting 188 features.</li> 189 <li>Allow new-style objects as exceptions. Actually, just do something 190 about the whole old-style vs. new-style class thing!</li> 191 <li>Allow possible optimisation for things like statically predetermined 192 method calls. The debate about static typing intersects slightly with the 193 need to define methods with parameters of particular types, but 194 supporting Java-style method "coexistence" (or multimethods, or whatever 195 the proper name is) would presumably involve doing lots of things to the 196 language that were once thought to be highly un-Pythonic. Besides, the 197 need to interoperate with statically typed languages shouldn't dictate 198 the design of Python, especially if better type systems could be adopted 199 instead, leaving the static typing glue for strictly special 200 occasions.</li> 201 <li>Not that threaded Java programs have been run on Python yet, but with 202 Python's current threading architecture I'd expect some 203 disappointment.</li> 204 </ul> 205 </body> 206 </html>