jde-usages

SourceForge.net Logo

jde-usages is a plugin for the Java Development Environment for Emacs (JDEE) that uses the ASM bytecode library to provide usage (eg: find all the callers of a method) and other useful information about your Java classes.

This plugin is based on the ideas in jde-xref.el that is distributed with JDEE but it is better because it is:

  • Faster. Initial setup is faster. Parsing byte-code is also much faster when done in java instead if elisp.

  • More Accurate. The usage information jde-usages provides is as up to date as the class files and jars in the classpath. You are not required to rebuild the database after compiling.

  • Easier to setup No extra configuration is required. jde-usages examines all the classes in jde-global-classpath and therefore doesn't require a separate classpath of generated files or a prefix list.

jde-usages also uses the information it gathers to provide some useful commands.

Requirements

To use jde-usages you need to have customized jde-global-classpath and jde-sourcepath for your project. The classpath provides a set of classes to search in when looking for usages while the sourcepath is used when navigating to the exact location of a usage. You will also need to have your JDK set up correctly so that bsh can start up. If you've gotten JDEE completion to work, you should be fine.

Download

An installable plugin binary of version 0.9.1 released on May 17, 2005 is available here along with release notes and the detailed ChangeLog. This file also includes all the source files used to build the plugin.

The source is also available via anonymous CVS here.

Installation

Using the binary: (jde-usages.zip)

  1. Unzip the plugin zip file in the JDEE plugin directory, if you haven't customized jde-plugins-directory this is the plugins directory under the JDEE install directory. Unzipping the plugin will create a directory called usages under plugins.
  2. Restart emacs.
OR
you could accomplish the same thing from within emacs:
  1. Copy the file plugin zip file to the JDEE plugin directory. Delete any old jde-usages plugin zip or usages subdirectory.
  2. Then say M-x jde-pi-install-plugins. This will only work if you have the "jar" executable in your exec-path.
  3. Kill any running beanshell process by saying M-x jde-bsh-exit.
  4. Finally say M-x jde-pi-load-plugins to load the plugin. This will however not give you the new menu items for jde-usages. You have to restart for that.

From CVS: The source is structured to look like an expanded plugin and so can be installed directly into the plugins directory.

  1. Check out the sources into your JDEE plugin directory. This will create a folder called usages under plugins.
  2. Go to the usages directory and say "ant build". This populates the usages/classes directory. Typing just "ant" without any targets will print out help about the other targets that can be built.
  3. Restart emacs. You can also say M-x jde-pi-load-plugins to load the plugin but the plugin submenu will not show up until emacs is restarted.

Useful Keybindings

I find the following Keybindings useful in addition to the menu bar commands.
Note: The bindings use "M-u" as a prefix command, overriding its default binding of 'upcase-word, which I almost never use. YMMV.
(define-key jde-mode-map "\M-u" nil)
(define-key jde-mode-map "\M-up" 'jde-usages-display-call-tree-for-thing-at-point) ;; p = point
(define-key jde-mode-map "\M-ui" 'jde-usages-display-call-tree-for-specified-class) ;; i = interactive
(define-key jde-mode-map "\M-uc" 'jde-usages-display-call-tree) ;; c = callers

(define-key jde-mode-map "\M-ut" 'jde-usages-display-type-hierarchy) ;; t = types
(define-key jde-mode-map "\M-ur" 'jde-usages-display-subs-implementing-method) ;; r = reimplements
(define-key jde-mode-map "\M-ud" 'jde-usages-display-subs-and-implementers) ;; d = descendants
(define-key jde-mode-map "\M-ua" 'jde-usages-display-superclasses) ;; a = ancestors

(define-key jde-mode-map "\M-un" 'jde-usages-next-pos)
(define-key jde-mode-map "\M-ul" 'jde-usages-locate-class)


(global-set-key [(meta n)]  (lambda ()
                              (interactive)
                              (jde-load-project-file)
                              (jde-open-class-source-with-completion)))

Notes

Setup

During the setup phase jde-usages looks at the constant table for every class to determine which other classes it refers to and uses this info. to create a dependency table which maps a class to all classes that might call that class. It's critical that this stage be as fast as possible. It is much faster than jde-xref ,which in its setup phase parses the byte-code of all methods to create the final usage table and then writes this data structure to disk, but it won't hurt to make it faster.

Caching:

Directory classpath entries take longer to process than jars because reading many small files turns out to be much slower than reading one large one. To mitigate this problem there is some experimental support to cache the processing results for directory classpath entries between runs. To enable this caching create a directory called ".jde-usages" in your home directory. To find out what java thinks is your home directory type

print (System.getProperty("user.home"));
in the *bsh* buffer. If the ~/.jde-usages directory exists cache files will we written there just before the JVM quits. To ensure that the java process is allowed to shut down completely when quitting emacs add the following code to your .emacs file.
(defun jde-bsh-exit-nicely ()
  "Tells the beanshell process to terminate and waits until the process finishes up."
  (interactive)
  (if (jde-bsh-running-p)
      (let ((process (bsh-get-process (oref 'jde-bsh the-bsh))))
	(message "Shutting down beanshell process")
        (if (and
             (boundp 'jde-ant-invocation-method) ;; ant package may not be loaded.
             (string= (car jde-ant-invocation-method) "Ant Server"))
            (bsh-eval (oref 'jde-bsh the-bsh) "jde.util.JdeUtilities.exit();\n")
	  (bsh-eval (oref 'jde-bsh the-bsh) "exit();\n"))
	(message ""))))

(add-hook 'kill-emacs-hook 'jde-bsh-exit-nicely)

Debugging

A special buffer called *jde-beanshell-scratch* records the data returned by calls the java code in jde.util.Usages. When reporting bugs the contents of this buffer would be useful. This buffer is not truncated right now and so could get to be very large.

Setting jde.util.Usages.DEBUG to true in the beanshell buffer will make jde-usages report some timing information.

Help

To report bugs, request features, or heap accolades, send me (Suraj Acharya) an email. I also monitor the JDEE mailing list pretty closely.