PyLucene 3.4.0-1 import
[pylucene.git] / doc / jcc / documentation / readme.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <head>
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="../../">
15 </head>
16 <body onload="init()">
17 <script type="text/javascript">ndeSetTextSize();</script>
18 <div id="top">
19 <!--+
20     |breadtrail
21     +-->
22 <div class="breadtrail">
23 <a href="http://www.apache.org/">apache</a> &gt; <a href="http://lucene.apache.org/">lucene</a><script src="../../skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
24 </div>
25 <!--+
26     |header
27     +-->
28 <div class="header">
29 <!--+
30     |start group logo
31     +-->
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>
34 </div>
35 <!--+
36     |end group logo
37     +-->
38 <!--+
39     |start Project Logo
40     +-->
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>
43 </div>
44 <!--+
45     |end Project Logo
46     +-->
47 <!--+
48     |start Tabs
49     +-->
50 <ul id="tabs">
51 <li>
52 <a class="unselected" href="../../index.html">PyLucene</a>
53 </li>
54 <li class="current">
55 <a class="selected" href="../../jcc/index.html">JCC</a>
56 </li>
57 </ul>
58 <!--+
59     |end Tabs
60     +-->
61 </div>
62 </div>
63 <div id="main">
64 <div id="publishedStrip">
65 <!--+
66     |start Subtabs
67     +-->
68 <div id="level2tabs"></div>
69 <!--+
70     |end Endtabs
71     +-->
72 <script type="text/javascript"><!--
73 document.write("Last Published: " + document.lastModified);
74 //  --></script>
75 </div>
76 <!--+
77     |breadtrail
78     +-->
79 <div class="breadtrail">
80
81              &nbsp;
82            </div>
83 <!--+
84     |start Menu, mainarea
85     +-->
86 <!--+
87     |start Menu
88     +-->
89 <div id="menu">
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>
96 </div>
97 </div>
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>
102 </div>
103 <div class="menupage">
104 <div class="menupagetitle">Features</div>
105 </div>
106 <div class="menuitem">
107 <a href="../../jcc/documentation/javadoc/index.html">Javadoc</a>
108 </div>
109 </div>
110 </div>
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>
114 <!--+
115   |alternative credits
116   +-->
117 <div id="credit2"></div>
118 </div>
119 <!--+
120     |end Menu
121     +-->
122 <!--+
123     |start content
124     +-->
125 <div id="content">
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>
128         PDF</a>
129 </div>
130 <h1>JCC Features</h1>
131 <div id="minitoc-area">
132 <ul class="minitoc">
133 <li>
134 <a href="#install">Installing JCC</a>
135 </li>
136 <li>
137 <a href="#invoking">Invoking JCC</a>
138 </li>
139 <li>
140 <a href="#use">Generating C++ and Python wrappers with JCC</a>
141 </li>
142 <li>
143 <a href="#classpath">Classpath considerations</a>
144 </li>
145 <li>
146 <a href="#setuptools">Using distutils vs setuptools</a>
147 </li>
148 <li>
149 <a href="#egg">Distributing an egg</a>
150 </li>
151 <li>
152 <a href="#api">JCC's runtime API functions</a>
153 </li>
154 <li>
155 <a href="#casting">Type casting and instance checks</a>
156 </li>
157 <li>
158 <a href="#generics">Handling generic classes</a>
159 </li>
160 <li>
161 <a href="#arrays">Handling arrays</a>
162 </li>
163 <li>
164 <a href="#exceptions">Exception reporting</a>
165 </li>
166 <li>
167 <a href="#extensions">Writing Java class extensions in Python</a>
168 </li>
169 <li>
170 <a href="#embedding">Embedding a Python VM in a Java VM</a>
171 </li>
172 <li>
173 <a href="#python">Pythonic protocols</a>
174 </li>
175 </ul>
176 </div>
177     
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>.
184     </div>
185 </div>
186     
187 <a name="N10017"></a><a name="install"></a>
188 <h2 class="boxed">Installing JCC</h2>
189 <div class="section">
190 <p>
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>.
195       </p>
196 <p>
197         See <a href="../../jcc/documentation/install.html">installation</a> for more
198         information and operating system specific notes.
199       </p>
200 </div>
201     
202 <a name="N1002E"></a><a name="invoking"></a>
203 <h2 class="boxed">Invoking JCC</h2>
204 <div class="section">
205 <p>
206         JCC is installed as a package and how to invoke it depends on the
207         Python version used:
208       </p>
209 <ul>
210         
211 <li>python 2.7: <span class="codefrag">python -m jcc</span>
212 </li>
213         
214 <li>python 2.6: <span class="codefrag">python -m jcc.__main__</span>
215 </li>
216         
217 <li>python 2.5: <span class="codefrag">python -m jcc</span>
218 </li>
219         
220 <li>python 2.4:
221           <ul>
222             
223 <li>no setuptools: <span class="codefrag">python </span><em><span class="codefrag">site-packages</span></em><span class="codefrag">/jcc/__init__.py</span>
224 </li>
225             
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>
227 </li>
228           
229 </ul>
230         
231 </li>
232         
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>
234 </li>
235       
236 </ul>
237 </div>
238     
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">
242 <p>
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
249         interface</a>.
250       </p>
251 <p>
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
256         type</a>.
257       </p>
258 <p>
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:
264       </p>
265 <ul>
266         
267 <li>
268           the type is one of the requested classes
269         </li>
270         
271 <li>
272           the type is one of the requested classes' superclass or implemented
273           interfaces 
274         </li>
275         
276 <li>
277           the type is available from one of the packages listed via the
278           <span class="codefrag">--package</span> command line argument
279         </li>
280       
281 </ul>
282 <p>
283         Overloaded methods are supported and are selected at runtime on the
284         basis of the type and number of arguments passed in.
285       </p>
286 <p>
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.
290       </p>
291 <p>
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>.
297       </p>
298 <p>
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.
303       </p>
304 <p>
305         JCC's command-line arguments are best illustrated via the PyLucene
306         example:
307       </p>
308 <pre class="code">
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 
318                               # java.lang package
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
333           java.io.StringReader
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
348                               # called lucene
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
361                    'length:()I' 
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
367                               # files
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
375                               # directory.
376       </pre>
377 <p>
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
381         wrapper classes.
382       </p>
383 <p>
384         Using the <span class="codefrag">--files</span> command line argument, this behaviour
385         can be tuned to workaround various limits:<br>
386         for example:
387       </p>
388 <ul>
389         
390 <li>
391           to break up the large wrapper class file into about 2 files:<br>
392           
393 <span class="codefrag">--files 2</span>
394         
395 </li>
396         
397 <li>
398           to break up the large wrapper class file into about 10 files:<br>
399           
400 <span class="codefrag"> --files 10</span>
401         
402 </li>
403         
404 <li>
405           to generate one C++ file per Java class wrapped:<br>
406           
407 <span class="codefrag">--files separate</span>
408         
409 </li>
410       
411 </ul>
412 <p>
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>.
415       </p>
416 </div>
417     
418 <a name="N10108"></a><a name="classpath"></a>
419 <h2 class="boxed">Classpath considerations</h2>
420 <div class="section">
421 <p>
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>.
431       </p>
432 <p>
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. 
439       </p>
440 <p>
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.
449       </p>
450 </div>
451     
452 <a name="N10130"></a><a name="setuptools"></a>
453 <h2 class="boxed">Using distutils vs setuptools</h2>
454 <div class="section">
455 <p>
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.
461       </p>
462 </div>
463     
464 <a name="N1014E"></a><a name="egg"></a>
465 <h2 class="boxed">Distributing an egg</h2>
466 <div class="section">
467 <p>
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>.
476       </p>
477 </div>
478     
479 <a name="N10172"></a><a name="api"></a>
480 <h2 class="boxed">JCC's runtime API functions</h2>
481 <div class="section">
482 <p>
483         JCC includes a small runtime component that is compiled into any
484         Python extension it produces.
485       </p>
486 <p>
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.
491       </p>
492 <p>
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:
496       </p>
497 <ul>
498         
499 <li>
500           
501 <span class="codefrag">classpath</span>
502 <br>
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.
512           <pre class="code">
513             &gt;&gt;&gt; import lucene
514             &gt;&gt;&gt; lucene.initVM(classpath=lucene.CLASSPATH)
515           </pre>
516         
517 </li>
518         
519 <li>
520           
521 <span class="codefrag">initialheap</span>
522 <br>
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.
526           <pre class="code">
527             &gt;&gt;&gt; import lucene
528             &gt;&gt;&gt; lucene.initVM(initialheap='32m')
529             &gt;&gt;&gt; lucene.Runtime.getRuntime().totalMemory()
530             33357824L
531           </pre>
532         
533 </li>
534         
535 <li>
536           
537 <span class="codefrag">maxheap</span>
538 <br>
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.
542         </li>
543         
544 <li>
545           
546 <span class="codefrag">maxstack</span>
547 <br>
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.
551         </li>
552         
553 <li>
554           
555 <span class="codefrag">vmargs</span>
556 <br>
557           A string of comma separated additional options to pass to the VM
558           startup rountine. These are passed through as-is. For example:
559           <pre class="code">
560             &gt;&gt;&gt; import lucene
561             &gt;&gt;&gt; lucene.initVM(vmargs='-Xcheck:jni,-verbose:jni,-verbose:gc')
562           </pre>
563         
564 </li>
565       
566 </ul>
567 <p>
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:
570       </p>
571 <ul>
572         
573 <li>
574           
575 <span class="codefrag">attachCurrentThread(name, asDaemon)</span>
576 <br>
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
580           self-explanatory.
581         </li>
582         
583 <li>
584           
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
590           moment.
591         </li>
592       
593 </ul>
594 <p>
595         There are several differences between JNI's <span class="codefrag">findClass()</span>
596         and Java's <span class="codefrag">Class.forName()</span>:
597       </p>
598 <ul>
599         
600 <li>
601           className is a '/' separated string of names
602         </li>
603         
604 <li>
605           the class loaders are different, <span class="codefrag">findClass()</span> may find
606           classes that <span class="codefrag">Class.forName()</span> won't.
607         </li>
608       
609 </ul>
610 <p>
611         For example:
612       </p>
613 <pre class="code">
614         &gt;&gt;&gt; from lucene import *
615         &gt;&gt;&gt; initVM(CLASSPATH)
616         &gt;&gt;&gt; findClass('org/apache/lucene/document/Document')
617         &lt;Class: class org.apache.lucene.document.Document&gt;
618         &gt;&gt;&gt; Class.forName('org.apache.lucene.document.Document')
619         Traceback (most recent call last):
620           File "&lt;stdin&gt;", line 1, in &lt;module&gt;
621         lucene.JavaError: java.lang.ClassNotFoundException:
622                           org/apache/lucene/document/Document
623         &gt;&gt;&gt; Class.forName('java.lang.Object')
624         &lt;Class: class java.lang.Object&gt;
625       </pre>
626 </div>
627     
628 <a name="N10207"></a><a name="casting"></a>
629 <h2 class="boxed">Type casting and instance checks</h2>
630 <div class="section">
631 <p>
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.
637       </p>
638 <p>
639         In C++, casting the object into its actual type is supported via the
640         regular C casting operator.
641       </p>
642 <p>
643         In Python each wrapped class has a class method
644         called <span class="codefrag">cast_</span> that implements the same functionality.
645       </p>
646 <p>
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:
650       </p>
651 <pre class="code">
652         if BooleanQuery.instance_(query):
653             booleanQuery = BooleanQuery.cast_(query)
654
655         print booleanQuery.getClauses()
656       </pre>
657 </div>
658     
659 <a name="N10227"></a><a name="generics"></a>
660 <h2 class="boxed">Handling generic classes</h2>
661 <div class="section">
662 <p>
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.
670       </p>
671 <p>
672         For example, an <span class="codefrag">ArrayList&lt;Document&gt;</span> instance,
673         has <span class="codefrag">(&lt;type 'Document'&gt;,)</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.
676       </p>
677 <p>
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&lt;E&gt;</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
685         others: 
686       </p>
687 <pre class="code">
688         &gt;&gt;&gt; a = ArrayList().of_(Document)
689         &gt;&gt;&gt; a
690         &lt;ArrayList: []&gt;
691         &gt;&gt;&gt; a.parameters_
692         (&lt;type 'Document'&gt;,)
693         &gt;&gt;&gt; a.add(Document())
694         True
695         &gt;&gt;&gt; a.get(0)
696         &lt;Document: Document&lt;&gt;&gt;
697       </pre>
698 <p>
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:  
702       </p>
703 <pre class="code">
704         &gt;&gt;&gt; a = ArrayList()
705         &gt;&gt;&gt; a
706         &lt;ArrayList: []&gt;
707         &gt;&gt;&gt; a.parameters_
708         (None,)
709         &gt;&gt;&gt; a.add(Document())
710         True
711         &gt;&gt;&gt; a.get(0)
712         &lt;Object: Document&lt;&gt;&gt;
713         &gt;&gt;&gt; Document.cast_(a.get(0))
714         &lt;Document: Document&lt;&gt;&gt;
715       </pre>
716 </div>
717     
718 <a name="N10263"></a><a name="arrays"></a>
719 <h2 class="boxed">Handling arrays</h2>
720 <div class="section">
721 <p>
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&lt;T&gt;</span>, accomodates all
725         java primitive types, <span class="codefrag">jstring</span>, <span class="codefrag">jobject</span> and
726         wrapper class arrays.
727       </p>
728 <p>
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
732         size.
733       </p>
734 <p>
735         To convert a char array to a Python string use
736         a <span class="codefrag">''.join(array)</span> construct.
737       </p>
738 <p>
739         Any Java method expecting an array can be called with the corresponding
740         sequence object from python.
741       </p>
742 <p>
743         To instantiate a Java array from Python, use one of the following
744         forms:
745       </p>
746 <pre class="code">
747         &gt;&gt;&gt; array = JArray('int')(size)
748         # the resulting Java int array is initialized with zeroes
749
750         &gt;&gt;&gt; array = JArray('int')(sequence)
751         # the sequence must only contain ints
752         # the resulting Java int array contains the ints in the sequence
753       </pre>
754 <p>
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.
760       </p>
761 <p>
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>.
766       </p>
767 <p>
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:
775       </p>
776 <pre class="code">
777         # cast obj to an array of ints
778         &gt;&gt;&gt; JArray('int').cast_(obj)
779         # cast obj to an array of Document
780         &gt;&gt;&gt; JArray('object').cast_(obj, Document)
781       </pre>
782 <p>
783         In both cases, the java type of obj must be compatible with the
784         array type it is being cast to.
785       </p>
786 <pre class="code">
787         # using nested array:
788
789         &gt;&gt;&gt; d = JArray('object')(1, Document)
790         &gt;&gt;&gt; d[0] = Document()
791         &gt;&gt;&gt; d
792         JArray&lt;object&gt;[&lt;Document: Document&lt;&gt;&gt;]
793         &gt;&gt;&gt; d[0]
794         &lt;Document: Document&lt;&gt;&gt;
795         &gt;&gt;&gt; a = JArray('object')(2)
796         &gt;&gt;&gt; a[0] = d
797         &gt;&gt;&gt; a[1] = JArray('int')([0, 1, 2])
798         &gt;&gt;&gt; a
799         JArray&lt;object&gt;[&lt;Object: [Lorg.apache.lucene.document.Document;@694f12&gt;, &lt;Object: [I@234265&gt;]
800         &gt;&gt;&gt; a[0]
801         &lt;Object: [Lorg.apache.lucene.document.Document;@694f12&gt;
802         &gt;&gt;&gt; a[1]
803         &lt;Object: [I@234265&gt;
804         &gt;&gt;&gt; JArray('object').cast_(a[0])[0]
805         &lt;Object: Document&lt;&gt;&gt;
806         &gt;&gt;&gt; JArray('object').cast_(a[0], Document)[0]
807         &lt;Document: Document&lt;&gt;&gt;
808         &gt;&gt;&gt; JArray('int').cast_(a[1])
809         JArray&lt;int&gt;[0, 1, 2]
810         &gt;&gt;&gt; JArray('int').cast_(a[1])[0]
811         0
812       </pre>
813 <p>
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
818         above:
819       </p>
820 <pre class="code">
821         # is d array of Object ? are d's elements of type Object ?
822         &gt;&gt;&gt; JArray('object').instance_(d)
823         True
824
825         # can it receive Object instances ?
826         &gt;&gt;&gt; JArray('object').assignable_(d)
827         False
828
829         # is it array of Document ? are d's elements of type Document ?
830         &gt;&gt;&gt; JArray('object').instance_(d, Document)
831         True
832
833         # is it array of Class ? are d's elements of type Class ?
834         &gt;&gt;&gt; JArray('object').instance_(d, Class)
835         False
836
837         # can it receive Document instances ?
838         &gt;&gt;&gt; JArray('object').assignable_(d, Document)
839         True
840       </pre>
841 </div>
842     
843 <a name="N102E0"></a><a name="exceptions"></a>
844 <h2 class="boxed">Exception reporting</h2>
845 <div class="section">
846 <p>
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.
852       </p>
853 <p>
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.
860       </p>
861 <p>
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.
868       </p>
869 </div>
870     
871 <a name="N10306"></a><a name="extensions"></a>
872 <h2 class="boxed">Writing Java class extensions in Python</h2>
873 <div class="section">
874 <p>
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.
880       </p>
881 <p>
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.
886       </p>
887 <p>
888         For example, to implement a Lucene analyzer in Python, one would
889         implement first such an extension class in Java:
890       </p>
891 <pre class="code">
892     package org.apache.pylucene.analysis;
893
894     import org.apache.lucene.analysis.Analyzer;
895     import org.apache.lucene.analysis.TokenStream;
896     import java.io.Reader;
897
898     public class PythonAnalyzer extends Analyzer {
899         private long pythonObject;
900
901         public PythonAnalyzer()
902         {
903         }
904
905         public void pythonExtension(long pythonObject)
906         {
907             this.pythonObject = pythonObject;
908         }
909         public long pythonExtension()
910         {
911             return this.pythonObject;
912         }
913
914         public void finalize()
915             throws Throwable
916         {
917             pythonDecRef();
918         }
919
920         public native void pythonDecRef();
921         public native TokenStream tokenStream(String fieldName, Reader reader);
922     }
923       </pre>
924 <p>
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.
929       </p>
930 <p>
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.
939       </p>
940 <p>
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
943         the example above.
944       </p>
945 <p>
946         The corresponding Python class(es) are implemented as follows:
947       </p>
948 <pre class="code">
949         class _analyzer(PythonAnalyzer):
950             def tokenStream(_self, fieldName, reader):
951                 class _tokenStream(PythonTokenStream):
952                     def __init__(self_):
953                         super(_tokenStream, self_).__init__()
954                         self_.TOKENS = ["1", "2", "3", "4", "5"]
955                         self_.INCREMENTS = [1, 2, 1, 0, 1]
956                         self_.i = 0
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):
962                             return False
963                         self_.termAtt.setTermBuffer(self_.TOKENS[self_.i])
964                         self_.offsetAtt.setOffset(self_.i, self_.i)
965                         self_.posIncrAtt.setPositionIncrement(self_.INCREMENTS[self_.i])
966                         self_.i += 1
967                         return True
968                     def end(self_):
969                         pass
970                     def reset(self_):
971                         pass
972                     def close(self_):
973                         pass
974                 return _tokenStream()
975       </pre>
976 <p>
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.
980       </p>
981 <p>
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.
986       </p>
987 <p>
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>.
991       </p>
992 </div>
993     
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">
997 <p>
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:
1001       </p>
1002 <ul>
1003         
1004 <li>
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.
1011         </li>
1012         
1013 <li>
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
1018           Java.
1019         </li>
1020         
1021 <li>
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>.
1027         </li>
1028         
1029 <li>
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.
1036         </li>
1037         
1038 <li>
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.
1052         </li>
1053         
1054 <li>
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
1063           Java VM thread.
1064         </li>
1065         
1066 <li>
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.
1079         </li>
1080       
1081 </ul>
1082 </div>
1083     
1084 <a name="N103C4"></a><a name="python"></a>
1085 <h2 class="boxed">Pythonic protocols</h2>
1086 <div class="section">
1087 <p>
1088         When generating wrappers for Python, JCC attempts to detect which
1089         classes can be made iterable:
1090       </p>
1091 <ul>
1092         
1093 <li>
1094           When a class declares to
1095           implement <span class="codefrag">java.lang.Iterable</span>, JCC makes it iterable
1096           from Python.
1097         </li>
1098         
1099 <li>
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>.
1104         </li>
1105       
1106 </ul>
1107 <p>
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>.
1114       </p>
1115 <p>
1116       For example, <span class="codefrag">System.getProperties()['java.class.path']</span> is
1117       made possible by:
1118       </p>
1119 <pre class="code">
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
1125       </pre>
1126 <p>
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:
1133       </p>
1134 <pre class="code">
1135       for i in xrange(len(hits)): 
1136           doc = hits[i]
1137           ...
1138       </pre>
1139 <p>
1140         is made possible by:
1141       </p>
1142 <pre class="code">
1143         --sequence org.apache.lucene.search.Hits
1144                    'length:()I' 
1145                    'doc:(I)Lorg/apache/lucene/document/Document;'
1146       </pre>
1147 </div>
1148   
1149 </div>
1150 <!--+
1151     |end content
1152     +-->
1153 <div class="clearboth">&nbsp;</div>
1154 </div>
1155 <div id="footer">
1156 <!--+
1157     |start bottomstrip
1158     +-->
1159 <div class="lastmodified">
1160 <script type="text/javascript"><!--
1161 document.write("Last Published: " + document.lastModified);
1162 //  --></script>
1163 </div>
1164 <div class="copyright">
1165         Copyright &copy;
1166          2009-2011 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
1167 </div>
1168 <!--+
1169     |end bottomstrip
1170     +-->
1171 </div>
1172 </body>
1173 </html>