<emmajava>/emmarun — instrumented application runner (on-the-fly instrumentation mode).
<emmajava>/emmarun pairs an advanced custom classloader with a combination of core internal components of <instr>/instr and <report>/report to form a unique convenience tool in EMMA kit: an application runner that instruments classes on the fly and generates coverage reports without any need for a separate build or any intermediate work files alltogether.
<emmajava>/emmarun convenience is especially apparent in command line mode, because its option names intentionally mimick the familiar java options: a Java application launch command line could be made coverage-enabled by inserting a single new word (emmarun) into the command line. Similarly, the ANT version of this tool is an extension of ANT's standard <java> task. <emmajava>/emmarun can execute as little as a single Java class or as much as a complex Swing application made up of hundreds of classes, all with equally small instrumentation overhead.
Thinking of <emmajava>/emmarun as a combination of EMMA class instrumentor and report generator is a good way to remember its ANT attributes and command line options: in the reference sections that follow most of them are documented as identical to their namesakes in <instr>/instr and <report>/report.
What gets instrumented. The default <emmajava>/emmarun behavior is to instrument only the classes that are loaded by the JVM for the running application. The resulting report will not even mention classes that were never loaded and which potentially decrease your coverage percentages. If your objective is to get a complete coverage report (as you would from an offline combination of <instr>/instr and <report>/report) you should use the option for a full classpath scan, possibly in combination with some coverage filters.
Compatibility. At runtime, <emmajava>/emmarun's instrumenting classloader installs
itself as the application classloader, bypassing the standard
system classloader. It uses a smart class
delegation strategy, whereby it automatically detects JRE core and
extension classes without having to filter by class names (the
frequently used, but inadequate, delegation strategy). Coupled
with full support for Class-Path
manifest entries
and -jar
option, the resulting EMMA runtime will
correctly run most standalone Java programs. However, certain cases are
exceptions:
java.lang.ClassLoader.getSystemClassLoader()
(either directly or via
ClassLoader.findSystemClass()
and
related methods)
instead of using the current or thread context loaders will
bypass <emmajava>/emmarun classloader, causing subsequent classes to be
loaded at the wrong node of the classloader hierarchy. Such coding patterns should
really be considered bugs and are not supported. Such
code could be patched up on the fly during instrumentation,
but a reliable solution is expensive in terms of
processing. Switching to offline instrumentation is an easy
workaround.<emmajava> is always forked. ANT's in-process classloading model is not sufficiently
JRE-compatible. ANT's class
delegation in the standard <java> task in
fork='false'
(in-process) mode is
based on name matching (with a hardcoded set of name
filters) and inevitably fails for applications that depend on
non-standard JRE extensions. To support EMMA deployment as a JRE
extension <emmajava> always forces
fork='true'
to ensure correct execution (unless
its enabled
attribute makes it a pass-through).
Internal EMMA properties that affect classloading and class instrumentation. Several EMMA property settings affect instrumentation and classloading behavior done by <emmajava>/emmarun:
Changing the default classloading behavior should be done by
experienced Java users only. Most of instrumentation-related
properties should normally be left with their default
values. instr.do_suid.compensation
can be set to false
to gain extra instrumentation
processing speed when runtime execution does not involve class
de-serialization from existing files or serialization across
JVMs.