Permalink
Browse files

Merge branch 'develop'

  • Loading branch information...
Mike Johnson
Mike Johnson committed Jun 6, 2012
2 parents 87bf00e + 53d5085 commit d3d3e48e61e66f01867a212ad32c0c86e3e28976
Showing with 178 additions and 102 deletions.
  1. +2 −0 .gitignore
  2. +7 −10 ChangeLog
  3. +21 −37 README.rst
  4. +1 −1 commands/test.py
  5. +36 −8 jep/hook.py
  6. +1 −1 jep/version.py
  7. +14 −13 src/jep/pyembed.c
  8. +20 −25 src/jep/pyjarray.c
  9. +9 −6 src/jep/util.c
  10. +2 −1 tests/__init__.py
  11. BIN tests/lib/sqlitejdbc-v056.jar
  12. +13 −0 tests/test_import.py
  13. +52 −0 tests/test_jdbc.py
View
@@ -23,3 +23,5 @@ build
dist
*.pyc
MANIFEST
.DS_Store
.idea
View
@@ -1,14 +1,11 @@
2012-04-09 Mike Johnson <mike@mrj0.com>
* setup.py: distutils build, pypi integration
* tests: unittesting implemented in python
* jep: added `jep` command line script for launching console.py
* exception mapping (dynamic creation of python exceptions) no longer supported
* pyjobject.c: implement richcompare using Java .equals
* pyjobject.c: missing attribute raises AttributeError
* pyjobject.c: don't change optimization flag by default
* pyjarray.c: fix for iterator, so list() works on jarrays
2012-05-05 3.1.0 - Mike Johnson <mike@mrj0.com>
* lazy load classes imported via import hook
2007-03-19 Mike Johnson <mike@mrj0.com>
2012-03-06 3.0.0 - Mike Johnson <mike@mrj0.com>
* project uses distutils now, is pip installable
* added a proper import hook
2007-03-19 Mike Johnson <mrjohnson0@users.sourceforge.net>
* pyembed.c: patch from Jon Wright to convert packed strings to float array in java.
* pyembed.c: return jarray object in invoke and getValue
* pyembed.c: throw exception if invocation object not found
View
@@ -27,16 +27,16 @@ response.
Jep is licensed zlib/libpng license to avoid linking issues.
Dependencies
------------
* Python version >= 2.6
* JNI >= 1.4
Installation
------------
Simply run ``pip install jep``.
Dependencies
------------
* Python version >= 2.6
* JNI >= 1.4
*Building on Mac OS X*
OS X requires the `Java Developer Package and Xcode
@@ -53,33 +53,30 @@ on Windows has not worked in recent years because the compilers are
not widely available. If an OpenJDK build used MinGW, that'd be
much more likely to work.
Running scripts
---------------
The ``setup.py`` script will provide a ``jep`` shortcut to make launching Java and Python easier.
::
$ jep
>>> from java.lang import System
>>> System.out.println('hello, world')
hello, world
>>>
Running on \*nix
-----------------
Due to some (common) difficulties with Java and C projects
that dlopen libraries, you may need to set LD_PRELOAD environment
variable. That's in addition to setting LD_LIBRARY_PATH if you've
installed libjep into a directory not cached by ld.so.
For example, my Tomcat startup.sh script starts with this:
::
#!/bin/sh
# force system to load python
export LD_PRELOAD=/usr/lib/libpython2.7.so
# this is where my libjep.so is.
export LD_LIBRARY_PATH=/usr/local/lib
The libpython used here is whatever you've compiled jep against. If
you don't know, try this command:
See the contents of the installed ``jep`` script for an example how to do this.
The script should have the correct values for your interpreter and virtualenv
(if present).
::
$ ldd /usr/local/lib/libjep.so | grep python
/usr/lib/libpython2.7.so (0x00007f74adfbd000)
That's the libpython you want to set in LD_PRELOAD.
Running the tests
-----------------
@@ -90,19 +87,6 @@ The tests are run from setup.py:
$ python setup.py test
Running scripts
---------------
There is a ``jep`` shell script to make launching Java and Python a little easier.
::
$ jep
>>> from java.lang import System
>>> System.out.println('hello, world')
hello, world
>>>
Support
-------
View
@@ -18,4 +18,4 @@ def finalize_options(self):
pass
def run(self):
spawn(['java', '-cp', 'build/java/', 'jep.Test'])
spawn(['java', '-cp', 'build/java/:tests/lib/sqlitejdbc-v056.jar', 'jep.Test'])
View
@@ -1,6 +1,31 @@
from _jep import *
from _jep import findClass
import sys
import imp
from types import ModuleType
class module(ModuleType):
"""Lazy load classes not found at runtime.
Introspecting Java packages is difficult, there is not a good
way to get a list of all classes for a package. By providing
a __getattr__ implementation for modules, this class can
try to find classes manually.
Due to this Java limitation, some classes will not appear in dir()
but will import correctly.
"""
def __getattr__(self, name):
try:
return super(module, self).__getattribute__(name)
except AttributeError as ae:
try:
clazz = findClass('{0}.{1}'.format(self.__name__, name))
setattr(self, name, clazz)
return clazz
except Exception:
# should raise AttributeError, not JepException
raise ae
class JepImporter(object):
@@ -14,19 +39,22 @@ def find_module(self, fullname, path=None):
def load_module(self, fullname):
if fullname in sys.modules:
return fullname
mod = imp.new_module(fullname)
mod.__loader__ = self
return sys.modules[fullname]
mod = module(fullname)
mod.__dict__.update({
'__loader__': self,
'__path__': [],
'__file__': '<java>',
})
sys.modules[fullname] = mod
mod.__path__ = []
mod.__file__ = '<java>'
# list of classes in package
for name in self.classlist.get(fullname):
setattr(mod, name.split('.')[-1], findClass(name))
return mod
sys.meta_path = [importer for importer in sys.meta_path if isinstance(importer, JepImporter)]
sys.meta_path.append(JepImporter())
View
@@ -1,2 +1,2 @@
__VERSION__ = '3.0.0'
__VERSION__ = '3.0.1'
VERSION = __VERSION__
View
@@ -222,7 +222,7 @@ void pyembed_shutdown(void) {
intptr_t pyembed_thread_init(JNIEnv *env, jobject cl, jobject caller) {
JepThread *jepThread;
PyObject *tdict, *main_module, *globals;
PyObject *tdict, *mod_main, *globals;
if(cl == NULL) {
THROW_JEP(env, "Invalid Classloader.");
@@ -247,14 +247,14 @@ intptr_t pyembed_thread_init(JNIEnv *env, jobject cl, jobject caller) {
if(!cache_primitive_classes(env))
printf("WARNING: failed to get primitive class types.\n");
main_module = PyImport_AddModule("__main__"); /* borrowed */
if(main_module == NULL) {
mod_main = PyImport_AddModule("__main__"); /* borrowed */
if(mod_main == NULL) {
THROW_JEP(env, "Couldn't add module __main__.");
PyEval_ReleaseLock();
return 0;
}
globals = PyModule_GetDict(main_module);
globals = PyModule_GetDict(mod_main);
Py_INCREF(globals);
// init static module
@@ -394,7 +394,7 @@ static PyObject* pyembed_jproxy(PyObject *self, PyObject *args) {
jclass clazz;
jobject cl;
jobject classes;
int inum, i;
Py_ssize_t inum, i;
jobject proxy;
if(!PyArg_ParseTuple(args, "OO!:jproxy",
@@ -437,7 +437,7 @@ static PyObject* pyembed_jproxy(PyObject *self, PyObject *args) {
// now convert string list to java array
classes = (*env)->NewObjectArray(env, inum, JSTRING_TYPE, NULL);
classes = (*env)->NewObjectArray(env, (jsize) inum, JSTRING_TYPE, NULL);
if(process_java_exception(env) || !classes)
return NULL;
@@ -448,12 +448,12 @@ static PyObject* pyembed_jproxy(PyObject *self, PyObject *args) {
item = PyList_GET_ITEM(interfaces, i);
if(!PyString_Check(item))
return PyErr_Format(PyExc_ValueError, "Item %i not a string.", i);
return PyErr_Format(PyExc_ValueError, "Item %zd not a string.", i);
str = PyString_AsString(item);
jstr = (*env)->NewStringUTF(env, (const char *) str);
(*env)->SetObjectArrayElement(env, classes, i, jstr);
(*env)->SetObjectArrayElement(env, classes, (jsize) i, jstr);
(*env)->DeleteLocalRef(env, jstr);
}
@@ -507,7 +507,7 @@ static PyObject* pyembed_jimport(PyObject *self, PyObject *args) {
jclass clazz;
jobject cl;
JepThread *jepThread;
int len, i;
Py_ssize_t len, i;
jobjectArray jar;
char *name;
@@ -623,7 +623,7 @@ static PyObject* pyembed_jimport(PyObject *self, PyObject *args) {
PyObject *pclass = NULL;
PyObject *memberList = NULL;
member = (*env)->GetObjectArrayElement(env, jar, i);
member = (*env)->GetObjectArrayElement(env, jar, (jsize) i);
if(process_import_exception(env) || !member) {
(*env)->DeleteLocalRef(env, member);
continue;
@@ -653,7 +653,8 @@ static PyObject* pyembed_jimport(PyObject *self, PyObject *args) {
PyString_AsString(PyTuple_GET_ITEM(fromlist, 0))[0] != '*') {
PyObject *pymember;
int found, i, len;
int found;
Py_ssize_t i, len;
pymember = PyList_GET_ITEM(
memberList,
@@ -1177,7 +1178,7 @@ jobject pyembed_box_py(JNIEnv *env, PyObject *result) {
if(PyInt_Check(result)) {
jclass clazz;
jlong i = PyInt_AS_LONG(result);
jint i = (jint) PyInt_AS_LONG(result);
clazz = (*env)->FindClass(env, "java/lang/Integer");
@@ -1547,7 +1548,7 @@ static int maybe_pyc_file(FILE *fp,
/* Read only two bytes of the magic. If the file was opened in
text mode, the bytes 3 and 4 of the magic (\r\n) might not
be read as they are on disk. */
long halfmagic = PyImport_GetMagicNumber() & 0xFFFF;
unsigned int halfmagic = (unsigned int) PyImport_GetMagicNumber() & 0xFFFF;
unsigned char buf[2];
/* Mess: In case of -x, the stream is NOT at its start now,
and ungetc() was used to push back the first newline,
Oops, something went wrong.

0 comments on commit d3d3e48

Please sign in to comment.