A jailhouse is probably one of the worst places to be, as an inmate, and one of the least positive places, for the society. The more interesting is an example of what can be made out of such a calamity. Here’s a documentary video of Mr. Garcia, manager of the CPDRC prison in the Philippines, and what he made out of his prison.

Just wanted to share this as a motivating example of an ingenious idea what can be done for society even if the starting situation is one of the worst possible ones. I’d like to see such ideas in more men of this world, in men of our country, and in me 🙂

If you liked to watch the dancing prisoners in the clip above, here are all the videos from Mr. Garcias official YouTube account.

A java.lang.LinkageError happens when “a class has some dependency on another class; however, the latter class has incompatibly changed after the compilation of the former class.” [Java Platform SE 6 API Docs on LinkageError]. Normally, the error is more concretely defined by subclasses of LinkageError, but not always. There are multiple reasons possible:

  1. You have a JAR file in your project that requires another JAR file that’s not in your project. In this case, the latter JAR file is installed somewhere on your system. It is found, but it’s version differs from the version where the JAR file in your project was compiled against. So to speak, the JAR file “changed (in version) after the compilation of the JAR file that’s in your project”.
    A solution (sometimes possible) is to include the requiring JAR as source code into your project. Then, it is comiled itself, and correctly linked against the available version of the required JAR file.
    The alternative, obvious solution is to let the JAR find its expected version of the required JAR files. You may influence this by the order of entries in the Java build path, or if you do Eclipse plugin development and you want JAR files within your plugin to be found, in the plugin classpath in MANIFEST.MF.
  2. You run into an error of Eclipse 3.3.1.1. You recognize this if the java.lang.linkage error persists even if both the requiring and the required JAR files are replaced by source versions in the Eclipse project. (This bug possibly applies only to Eclipse plugin projects.) If this is the case, the required library is one that’s also part of the Java system library. It seems that the Eclipse framework uses its own class loader and replaces the Java class loader, or something with similar effect. The effect is that at runtime, the code refers to other code (always the library that’s part of the Java system library) than at compile time (the library within the same or another plugin project). So again, the required JAR file “changed” (in version) from compile time to runtime.
    Solution: include the requiring JAR as source code, and remove all duplicates of the library from your projects, so that the only installed version of the required JAR library is in the Java system library. Now both at compile and runtime, this is the only thing where requiring code can refer to.

A concrete example for the Eclipse bug described above: the error message was “java.lang.LinkageError: org/xml/sax/ContentHandler” in a plugin used to capsule JDOM code (as source, not as a JAR file).

Due to the bug, at runtime JDOM code always used the Java system library’s SAX when doing “import org.xml.sax.ContentHandler”. Regardless of what the code referred to at compile time: SAX in a JAR file in the same or a required plugin project, SAX as source code in the same source folder of the same plugin project etc..

Also, using the “order” feature when configuring the Java build path of the JDOM plugin project did not help: “plugin dependencies” can be placed above “Java system library”, but regardless of that setting, at runtime the Java system library was used. And this was a JAR file with a different version than what the project was compiled against at compile time … .

The solution was this: remove the dependency from another plugin that contained SAX as a JAR library, and (!) remove the SAX source and JAR files from the plugin project that encapsuled JDOM. Only one of these steps is not enough. Both together probably made Eclipse compile against the same lib as used at runtime, namely SAX form the Java system library.

To conclude: currently, there seems to be no possibility to use a package in place of a package of the same name that’s supplied by the Java system library; which is an Eclipse bug.

Here’s one solution to one cause, there might be other causes as well. The error means that the class definition existed when compiling but disappeared in the meantime (see Sun Documentation). You see this from the fact that this error message is thrown e.g. when deleting a necessary .class file in the bin output folder of a project. (However, deleting a .class file may also result in java.lang.ClassNotFoundException, for classes that are dynamically loaded by some configurable class loader utility.

In this case, a plugin needed a library (JDOM), which was capsuled in another plugin. Note that these errors are hard to trace with a debugger: the line that generates the exception may need one type of the required library in the other plugin, and that type might be a subtype of the one that’s in the error message, or similar complicated things. With the debugger, you cannot “step into” the loading of statically bound .class files (that’s behind the scenes), and therefore just see this error message appearin out of nothing. You can, however, “step into” the loading of dynamically loaded classes, where some configurable class loader utility is involved.

First, here’s the list of things that did not help:

  1. It was no problem of a missing .class file, as the required .class file was in place.
  2. Cleaning and rebuilding the at.ezra.thirdparty.jsword project (equivalent to deleting bin/*) changes nothing regarding these errors. So it’s not just due to a missing or erroneous .class file.
  3. “PDE-Tools -> Update classpath…” for all or some plugins does not cure the errors.
  4. It might be necessary to include a plugin dependency to the plugin that contains the library, even if Eclipse doesn’t demand this. Eclipse might not notice that this dependency is necessary if the library is just necessary in dynamically loaded classes, involving some configurable class loader utility. However, this did not solve the issue here.
  5. It was no problem of lacking dependencies etc. between the two plugins, as the error even arouse when placing the library .jar file directly into the plugin that needed it.

And now, the thing that did the cure:

  1. Open MANIFEST.MF of the plugin that contains your not-found class definition (here the library plugin). Use the Eclipse manifest editor for this.
  2. Go to tab “Runtime”, section “Classpath”, click “New” and enter “.” in the edit box. That’s it. In this tab, it’s written that the plugin root dir is automatically (!) the plugin’s class path, but they mean, only if there are no additional entries, in which case one must enter “.” additionally. You need additional entries if you plugin’s library file is located outside of the plugin root dir, e.g. in “lib/”.

The result is a new line “.” (last line in code below!) in the build.properties file, meaning that the plugin’s root dir is now included into the plugin’s classpath. Only then, the .class files in the bin directory can be found, as the bin directory is placed below the plugins root dir. (This whole thing might be an Eclipse bug, actually …).

bin.includes = META-INF/,
lib/jaxen-core.jar,
lib/jaxen-jdom.jar,
lib/saxpath.jar,
.

Additionally, the following steps might be necessary: add the following lines in the plugin’s build. properties file (they might be missing, but at least the src.. and bin.. lines should be present in all plugins):

jars.compile.order = .
source.. = src/
output.. = bin/

A tip: the general process of removing path-related / class search related errors is probably this: compare build.properties, .classpath and MANIFEST.MF with working species of these files from other plugins.

And if you get a “java.lang.LinkageError: <some class>” error, this might be just a synonym of this error, so check this first.

Annotation icons are the small icons placed on top of other icons, mainly in the package explorer view of Eclipse. In Subclipse 1.2.4, it can happen that these are no longer shown (or incorrectly shown), though the project is in SVN.

To correct missing icons, restart Eclipse or switch the workspace forth and back.

To correct wrong icons (like »?« where »in sync« should be), disconnect the project from SVN without deleting the SVN metadata, then reconnect.

The full error message is:

org.tigris.subversion.javahl.ClientException: svn: Directory '[...]/.svn' containing working copy admin area is missing

And when creating the .svn directory yourself in your local directory, the following error appears:

org.tigris.subversion.javahl.ClientException: svn: Unable to lock '<plugin project name>'

This seems to be a bug in Subclipse 1.2.4. The solution: do manually what the “share project …” wizard would do. That is:

  1. Create a new remote directory in the SVN repository view.
  2. Check that directory out on top of the existing project.
  3. Say yes to deleting the local resource: that means just the directory, not the files in it.
  4. Commit your files to SVN.

Create a new plugin and choose “from existing archive file”.

If you want to add the JAR file to an existing project, the simplest way is to import the JAR file using “File -> Import …”. You now need to tell Eclipse that it’s something where Eclipse is allowed to read executable code from, i.e. you need  to add it to the Java classpath. The simplest way would be to right-click the file in package explorer and add it to the build path. The problem is that the effect gets lost when choosing “PDE-Tools > Update classpath …”. Therefore, better follow the way described in this post.

What works. You need to include the JAR in the MANIFEST.MF file: when using the MANIFEST editor from Eclipse, navigate to tab “Plugin”, section “classpath”, and add the JAR there. And, if you want to have these JARs accessible from other plugins, add the corresponding packages to section “exported packages”.

What does not work. If you however just right-click the JAR file in package explorer and chose “Add to Build path” and (in case the JARs shall be accessible from other plugins) tick the JAR file in “Configure Build Path > Order and Export”, these changes get lost when using “PDE tools > Update classpath…”.

Explanation. As a general rule, the PDE mechanisms are a layer above the “normal” Java build path mechanism, i.e. simply use the higher level exclusively and you stay out of problems. The “PDE Tools > Update classpath” means probably: update the Java classpath (=Java build path) from the plugin’s classparth (= OSGi BundleClasspath in MANIFEST.MF, edited as described above); i.e. it’s the penetration of changes from PDE to (lower) Java abstraction level.