|
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)
- 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.
- Restart emacs.
OR
you could accomplish the same thing from within emacs:
- Copy the file plugin zip file to the JDEE plugin
directory. Delete any old jde-usages plugin zip or
usages subdirectory.
- Then say M-x jde-pi-install-plugins. This will only
work if you have the "jar" executable in your
exec-path.
- Kill any running beanshell process by saying M-x jde-bsh-exit.
- 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.
- Check out the sources into your JDEE plugin
directory. This will create a folder called
usages under plugins.
- 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.
- 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.
HelpTo report bugs, request features, or heap
accolades, send me
(Suraj Acharya)
an email. I also monitor the JDEE mailing list pretty
closely.
|