1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4 <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <meta content="Apache Forrest" name="Generator">
6 <meta name="Forrest-version" content="0.8">
7 <meta name="Forrest-skin-name" content="pelt">
8 <title>JCC Features</title>
9 <link type="text/css" href="../../skin/basic.css" rel="stylesheet">
10 <link media="screen" type="text/css" href="../../skin/screen.css" rel="stylesheet">
11 <link media="print" type="text/css" href="../../skin/print.css" rel="stylesheet">
12 <link type="text/css" href="../../skin/profile.css" rel="stylesheet">
13 <script src="../../skin/getBlank.js" language="javascript" type="text/javascript"></script><script src="../../skin/getMenu.js" language="javascript" type="text/javascript"></script><script src="../../skin/fontsize.js" language="javascript" type="text/javascript"></script>
14 <link rel="shortcut icon" href="../../">
16 <body onload="init()">
17 <script type="text/javascript">ndeSetTextSize();</script>
22 <div class="breadtrail">
23 <a href="http://www.apache.org/">apache</a> > <a href="http://lucene.apache.org/">lucene</a><script src="../../skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
32 <div class="grouplogo">
33 <a href="http://lucene.apache.org/"><img class="logoImage" alt="Lucene" src="../../images/lucene_green_150.gif" title="Lucene Description"></a>
41 <div class="projectlogoA1">
42 <a href="http://lucene.apache.org/pylucene/"><img class="logoImage" alt="PyLucene" src="../../images/project.png" title="PyLucene Description"></a>
52 <a class="unselected" href="../../index.html">PyLucene</a>
55 <a class="selected" href="../../jcc/index.html">JCC</a>
64 <div id="publishedStrip">
68 <div id="level2tabs"></div>
72 <script type="text/javascript"><!--
73 document.write("Last Published: " + document.lastModified);
79 <div class="breadtrail">
90 <div onclick="SwitchMenu('menu_selected_1.1', '../../skin/')" id="menu_selected_1.1Title" class="menutitle" style="background-image: url('../../skin/images/chapter_open.gif');">JCC</div>
91 <div id="menu_selected_1.1" class="selectedmenuitemgroup" style="display: block;">
92 <div onclick="SwitchMenu('menu_1.1.1', '../../skin/')" id="menu_1.1.1Title" class="menutitle">About</div>
93 <div id="menu_1.1.1" class="menuitemgroup">
94 <div class="menuitem">
95 <a href="../../jcc/index.html" title="Welcome to JCC">Index</a>
98 <div onclick="SwitchMenu('menu_selected_1.1.2', '../../skin/')" id="menu_selected_1.1.2Title" class="menutitle" style="background-image: url('../../skin/images/chapter_open.gif');">Documentation</div>
99 <div id="menu_selected_1.1.2" class="selectedmenuitemgroup" style="display: block;">
100 <div class="menuitem">
101 <a href="../../jcc/documentation/install.html">Installation</a>
103 <div class="menupage">
104 <div class="menupagetitle">Features</div>
106 <div class="menuitem">
107 <a href="../../jcc/documentation/javadoc/index.html">Javadoc</a>
111 <div id="credit"></div>
112 <div id="roundbottom">
113 <img style="display: none" class="corner" height="15" width="15" alt="" src="../../skin/images/rc-b-l-15-1body-2menu-3menu.png"></div>
117 <div id="credit2"></div>
126 <div title="Portable Document Format" class="pdflink">
127 <a class="dida" href="readme.pdf"><img alt="PDF -icon" src="../../skin/images/pdfdoc.gif" class="skin"><br>
130 <h1>JCC Features</h1>
131 <div id="minitoc-area">
134 <a href="#install">Installing JCC</a>
137 <a href="#invoking">Invoking JCC</a>
140 <a href="#use">Generating C++ and Python wrappers with JCC</a>
143 <a href="#classpath">Classpath considerations</a>
146 <a href="#setuptools">Using distutils vs setuptools</a>
149 <a href="#egg">Distributing an egg</a>
152 <a href="#api">JCC's runtime API functions</a>
155 <a href="#casting">Type casting and instance checks</a>
158 <a href="#generics">Handling generic classes</a>
161 <a href="#arrays">Handling arrays</a>
164 <a href="#exceptions">Exception reporting</a>
167 <a href="#extensions">Writing Java class extensions in Python</a>
170 <a href="#embedding">Embedding a Python VM in a Java VM</a>
173 <a href="#python">Pythonic protocols</a>
178 <div class="warning">
179 <div class="label">Warning</div>
180 <div class="content">
181 Before calling any PyLucene API that requires the Java VM, start it by
182 calling <span class="codefrag">initVM(classpath, ...)</span>. More about this function
183 in <a href="#api">here</a>.
187 <a name="N10017"></a><a name="install"></a>
188 <h2 class="boxed">Installing JCC</h2>
189 <div class="section">
191 JCC is a Python extension written in Python and C++. It requires a
192 Java Runtime Environment (JRE) to operate as it uses Java's
193 reflection APIs to do its work. It is built and installed
194 via <span class="codefrag">distutils</span> or <span class="codefrag">setuptools</span>.
197 See <a href="../../jcc/documentation/install.html">installation</a> for more
198 information and operating system specific notes.
202 <a name="N1002E"></a><a name="invoking"></a>
203 <h2 class="boxed">Invoking JCC</h2>
204 <div class="section">
206 JCC is installed as a package and how to invoke it depends on the
211 <li>python 2.7: <span class="codefrag">python -m jcc</span>
214 <li>python 2.6: <span class="codefrag">python -m jcc.__main__</span>
217 <li>python 2.5: <span class="codefrag">python -m jcc</span>
223 <li>no setuptools: <span class="codefrag">python </span><em><span class="codefrag">site-packages</span></em><span class="codefrag">/jcc/__init__.py</span>
226 <li>with setuptools: <span class="codefrag">python </span><em><span class="codefrag">site-packages</span></em>/<em><span class="codefrag">jcc egg directory</span></em><span class="codefrag">/jcc/__init__.py</span>
233 <li>python 2.3: <span class="codefrag">python </span><em><span class="codefrag">site-packages</span></em>/<em><span class="codefrag">jcc egg directory</span></em><span class="codefrag">/jcc/__init__.py</span>
239 <a name="N10076"></a><a name="use"></a>
240 <h2 class="boxed">Generating C++ and Python wrappers with JCC</h2>
241 <div class="section">
243 JCC started as a C++ code generator for hiding the gory details of
244 accessing methods and fields on Java classes via
245 Java's <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html">Native Invocation Interface</a>.
246 These C++ wrappers make it possible to access a Java object as if it
247 was a regular C++ object very much like GCJ's
248 <a href="http://gcc.gnu.org/onlinedocs/gcj/About-CNI.html">CNI
252 It then became apparent that JCC could also generate the C++
253 wrappers for making these classes available to Python. Every class
254 that gets thus wrapped becomes a
255 <a href="http://docs.python.org/ext/defining-new-types.html">CPython
259 JCC generates wrappers for all public classes that are requested by
260 name on the command line or via the <span class="codefrag">--jar</span> command line
261 argument. It generates wrapper methods for all public methods and
262 fields on these classes whose return type and parameter types are
263 found in one of the following ways:
268 the type is one of the requested classes
272 the type is one of the requested classes' superclass or implemented
277 the type is available from one of the packages listed via the
278 <span class="codefrag">--package</span> command line argument
283 Overloaded methods are supported and are selected at runtime on the
284 basis of the type and number of arguments passed in.
287 JCC does not generate wrappers for methods or fields which don't
288 satisfy these requirements. Thus, JCC can avoid generating code for
289 runaway transitive closures of type dependencies.
292 JCC generates property accessors for a property
293 called <em><span class="codefrag">field</span></em> when it finds Java methods
294 named <span class="codefrag">set</span><em><span class="codefrag">Field</span></em><span class="codefrag">(value)</span>,
295 <span class="codefrag">get</span><em><span class="codefrag">Field</span></em><span class="codefrag">()</span> or
296 <span class="codefrag">is</span><em><span class="codefrag">Field</span></em><span class="codefrag">()</span>.
299 The C++ wrappers are declared in a C++ namespace structure that
300 mirrors the Java classes' Java packages. The Python types are
301 declared in a flat namespace at the top level of the resulting
302 Python extension module.
305 JCC's command-line arguments are best illustrated via the PyLucene
309 $ python -m jcc # run JCC to wrap
310 --jar lucene.jar # all public classes in the lucene jar file
311 --jar analyzers.jar # and the lucene analyzers contrib package
312 --jar snowball.jar # and the snowball contrib package
313 --jar highlighter.jar # and the highlighter contrib package
314 --jar regex.jar # and the regex search contrib package
315 --jar queries.jar # and the queries contrib package
316 --jar extensions.jar # and the Python extensions package
317 --package java.lang # including all dependencies found in the
319 --package java.util # and the java.util package
320 --package java.io # and the java.io package
321 java.lang.System # and to explicitely wrap java.lang.System
322 java.lang.Runtime # as well as java.lang.Runtime
323 java.lang.Boolean # and java.lang.Boolean
324 java.lang.Byte # and java.lang.Byte
325 java.lang.Character # and java.lang.Character
326 java.lang.Integer # and java.lang.Integer
327 java.lang.Short # and java.lang.Short
328 java.lang.Long # and java.lang.Long
329 java.lang.Double # and java.lang.Double
330 java.lang.Float # and java.lang.Float
331 java.text.SimpleDateFormat
332 # and java.text.SimpleDateFormat
334 # and java.io.StringReader
335 java.io.InputStreamReader
336 # and java.io.InputStreamReader
337 java.io.FileInputStream
338 # and java.io.FileInputStream
339 java.util.Arrays # and java.util.Arrays
340 --exclude org.apache.lucene.queryParser.Token
341 # while explicitely not wrapping
342 # org.apache.lucene.queryParser.Token
343 --exclude org.apache.lucene.queryParser.TokenMgrError
344 # nor org.apache.lucene.queryParser.TokenMgrError
345 --exclude org.apache.lucene.queryParser.ParseException
346 # nor.apache.lucene.queryParser.ParseException
347 --python lucene # generating Python wrappers into a module
349 --version 2.4.0 # giving the Python extension egg version 2.4.0
350 --mapping org.apache.lucene.document.Document
351 'get:(Ljava/lang/String;)Ljava/lang/String;'
352 # asking for a Python mapping protocol wrapper
353 # for get access on the Document class by
354 # calling its get method
355 --mapping java.util.Properties
356 'getProperty:(Ljava/lang/String;)Ljava/lang/String;'
357 # asking for a Python mapping protocol wrapper
358 # for get access on the Properties class by
359 # calling its getProperty method
360 --sequence org.apache.lucene.search.Hits
362 'doc:(I)Lorg/apache/lucene/document/Document;'
363 # asking for a Python sequence protocol wrapper
364 # for length and get access on the Hits class by
365 # calling its length and doc methods
366 --files 2 # generating all C++ classes into about 2 .cpp
368 --build # and finally compiling the generated C++ code
369 # into a Python egg via setuptools - when
370 # installed - or a regular Python extension via
371 # distutils or setuptools otherwise
372 --module collections.py
373 # copying the collections.py module into the egg
374 --install # installing it into Python's site-packages
378 There are limits to both how many files can fit on the command line
379 and how large a C++ file the C++ compiler can handle. By default,
380 JCC generates one large C++ file containing the source code for all
384 Using the <span class="codefrag">--files</span> command line argument, this behaviour
385 can be tuned to workaround various limits:<br>
391 to break up the large wrapper class file into about 2 files:<br>
393 <span class="codefrag">--files 2</span>
398 to break up the large wrapper class file into about 10 files:<br>
400 <span class="codefrag"> --files 10</span>
405 to generate one C++ file per Java class wrapped:<br>
407 <span class="codefrag">--files separate</span>
413 The <span class="codefrag">--prefix</span> and <span class="codefrag">--root</span> arguments are
414 passed through to <span class="codefrag">distutils</span>' <span class="codefrag">setup()</span>.
418 <a name="N10108"></a><a name="classpath"></a>
419 <h2 class="boxed">Classpath considerations</h2>
420 <div class="section">
422 When generating wrappers for Python, the JAR files passed to JCC
423 via <span class="codefrag">--jar</span> are copied into the resulting Python extension
424 egg as resources and added to the extension
425 module's <span class="codefrag">CLASSPATH</span> variable. Classes or JAR files that
426 are required by the classes contained in the argument JAR files need
427 to be made findable via JCC's <span class="codefrag">--classpath</span> command line
428 argument. At runtime, these need to be appended to the
429 extension's <span class="codefrag">CLASSPATH</span> variable before starting the VM
430 with <span class="codefrag">initVM(CLASSPATH)</span>.
433 To have such required jar files also automatically copied into
434 resulting Python extension egg and added to the classpath at build
435 and runtime, use the <span class="codefrag">--include</span> option. This option
436 works like the <span class="codefrag">--jar</span> option except that no wrappers are
437 generated for the classes contained in them unless they're
438 explicitely named on the command line.
441 When more than one JCC-built extension module is going to be used in
442 the same Python VM and these extension modules share Java classes,
443 only one extension module should be generated with wrappers for these
444 shared classes. The other extension modules must be built by importing
445 the one with the shared classes by using the <span class="codefrag">--import</span>
446 command line parameter. This ensures that only one copy of the
447 wrappers for the shared classes are generated and that they are
448 compatible among all extension modules sharing them.
452 <a name="N10130"></a><a name="setuptools"></a>
453 <h2 class="boxed">Using distutils vs setuptools</h2>
454 <div class="section">
456 By default, when building a Python extension,
457 if <span class="codefrag">setuptools</span> is found to be installed, it is used
458 over <span class="codefrag">distutils</span>. If you want to force the use
459 of <span class="codefrag">distutils</span> over <span class="codefrag">setuptools</span>, use
460 the <span class="codefrag">--use-distutils</span> command line argument.
464 <a name="N1014E"></a><a name="egg"></a>
465 <h2 class="boxed">Distributing an egg</h2>
466 <div class="section">
468 The <span class="codefrag">--bdist</span> option can be used to ask JCC to
469 invoke <span class="codefrag">distutils</span> with <span class="codefrag">bdist</span>
470 or <span class="codefrag">setuptools</span>
471 with <span class="codefrag">bdist_egg</span>. If <span class="codefrag">setuptools</span> is used,
472 the resulting egg has to be installed with the
473 <a href="http://peak.telecommunity.com/DevCenter/EasyInstall"><span class="codefrag">easy_install</span></a>
474 installer which is normally part of a Python installation that
475 includes <span class="codefrag">setuptools</span>.
479 <a name="N10172"></a><a name="api"></a>
480 <h2 class="boxed">JCC's runtime API functions</h2>
481 <div class="section">
483 JCC includes a small runtime component that is compiled into any
484 Python extension it produces.
487 This runtime component makes it possible to manage the Java VM from
488 Python. Because a Java VM can be configured with a myriad of
489 options, it is not automatically started when the resulting Python
490 extension module is loaded into the Python interpreter.
493 Instead, the <span class="codefrag">initVM()</span> function must be called from the
494 main thread before using any of the wrapped classes. It takes the
495 following keyword arguments:
501 <span class="codefrag">classpath</span>
503 A string containing one or more directories or jar files for the
504 Java VM to search for classes. Every Python extension produced by
505 JCC exports a <span class="codefrag">CLASSPATH</span> variable that is hardcoded to
506 the jar files that it was produced from. A copy of each jar file
507 is installed as a resource file with the extension when JCC is
508 invoked with the <span class="codefrag">--install</span> command line argument.
509 This parameter is optional and defaults to the
510 <span class="codefrag">CLASSPATH</span> string exported by the module
511 <span class="codefrag">initVM</span> is imported from.
513 >>> import lucene
514 >>> lucene.initVM(classpath=lucene.CLASSPATH)
521 <span class="codefrag">initialheap</span>
523 The initial amount of Java heap to start the Java VM with. This
524 argument is a string that follows the same syntax as the
525 similar <span class="codefrag">-Xms</span> java command line argument.
527 >>> import lucene
528 >>> lucene.initVM(initialheap='32m')
529 >>> lucene.Runtime.getRuntime().totalMemory()
537 <span class="codefrag">maxheap</span>
539 The maximum amount of Java heap that could become available to the
540 Java VM. This argument is a string that follows the same syntax as
541 the similar <span class="codefrag">-Xmx</span> java command line argument.
546 <span class="codefrag">maxstack</span>
548 The maximum amount of stack space that available to the Java
549 VM. This argument is a string that follows the same syntax as the
550 similar <span class="codefrag">-Xss</span> java command line argument.
555 <span class="codefrag">vmargs</span>
557 A string of comma separated additional options to pass to the VM
558 startup rountine. These are passed through as-is. For example:
560 >>> import lucene
561 >>> lucene.initVM(vmargs='-Xcheck:jni,-verbose:jni,-verbose:gc')
568 The <span class="codefrag">initVM()</span> and <span class="codefrag">getVMEnv()</span> functions
569 return a JCCEnv object that has a few utility methods on it:
575 <span class="codefrag">attachCurrentThread(name, asDaemon)</span>
577 Before a thread created in Python or elsewhere but not in the Java
578 VM can be used with the Java VM, this method needs to be
579 invoked. The two arguments it takes are optional and
585 <span class="codefrag">detachCurrentThread()</span>
586 The opposite of <span class="codefrag">attachCurrentThread()</span>. This method
587 should be used with extreme caution as Python's and java VM's
588 garbage collectors may use a thread detached too early causing a
589 system crash. The utility of this method seems dubious at the
595 There are several differences between JNI's <span class="codefrag">findClass()</span>
596 and Java's <span class="codefrag">Class.forName()</span>:
601 className is a '/' separated string of names
605 the class loaders are different, <span class="codefrag">findClass()</span> may find
606 classes that <span class="codefrag">Class.forName()</span> won't.
614 >>> from lucene import *
615 >>> initVM(CLASSPATH)
616 >>> findClass('org/apache/lucene/document/Document')
617 <Class: class org.apache.lucene.document.Document>
618 >>> Class.forName('org.apache.lucene.document.Document')
619 Traceback (most recent call last):
620 File "<stdin>", line 1, in <module>
621 lucene.JavaError: java.lang.ClassNotFoundException:
622 org/apache/lucene/document/Document
623 >>> Class.forName('java.lang.Object')
624 <Class: class java.lang.Object>
628 <a name="N10207"></a><a name="casting"></a>
629 <h2 class="boxed">Type casting and instance checks</h2>
630 <div class="section">
632 Many Java APIs are declared to return types that are less specific
633 than the types actually returned. In Java 1.5, this is worked around
634 with type parameters. JCC generates code to heed type parameters
635 unless the <span class="codefrag">--no-generics</span> is used. See next section for
636 details on Java generics support.
639 In C++, casting the object into its actual type is supported via the
640 regular C casting operator.
643 In Python each wrapped class has a class method
644 called <span class="codefrag">cast_</span> that implements the same functionality.
647 Similarly, each wrapped class has a class method
648 called <span class="codefrag">instance_</span> that tests whether the wrapped java
649 instance is of the given type. For example:
652 if BooleanQuery.instance_(query):
653 booleanQuery = BooleanQuery.cast_(query)
655 print booleanQuery.getClauses()
659 <a name="N10227"></a><a name="generics"></a>
660 <h2 class="boxed">Handling generic classes</h2>
661 <div class="section">
663 Java 1.5 added support for parameterized types. JCC generates code
664 to heed type parameters unless the <span class="codefrag">--no-generics</span>
665 command line parameter is used. Java type parameterization is a
666 runtime feature. The same class is used for all its
667 parameterizations. Similarly, JCC wrapper objects all use the same
668 class but store type parameterizations on instances and make them
669 accessible as a tuple via the <span class="codefrag">parameters_</span> property.
672 For example, an <span class="codefrag">ArrayList<Document></span> instance,
673 has <span class="codefrag">(<type 'Document'>,)</span>
674 for <span class="codefrag">parameters_</span> and its <span class="codefrag">get()</span> method uses
675 that type parameter to wrap its return values.
678 To allocate an instance of a generic Java class with specific type
679 parameters use the <span class="codefrag">of_()</span> method. This method accepts
680 one or more Python wrapper classes to use as type parameters. For
681 example, <span class="codefrag">java.util.ArrayList<E></span> is declared to
682 accept one type parameter. Its wrapper's <span class="codefrag">of_()</span> method
683 hence accepts one parameter, a Python class, to use as type
684 parameter for the return type of its <span class="codefrag">get()</span> method, among
688 >>> a = ArrayList().of_(Document)
690 <ArrayList: []>
691 >>> a.parameters_
692 (<type 'Document'>,)
693 >>> a.add(Document())
695 >>> a.get(0)
696 <Document: Document<>>
699 The use of type parameters is, of course, optional. A generic Java
700 class can still be used as before, without type parameters.
701 Downcasting from <span class="codefrag">Object</span> is then necessary:
704 >>> a = ArrayList()
706 <ArrayList: []>
707 >>> a.parameters_
709 >>> a.add(Document())
711 >>> a.get(0)
712 <Object: Document<>>
713 >>> Document.cast_(a.get(0))
714 <Document: Document<>>
718 <a name="N10263"></a><a name="arrays"></a>
719 <h2 class="boxed">Handling arrays</h2>
720 <div class="section">
722 Java arrays are wrapped with a C++ JArray
723 template. The <span class="codefrag">[]</span> is available for read
724 access. This template, <span class="codefrag">JArray<T></span>, accomodates all
725 java primitive types, <span class="codefrag">jstring</span>, <span class="codefrag">jobject</span> and
726 wrapper class arrays.
729 Java arrays are returned to Python in a <span class="codefrag">JArray</span> wrapper
730 instance that implements the Python sequence protocol. It is
731 possible to change an array's elements but not to change an array's
735 To convert a char array to a Python string use
736 a <span class="codefrag">''.join(array)</span> construct.
739 Any Java method expecting an array can be called with the corresponding
740 sequence object from python.
743 To instantiate a Java array from Python, use one of the following
747 >>> array = JArray('int')(size)
748 # the resulting Java int array is initialized with zeroes
750 >>> array = JArray('int')(sequence)
751 # the sequence must only contain ints
752 # the resulting Java int array contains the ints in the sequence
755 Instead of <span class="codefrag">'int'</span>, you may also use one
756 of <span class="codefrag">'object'</span>, <span class="codefrag">'string'</span>, <span class="codefrag">'bool'</span>,
757 <span class="codefrag">'byte'</span>, <span class="codefrag">'char'</span>, <span class="codefrag">'double'</span>,
758 <span class="codefrag">'float'</span>, <span class="codefrag">'long'</span> and <span class="codefrag">'short'</span>
759 to create an array of the corresponding type.
762 Because there is only one wrapper class for object arrays,
763 the <span class="codefrag">JArray('object')</span> type's constructor takes a second
764 argument denoting the class of the object elements. This argument is
765 optional and defaults to <span class="codefrag">Object</span>.
768 As with the <span class="codefrag">Object</span> types, the <span class="codefrag">JArray</span> types
769 also include a <span class="codefrag">cast_</span> method. This method becomes useful
770 when the array returned to Python is wrapped as a
771 plain <span class="codefrag">Object</span>. This is the case, for example, with
772 nested arrays since there is no distinct Python type for every
773 different java object array class - all java object arrays are
774 wrapped by <span class="codefrag">JArray('object')</span>. For example:
777 # cast obj to an array of ints
778 >>> JArray('int').cast_(obj)
779 # cast obj to an array of Document
780 >>> JArray('object').cast_(obj, Document)
783 In both cases, the java type of obj must be compatible with the
784 array type it is being cast to.
787 # using nested array:
789 >>> d = JArray('object')(1, Document)
790 >>> d[0] = Document()
792 JArray<object>[<Document: Document<>>]
794 <Document: Document<>>
795 >>> a = JArray('object')(2)
796 >>> a[0] = d
797 >>> a[1] = JArray('int')([0, 1, 2])
799 JArray<object>[<Object: [Lorg.apache.lucene.document.Document;@694f12>, <Object: [I@234265>]
801 <Object: [Lorg.apache.lucene.document.Document;@694f12>
803 <Object: [I@234265>
804 >>> JArray('object').cast_(a[0])[0]
805 <Object: Document<>>
806 >>> JArray('object').cast_(a[0], Document)[0]
807 <Document: Document<>>
808 >>> JArray('int').cast_(a[1])
809 JArray<int>[0, 1, 2]
810 >>> JArray('int').cast_(a[1])[0]
814 To verify that a Java object is of a given array type, use
815 the <span class="codefrag">instance_()</span> method available on the array
816 type. This is not the same as verifying that it is assignable with
817 elements of a given type. For example, using the arrays created
821 # is d array of Object ? are d's elements of type Object ?
822 >>> JArray('object').instance_(d)
825 # can it receive Object instances ?
826 >>> JArray('object').assignable_(d)
829 # is it array of Document ? are d's elements of type Document ?
830 >>> JArray('object').instance_(d, Document)
833 # is it array of Class ? are d's elements of type Class ?
834 >>> JArray('object').instance_(d, Class)
837 # can it receive Document instances ?
838 >>> JArray('object').assignable_(d, Document)
843 <a name="N102E0"></a><a name="exceptions"></a>
844 <h2 class="boxed">Exception reporting</h2>
845 <div class="section">
847 Exceptions that occur in the Java VM and that escape to C++ are
848 reported as a <span class="codefrag">javaError</span> C++ exception. When using
849 Python wrappers, the C++ exceptions are handled and reported with
850 Python exceptions. When using C++ only, failure to handle the
851 exception in your C++ code will cause the process to crash.
854 Exceptions that occur in the Java VM and that escape to the Python
855 VM are reported with a <span class="codefrag">JavaError</span> python exception
856 object. The <span class="codefrag">getJavaException()</span> method can be called
857 on <span class="codefrag">JavaError</span> objects to obtain the original java
858 exception object wrapped as any other Java object. This Java object
859 can be used to obtain a Java stack trace for the error, for example.
862 Exceptions that occur in the Python VM and that escape to the Java
863 VM, as for example can happen in Python extensions (see topic below)
864 are reported to the Java VM as a <span class="codefrag">RuntimeException</span> or as
865 a <span class="codefrag">PythonException</span> when using shared
866 mode. See <a href="../../jcc/documentation/install.html">installation
867 instructions</a> for more information about shared mode.
871 <a name="N10306"></a><a name="extensions"></a>
872 <h2 class="boxed">Writing Java class extensions in Python</h2>
873 <div class="section">
875 JCC makes it relatively easy to extend a Java class from
876 Python. This is done via an intermediary class written in Java that
877 implements a special method called <span class="codefrag">pythonExtension()</span>
878 and that declares a number of native methods that are to be
879 implemented by the actual Python extension.
882 When JCC sees these special extension java classes it generates the
883 C++ code implementing the native methods they declare. These native
884 methods call the corresponding Python method implementations passing
885 in parameters and returning the result to the Java VM caller.
888 For example, to implement a Lucene analyzer in Python, one would
889 implement first such an extension class in Java:
892 package org.apache.pylucene.analysis;
894 import org.apache.lucene.analysis.Analyzer;
895 import org.apache.lucene.analysis.TokenStream;
896 import java.io.Reader;
898 public class PythonAnalyzer extends Analyzer {
899 private long pythonObject;
901 public PythonAnalyzer()
905 public void pythonExtension(long pythonObject)
907 this.pythonObject = pythonObject;
909 public long pythonExtension()
911 return this.pythonObject;
914 public void finalize()
920 public native void pythonDecRef();
921 public native TokenStream tokenStream(String fieldName, Reader reader);
925 The <span class="codefrag">pythonExtension()</span> methods is what makes this class
926 recognized as an extension class by JCC. They should be included
927 verbatim as above along with the declaration of
928 the <span class="codefrag">pythonObject</span> instance variable.
931 The implementation of the native <span class="codefrag">pythonDecRef()</span> method
932 is generated by JCC and is necessary because it seems
933 that <span class="codefrag">finalize()</span> cannot itself be native. Since an
934 extension class wraps the Python instance object it's going to be
935 calling methods on, its ref count needs to be decremented when this
936 Java wrapper class disappears. A declaration
937 for <span class="codefrag">pythonDecRef()</span> and a <span class="codefrag">finalize()</span>
938 implementation should always be included verbatim as above.
941 Really, the only non boilerplate user input is the constructor of the
942 class and the other native methods, <span class="codefrag">tokenStream()</span> in
946 The corresponding Python class(es) are implemented as follows:
949 class _analyzer(PythonAnalyzer):
950 def tokenStream(_self, fieldName, reader):
951 class _tokenStream(PythonTokenStream):
953 super(_tokenStream, self_).__init__()
954 self_.TOKENS = ["1", "2", "3", "4", "5"]
955 self_.INCREMENTS = [1, 2, 1, 0, 1]
957 self_.posIncrAtt = self_.addAttribute(PositionIncrementAttribute.class_)
958 self_.termAtt = self_.addAttribute(TermAttribute.class_)
959 self_.offsetAtt = self_.addAttribute(OffsetAttribute.class_)
960 def incrementToken(self_):
961 if self_.i == len(self_.TOKENS):
963 self_.termAtt.setTermBuffer(self_.TOKENS[self_.i])
964 self_.offsetAtt.setOffset(self_.i, self_.i)
965 self_.posIncrAtt.setPositionIncrement(self_.INCREMENTS[self_.i])
974 return _tokenStream()
977 When an <span class="codefrag">__init__()</span> is declared, <span class="codefrag">super()</span>
978 must be called or else the Java wrapper class will not know about
979 the Python instance it needs to invoke.
982 When a java extension class declares native methods for which there
983 are public or protected equivalents available on the parent class,
984 JCC generates code that makes it possible to
985 call <span class="codefrag">super()</span> on these methods from Python as well.
988 There are a number of extension examples available in PyLucene's test
989 <a href="http://svn.apache.org/viewcvs.cgi/lucene/pylucene/trunk/test">suite</a>
990 and <a href="../../documentation/readme.html">samples</a>.
994 <a name="N1035C"></a><a name="embedding"></a>
995 <h2 class="boxed">Embedding a Python VM in a Java VM</h2>
996 <div class="section">
998 Using the same techniques used when writing a Python extension of a
999 Java class, JCC may also be used to embed a Python VM in a Java VM.
1000 Following are the steps and constraints to follow to achieve this:
1005 JCC must be built in shared mode. See
1006 <a href="../../jcc/documentation/install.html">installation
1007 instructions</a> for more information about shared mode.
1008 Note that for this use on Mac OS X, JCC must also be built
1009 with the link flags <span class="codefrag">"-framework", "Python"</span> in
1010 the <span class="codefrag">LFLAGS</span> value.
1014 As described in the previous section, define one or more Java
1015 classes to be "extended" from Python to provide the
1016 implementations of the native methods declared on them. Instances
1017 of these classes implement the bridges into the Python VM from
1022 The <span class="codefrag">org.apache.jcc.PythonVM</span> Java class is going be
1023 used from the Java VM's main thread to initialize the embedded
1024 Python VM. This class is installed inside the JCC egg under the
1025 <span class="codefrag">jcc/classes</span> directory and the full path to this
1026 directory must be on the Java <span class="codefrag">CLASSPATH</span>.
1030 The JCC egg directory contains the JCC shared runtime library - not
1031 the JCC Python extension shared library - but a library
1032 called <span class="codefrag">libjcc.dylib</span> on Mac OS X,
1033 <span class="codefrag">libjcc.so</span> on Linux or <span class="codefrag">jcc.dll</span> on Windows.
1034 This directory must be added to the Java VM's shared library path
1035 via the <span class="codefrag">-Djava.library.path</span> command line parameter.
1039 In the Java VM's main thread, initialize the Python VM by
1040 calling its static <span class="codefrag">start()</span> method passing it a
1041 Python program name string and optional start-up arguments
1042 in a string array that will be made accessible in Python via
1043 <span class="codefrag">sys.argv</span>. Note that the program name string is
1044 purely informational, and is not used by the
1045 <span class="codefrag">start()</span> code other than to initialize that
1046 Python variable. This method returns the singleton PythonVM
1047 instance to be used in this Java VM. <span class="codefrag">start()</span>
1048 may be called multiple times; it will always return the same
1049 singleton instance. This instance may also be retrieved at any
1050 later time via the static <span class="codefrag">get()</span> method defined
1051 on the <span class="codefrag">org.apache.jcc.PythonVM</span> class.
1055 Any Java VM thread that is going to be calling into the Python VM
1056 should start with acquiring a reference to the Python thread state
1057 object by calling <span class="codefrag">acquireThreadState()</span> method on the
1058 Python VM instance. It should then release the Python thread state
1059 before terminating by calling <span class="codefrag">releaseThreadState()</span>.
1060 Calling these methods is optional but strongly recommended as it
1061 ensures that Python is not creating and throwing away a thread
1062 state everytime the Python VM is entered and exited from a given
1067 Any Java VM thread may instantiate a Python object for which an
1068 extension class was defined in Java as described in the previous
1069 section by calling the <span class="codefrag">instantiate()</span> method on the
1070 PythonVM instance. This method takes two string parameters, the
1071 name of the Python module and the name of the Python class to
1072 import and instantiate from it. The <span class="codefrag">__init__()</span>
1073 constructor on this class must be callable without any parameters
1074 and, if defined, must call <span class="codefrag">super()</span> in order to
1075 initialize the Java side. The <span class="codefrag">instantiate()</span> method is
1076 declared to return <span class="codefrag">java.lang.Object</span> but the return
1077 value is actually an instance of the Java extension class used and
1078 must be downcast to it.
1084 <a name="N103C4"></a><a name="python"></a>
1085 <h2 class="boxed">Pythonic protocols</h2>
1086 <div class="section">
1088 When generating wrappers for Python, JCC attempts to detect which
1089 classes can be made iterable:
1094 When a class declares to
1095 implement <span class="codefrag">java.lang.Iterable</span>, JCC makes it iterable
1100 When a Java class declares a method called <span class="codefrag">next()</span>
1101 with no arguments returning an object type, this class is made
1102 iterable. Its <span class="codefrag">next()</span> method is assumed to terminate
1103 iteration by returning <span class="codefrag">null</span>.
1108 JCC generates a Python mapping get method for a class when requested
1109 to do so via the <span class="codefrag">--mapping</span> command line option which
1110 takes two arguments, the class to generate the mapping get for and
1111 the Java method to use. The method is specified with its name
1112 followed by ':' and its Java
1113 <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp16432">signature</a>.
1116 For example, <span class="codefrag">System.getProperties()['java.class.path']</span> is
1120 --mapping java.util.Properties
1121 'getProperty:(Ljava/lang/String;)Ljava/lang/String;'
1122 # asking for a Python mapping protocol wrapper
1123 # for get access on the Properties class by
1124 # calling its getProperty method
1127 JCC generates Python sequence length and get methods for a class
1128 when requested to do so via the <span class="codefrag">--sequence</span> command line
1129 option which takes three arguments, the class to generate the
1130 sequence length and get for and the two java methods to use. The
1131 methods are specified with their name followed by ':' and their Java
1132 <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp16432">signature</a>. For example:
1135 for i in xrange(len(hits)):
1140 is made possible by:
1143 --sequence org.apache.lucene.search.Hits
1145 'doc:(I)Lorg/apache/lucene/document/Document;'
1153 <div class="clearboth"> </div>
1159 <div class="lastmodified">
1160 <script type="text/javascript"><!--
1161 document.write("Last Published: " + document.lastModified);
1164 <div class="copyright">
1166 2009-2011 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>