Introduce CodeHacker#hasField(String fieldName)

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Allow multiple CodeHacker instances to be used

With Fiji, we will set the application name before we let the
LegacyService inject the hooks. Therefore, we will need to be able
to instantiate CodeHacker a couple of times with the same class loader.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
LegacyInjector: Allow setting the application name

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Teach CodeHacker to edit/add exception handlers

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Move NoSuchMethodError handling from fiji-compat into ij-legacy

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
ij-legacy: clarify the double-purpose of LegacyHacker

LegacyHacker serves two purposes:

- making it possible to synchronize legacy and modern ImageJ instances,

- give fiji-compat's backwards-compatibility patches a safe home (Fiji
  made ImageJ 1.x more backwards-compatible than it wanted to be).

The latter purpose also includes hooks introduced by Fiji e.g. for
setting the application name, the window icon, or patching in the Script
Editor in place of the bare-bones text editor of ImageJ 1.x.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Move Fiji's JavassistHelper#disassemble() into the CodeHacker

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Move Fiji's JavassistHelper#writeJar() into the CodeHacker

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Add documentation for CodeHacker#disassemble

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Add documentation for CodeHacker#writeJar

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
CodeHackerTest: clarify an assertion

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
CodeHacker: organize imports

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Hack bytecode verification into the CodeHacker

This is extremely hacky at the moment: it assumes that you have
a Fiji.app/ in your home directory and loads the ASM embedded in
Fiji's jruby.jar. This is extremely fragile and needs to be cleaned
up. However, in the interest of YAGNI, this commit does not do
that yet.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
ij-legacy: add legacy plugins from $HOME/.plugins/

This is the first step to replace Fiji's FijiClassLoader: it looks
also in ~/.plugins/.

However, to test, and to be able to override, we also look at the
property 'ij1.plugin.dirs' which is interpreted as a PATH-style list
of directories. If this property is set, ~/.plugins/ is not looked
at automatically.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Test ij-legacy's ~/.plugins/ support

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
ij-legacy: stop the Java Agent whenever CodeHacker loads classes

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
ij-legacy tests: refactor getClassLoader()

This method serves only one purpose: to get a fresh class loader that
does not have any ImageJ 1.x classes loaded yet. That is too useful
for the legacy tests to be hidden in the headless unit test class.

While at it (because it is needed now), make the code more robust: do
not load the ImageJ class at all yet.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
ij-legacy tests: further refactor getFreshClassLoader()

We might need to make sure that other classes are found than the
Headless Example Plugin...

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Add javadocs for LegacyTestUtils#getFreshClassLoader

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
LegacyInjector: for testing, accept a fully-initialized CodeHacker

... instead of a ClassLoader.

But do not set the LegacyService in ij.IJ._service in that case because it
is most likely from another class loader.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>