| Gerrit Inspector |
| ================ |
| |
| NAME |
| ---- |
| Gerrit Inspector - Interactive Jython environment for Gerrit |
| |
| SYNOPSIS |
| -------- |
| -- |
| 'java' -jar gerrit.war 'daemon' |
| -d <SITE_PATH> |
| [\--enable-httpd | \--disable-httpd] |
| [\--enable-sshd | \--disable-sshd] |
| [\--console-log] |
| [\--slave] |
| -s |
| -- |
| |
| DESCRIPTION |
| ----------- |
| Runs the Gerrit network daemon on the local system as described |
| in the link:pgm-daemon.html[Daemon documentation], additionally |
| starting an interactive Jython shell for inspection |
| and troubleshooting of live data of the Gerrit instance. |
| |
| CAUTION: 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. |
| |
| INSTALLATION |
| ------------ |
| |
| 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 http://www.jython.org/ |
| 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. |
| |
| STARTUP |
| ------- |
| |
| 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 "com.google.gerrit.pgm.shell.JythonShell@61644f2d" |
| "m" is "com.google.gerrit.lifecycle.LifecycleManager@6f03b248" |
| "ds" is "com.google.gerrit.server.schema.DataSourceProvider@6b3592c" |
| "schk" is "com.google.gerrit.server.schema.SchemaVersionCheck@5e8cb9bd" |
| |
| 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/Startup.py'. |
| |
| 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. |
| |
| USING THE INTERPRETER |
| --------------------- |
| |
| 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 |
| http://www.jython.org/[Jython documentation]. |
| |
| After sucessful initialization it is possible to examine components of |
| Java packages, classes and live instances. |
| |
| ---- |
| >>> import com.google.inject |
| >>> dir(com.google.inject) |
| ['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(com.google.inject) |
| <type 'javapackage'> |
| >>> dir(com.google.inject.Guice) |
| ['__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 |
| org.apache.commons.dbcp.BasicDataSource@61db2215 |
| >>> ds.driverClassName |
| u'org.postgresql.Driver' |
| >>> ds.dataSource |
| org.apache.commons.dbcp.PoolingDataSource@23226fe1 |
| >>> ds.dataSource.connection |
| jdbc:postgresql://localhost/reviewdb, UserName=rv, PostgreSQL Native Driver |
| ---- |
| |
| It is also possible to interact with the ORM layer: |
| |
| ---- |
| >>> db = schk.schema.open() |
| >>> db |
| com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$28@24cbbdf3 |
| >>> db.getDialect() |
| com.google.gwtorm.schema.sql.DialectPostgreSQL@4de07d3e |
| >>> 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 |
| com.google.gerrit.reviewdb.client.PatchLineComment@5381298a |
| com.google.gerrit.reviewdb.client.PatchLineComment@44ce4dda |
| com.google.gerrit.reviewdb.client.PatchLineComment@44594680 |
| >>> dir(com.google.gerrit.reviewdb.client.PatchLineComment) |
| ['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 "com.google.gerrit.server.schema.SchemaVersionCheck@5e8cb9bd" |
| "ds" is "com.google.gerrit.server.schema.DataSourceProvider@6b3592c" |
| "m" is "com.google.gerrit.lifecycle.LifecycleManager@6f03b248" |
| "Shell" is "com.google.gerrit.pgm.shell.JythonShell@61644f2d" |
| "d" is "com.google.gerrit.pgm.Daemon@28a3f689" |
| |
| 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(NativeConstructorAccessorImpl.java:57) |
| at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) |
| at java.lang.reflect.Constructor.newInstance(Constructor.java:532) |
| at org.python.core.PyReflectedConstructor.constructProxy(PyReflectedConstructor.java:210) |
| |
| 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 com.google.gerrit.pgm.Daemon : caught shutdown, cleaning up |
| ---- |
| |
| TROUBLESHOOTING |
| --------------- |
| |
| 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 com.google.gerrit.pgm.shell.JythonShell : 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 com.google.gerrit.pgm.Daemon : Unable to start daemon |
| com.google.inject.ProvisionException: 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) |
| at com.google.gerrit.pgm.shell.JythonShell.<init>(JythonShell.java:47) |
| while locating com.google.gerrit.pgm.shell.JythonShell |
| while locating com.google.gerrit.pgm.shell.InteractiveShell |
| ---- |
| |
| Errors during processing of the startup script, 'Startup.py', are logged |
| to the error log: |
| |
| ---- |
| [2012-04-17 14:20:30,558] INFO com.google.gerrit.pgm.shell.JythonShell : Jython shell instance created. |
| [2012-04-17 14:20:38,005] ERROR com.google.gerrit.pgm.shell.JythonShell : Exception occured while loading file Startup.py : |
| java.lang.reflect.InvocationTargetException |
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) |
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) |
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) |
| at java.lang.reflect.Method.invoke(Method.java:616) |
| at com.google.gerrit.pgm.shell.JythonShell.runMethod0(JythonShell.java:112) |
| at com.google.gerrit.pgm.shell.JythonShell.execFile(JythonShell.java:194) |
| at com.google.gerrit.pgm.shell.JythonShell.reload(JythonShell.java:178) |
| at com.google.gerrit.pgm.shell.JythonShell.run(JythonShell.java:152) |
| at com.google.gerrit.pgm.Daemon.run(Daemon.java:190) |
| at com.google.gerrit.pgm.util.AbstractProgram.main(AbstractProgram.java:67) |
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) |
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) |
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) |
| at java.lang.reflect.Method.invoke(Method.java:616) |
| at com.google.gerrit.launcher.GerritLauncher.invokeProgram(GerritLauncher.java:167) |
| at com.google.gerrit.launcher.GerritLauncher.mainImpl(GerritLauncher.java:91) |
| at com.google.gerrit.launcher.GerritLauncher.main(GerritLauncher.java:49) |
| at Main.main(Main.java:25) |
| Caused by: Traceback (most recent call last): |
| File "/home/user/.gerritcodereview/Startup.py", line 1, in <module> |
| Test |
| 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: |
| |
| ---- |
| Shell.reload() |
| ---- |
| |
| LOGGING |
| ------- |
| 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. |
| |
| KNOWN ISSUES |
| ------------ |
| The Inspector does not yet recognize Google Guice bindings. |
| |
| IMPORTANT: Using the Inspector may void your warranty. |
| |
| GERRIT |
| ------ |
| Part of link:index.html[Gerrit Code Review] |
| |
| SEARCHBOX |
| --------- |