paul@140 | 1 | This file contains some information on the essential concepts and principles
|
paul@140 | 2 | involved in the use of this software.
|
paul@140 | 3 |
|
paul@140 | 4 | Installation
|
paul@140 | 5 | ------------
|
paul@140 | 6 |
|
paul@140 | 7 | Usually, I issue this command first:
|
paul@140 | 8 |
|
paul@140 | 9 | python setup.py build
|
paul@140 | 10 |
|
paul@140 | 11 | The following should, in any case, be sufficient:
|
paul@140 | 12 |
|
paul@140 | 13 | python setup.py install
|
paul@140 | 14 |
|
paul@140 | 15 | I don't think distutils supports uninstall, but the installation just adds the
|
paul@140 | 16 | java and javaclass packages to your site-packages directory and the
|
paul@140 | 17 | runclass.py program to the same bin directory that python resides in.
|
paul@140 | 18 |
|
paul@122 | 19 | Class Search Paths
|
paul@122 | 20 | ------------------
|
paul@122 | 21 |
|
paul@122 | 22 | Java classes belonging to packages are located using sys.path or PYTHONPATH
|
paul@122 | 23 | in the same way that they would be located using the Java classpath (or
|
paul@122 | 24 | CLASSPATH environment variable). Thus, the rules for locating package
|
paul@122 | 25 | classes are as follows:
|
paul@122 | 26 |
|
paul@122 | 27 | * Classes residing within plain directories which represent a package
|
paul@122 | 28 | hierarchy can be accessed by putting the parent directory of the top of
|
paul@122 | 29 | the package hierarchy on the PYTHONPATH (or sys.path). For example, a
|
paul@122 | 30 | package called mypackage, represented by a directory of the same name at
|
paul@122 | 31 | /home/java/classes/mypackage, would be made accessible by adding the
|
paul@122 | 32 | /home/java/classes directory to the PYTHONPATH.
|
paul@122 | 33 |
|
paul@122 | 34 | * Classes residing within .jar files can be accessed by putting the path to
|
paul@122 | 35 | each .jar file on the PYTHONPATH. For example, a package called
|
paul@122 | 36 | mypackage, represented by a file located at /home/java/lib/mypackage.jar,
|
paul@122 | 37 | would be made accessible by adding the /home/java/lib/mypackage.jar file
|
paul@122 | 38 | to the PYTHONPATH.
|
paul@122 | 39 |
|
paul@122 | 40 | Note that classes not belonging to a package cannot be accessed via such
|
paul@122 | 41 | search paths and are made available using a special module (see "Non-package
|
paul@122 | 42 | Classes" below).
|
paul@122 | 43 |
|
paul@122 | 44 | Importing Classes
|
paul@122 | 45 | -----------------
|
paul@99 | 46 |
|
paul@140 | 47 | In Python, the following statement should be enough to enable Java class
|
paul@140 | 48 | import:
|
paul@99 | 49 |
|
paul@140 | 50 | import javaclass.classhook
|
paul@99 | 51 |
|
paul@140 | 52 | (Other modules reside in the javaclass package, so it is possible to access
|
paul@140 | 53 | them without changing Python's import mechanisms, should such modification be
|
paul@140 | 54 | undesirable or unnecessary.)
|
paul@99 | 55 |
|
paul@122 | 56 | Importing Non-package Classes
|
paul@122 | 57 | -----------------------------
|
paul@99 | 58 |
|
paul@122 | 59 | Classes which do not belong to a package are only accessible when residing
|
paul@122 | 60 | in the current working directory of any program attempting to use them. Such
|
paul@122 | 61 | classes will not be made available automatically, but must be imported from
|
paul@122 | 62 | a special module called __this__.
|
paul@99 | 63 |
|
paul@122 | 64 | * Usage of the "import __this__" statement will cause all classes in the
|
paul@122 | 65 | current directory to be made available within the __this__ module.
|
paul@99 | 66 |
|
paul@122 | 67 | * Usage of the "from __this__ import" construct will cause all classes in
|
paul@122 | 68 | the current directory to be processsed, but only named classes will be
|
paul@122 | 69 | made available in the global namespace unless "*" was specified (which
|
paul@122 | 70 | will, as usual, result in all such classes being made available).
|
paul@99 | 71 |
|
paul@122 | 72 | Running Java Classes
|
paul@122 | 73 | --------------------
|
paul@99 | 74 |
|
paul@122 | 75 | Java classes with a public, static main method can be run directly using the
|
paul@122 | 76 | runclass.py program.
|
paul@99 | 77 |
|
paul@122 | 78 | * Free-standing classes (ie. not belonging to packages) can be run from
|
paul@122 | 79 | the directory in which they reside. For example, suitable classes in the
|
paul@122 | 80 | tests directory would be run as follows:
|
paul@99 | 81 |
|
paul@122 | 82 | cd tests
|
paul@122 | 83 | runclass.py MainTest hello world
|
paul@122 | 84 |
|
paul@122 | 85 | * Classes residing in packages can be run by ensuring that the packages
|
paul@122 | 86 | are registered on the PYTHONPATH (see "Class Search Paths" above). Then,
|
paul@122 | 87 | the testpackage.MainTest class (for example) would be run as follows:
|
paul@99 | 88 |
|
paul@122 | 89 | runclass.py testpackage.MainTest hello world
|
paul@99 | 90 |
|
paul@99 | 91 | Accessing Python Libraries from Java
|
paul@99 | 92 | ------------------------------------
|
paul@99 | 93 |
|
paul@99 | 94 | To wrap Python libraries for use with Java, skeleton classes need to be
|
paul@99 | 95 | compiled corresponding to each of the wrapped classes. Each of the methods
|
paul@99 | 96 | in the skeleton classes can be empty (or return any permissible value) since
|
paul@99 | 97 | the only purpose they serve is to provide the Java compiler with information
|
paul@99 | 98 | about the Python libraries.
|
paul@99 | 99 |
|
paul@99 | 100 | 1. Compile the skeleton classes:
|
paul@99 | 101 |
|
paul@140 | 102 | javac examples/Tkinter/tkjava/*.java
|
paul@99 | 103 |
|
paul@99 | 104 | 2. Compile the Java classes which use the wrapped Python libraries:
|
paul@99 | 105 |
|
paul@140 | 106 | javac -classpath examples/Tkinter examples/Tkinter/Application.java
|
paul@99 | 107 |
|
paul@99 | 108 | 3. Run the wrap.py tool on the directory where the skeleton class files
|
paul@99 | 109 | reside, providing the name of the Python package or module being
|
paul@99 | 110 | wrapped. This converts the directory into a Python package:
|
paul@99 | 111 |
|
paul@140 | 112 | python tools/wrap.py examples/Tkinter/tkjava Tkinter
|
paul@99 | 113 |
|
paul@140 | 114 | Since the Java class files, if left in the processed directory, would be
|
paul@140 | 115 | detected and imported using the special import hook, and since this would
|
paul@140 | 116 | result in two conflicting implementations being imported (with possibly the
|
paul@140 | 117 | non-functional Java classes being made available instead of the generated
|
paul@140 | 118 | wrapper classes), the wrap.py tool removes all processed class files,
|
paul@140 | 119 | leaving only Python source files in the processed directory.
|
paul@99 | 120 |
|
paul@99 | 121 | 4. The Java classes which use the wrapped Python libraries can now be
|
paul@140 | 122 | imported and used as described above. The wrapper package (tkjava in
|
paul@122 | 123 | the above example) needs to reside in sys.path or PYTHONPATH, as must
|
paul@140 | 124 | the wrapped library (Tkinter in the above example).
|
paul@140 | 125 |
|
paul@140 | 126 | cd examples/Tkinter
|
paul@140 | 127 | runclass.py Application
|
paul@99 | 128 |
|
paul@99 | 129 | Issues
|
paul@99 | 130 | ------
|
paul@99 | 131 |
|
paul@92 | 132 | Investigate better exception raising. Currently, exceptions have to be
|
paul@92 | 133 | derived from object so that object.__new__ can be used upon them. However,
|
paul@92 | 134 | this seems to prevent them from being raised, and they need to be wrapped
|
paul@92 | 135 | within Exception so that the information can be transmitted to the
|
paul@92 | 136 | exception's handler.
|
paul@92 | 137 |
|
paul@92 | 138 | Consider nicer ways of writing the method names in Python, perhaps using a
|
paul@92 | 139 | function which takes the individual parameter types as arguments.
|