Gerrit Inspector - Interactive Jython environment for Gerrit


java -jar gerrit.war daemon -d <SITE_PATH> [\--enable-httpd | \--disable-httpd] [\--enable-sshd | \--disable-sshd] [\--console-log] [\--slave] -s


Runs the Gerrit network daemon on the local system as described in the Daemon documentation, additionally starting an interactive Jython shell for inspection and troubleshooting of live data of the Gerrit instance.

Gerrit Inspector works directly on instances of Java Virtual Machine objects and it is possible to read and write instance members as well as invoke Java functions. Access is granted also to private and protected members. Therefore it is possible to introduce changes to the internal state of the system in an inconsistent way. Care must be taken not to break the running system and/or destroy the data.


Gerrit Inspector requires Jython library (jython.jar) to be installed in the $site_path/lib directory. Jython, a Python interpreter for the Java Virtual Machine, can be obtained from the website. Only jython.jar file is needed, installation of Jython libraries is optional. Gerrit Inspector has been tested with Jython 2.5.2 but might work an earlier version.


During startup Jython examines Java libraries found on the classpath. While libraries are inspected a large amount of messages is displayed on the console:

*sys-package-mgr*: processing new jar, '/home/user/.gerritcodereview/tmp/gerrit_4890671371398741854_app/sshd-core-0.5.1-r1095809.jar'

After this a system-wide embedded initialization script is started. This script is contained in the gerrit’s WAR archive. This script produces output similar to the following on the console:

"Shell" is ""
"m" is ""
"ds" is ""
"schk" is ""

Welcome to the Gerrit Inspector
Enter help() to see the above again, EOF to quit and stop Gerrit

Then an optional user startup script is processed. It should be located in the gerrit user home directory as .gerritcodereview/

This script can access all variables defined in the system (such as the ones displayed by the initialization script as shown above). Variables and functions defined by the startup scripts are available for the interactive interpreter.

When interactive interpreter exits (by issuing EOF on the command line), a whole Gerrit instance is shut down gracefully.


Gerrit Inspector launches Jython interpreter in the context of the Gerrit Java Virtual Machine. All core facilities of the Jython (and Python) language are available to the user.

Additional facilities can be provided, for example a Lib directory from the Jython distribution can be installed under $site_path/lib/Lib to provide access to many standard Python modules. Jython can also use additional Java classes and libraries and most of the Python modules and scripts.

The Inspector has by default access to classes and object instances available in the Java Virtual Machine. Objects are introspected and private and protected members are also available.

For more information on using Jython, especially with regards to its limitations in interfacing to the Java Virtual Machine, please refer to the Jython documentation.

After successful initialization it is possible to examine components of Java packages, classes and live instances.

>>> import
>>> dir(
['AbstractModule', 'Binder', 'Binding', 'BindingAnnotation', 'ConfigurationException', 'CreationException', 'Exposed', 'Guice', 'ImplementedBy', 'Inject', 'Injector', 'Key', 'MembersInjector', 'Module', 'OutOfScopeException', 'PrivateBinder', 'PrivateModule', 'ProvidedBy', 'Provider', 'Provides', 'ProvisionException', 'Scope', 'ScopeAnnotation', 'Scopes', 'Singleton', 'Stage', 'TypeLiteral', '__name__', 'assistedinject', 'binder', 'internal', 'matcher', 'name', 'servlet', 'spi', 'util']
>>> type(
<type 'javapackage'>
>>> dir(
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__',
'__eq__', '__getattribute__', '__hash__', '__init__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__str__', '__unicode__', 'class', 'clone', 'createInjector',
'equals', 'finalize', 'getClass', 'hashCode', 'notify', 'notifyAll',
'registerNatives', 'toString', 'wait']

Startup script provides some convenient variables to access some global Gerrit components, for example a connection to the review database is kept open:

>>> ds
>>> ds.driverClassName
>>> ds.dataSource
>>> ds.dataSource.connection
jdbc:postgresql://localhost/reviewdb, UserName=rv, PostgreSQL Native Driver

It is also possible to interact with the ORM layer:

>>> db =
>>> db$$28@24cbbdf3
>>> db.getDialect()
>>> for x in db.patchSets().iterateAllEntities():
...     print x
[PatchSet 1,1]
[PatchSet 2,1]
[PatchSet 3,1]
[PatchSet 4,1]
[PatchSet 5,1]
[PatchSet 6,1]
[PatchSet 7,1]
[PatchSet 8,1]
[PatchSet 6,2]
>>> for x in db.patchComments().iterateAllEntities():
...     print x
>>> dir(
['Key', 'STATUS_DRAFT', 'STATUS_PUBLISHED', 'Status', '__class__',
'__copy__', '__deepcopy__', '__delattr__', '__doc__', '__eq__',
'__getattribute__', '__hash__', '__init__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__',
'__unicode__', 'author', 'class', 'clone', 'equals', 'finalize',
'getAuthor', 'getClass', 'getKey', 'getLine', 'getMessage',
'getParentUuid', 'getSide', 'getStatus', 'getWrittenOn', 'hashCode',
'key', 'line', 'lineNbr', 'message', 'notify', 'notifyAll',
'parentUuid', 'registerNatives', 'setMessage', 'setSide', 'setStatus',
'side', 'status', 'toString', 'updated', 'wait', 'writtenOn']
>>> for x in db.patchComments().iterateAllEntities():
...     print x.status, x.line, x.message
P 2 I like it!
P 2 more
P 1 better

A built-in help() function provides values of global variables defined in the interpreter:

>>> help()
"schk" is ""
"ds" is ""
"m" is ""
"Shell" is ""
"d" is ""

Welcome to the Gerrit Inspector
Enter help() to see the above again, EOF to quit and stop Gerrit

Java and Python exceptions are intercepted by the Inspector:

>>> import java.lang.RuntimeException
>>> raise java.lang.RuntimeException("Exiting")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(
        at java.lang.reflect.Constructor.newInstance(
        at org.python.core.PyReflectedConstructor.constructProxy(

java.lang.RuntimeException: java.lang.RuntimeException: Exiting

To exit the interpreter, use EOF character (Ctrl-D on Unix systems, Ctrl-Z on Windows).

It is also possible to shut down the JVM by using System.exit()

>>> import java.lang.System
>>> java.lang.System.exit(1)

And Gerrit should shut down all its subsystems and exit:

[2012-04-17 15:31:08,458] INFO : caught shutdown, cleaning up


Gerrit Inspector is logging to the Gerrit error log.

A successful startup is indicated in the logfile:

  [2012-04-17 13:43:44,888] INFO : Jython shell instance created.

If jython.jar library is not available, Gerrit refuses to start when given -s option:

[2012-04-17 13:57:29,611] ERROR : Unable to start daemon Guice provision errors:

1) Error injecting constructor, java.lang.UnsupportedOperationException: Cannot create Jython shell: Class org.python.util.InteractiveConsole not found
     (You might need to install jython.jar in the lib directory)
  while locating
  while locating

Errors during processing of the startup script,, are logged to the error log:

[2012-04-17 14:20:30,558] INFO : Jython shell instance created.
[2012-04-17 14:20:38,005] ERROR : Exception occured while loading file :
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(
        at java.lang.reflect.Method.invoke(
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(
        at java.lang.reflect.Method.invoke(
        at Main.main(
Caused by: Traceback (most recent call last):
  File "/home/user/.gerritcodereview/", line 1, in <module>
NameError: name 'Test' is not defined

Those errors are non-fatal. System and user scripts can be loaded again by issuing the following command in the Gerrit Inspector console:



Error and warning messages from the server are automatically written to the log file under $site_path/logs/error_log.

Output and error messages (including Java and Python exceptions) resulting from interactive work are logged to the console.


The Inspector does not yet recognize Google Guice bindings.

Using the Inspector may void your warranty.