Maven2: native2ascii conversion from UTF-8 to ascii

November 13th, 2008 by joachim

Sometime it’s necessary to convert .properties files which have been saved as UTF-8 to the native ascii format so they can be loaded by Java applications later on. If you use Maven2 you will run into some nasty problems. Whatever you do, the files seems to never be converted…

Let’s assume we want to convert the file i18n/lift-core_de_DE.properties to the .properties ascii format (escaped unicode characters). You need this section in your POM file:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>native2ascii-maven-plugin</artifactId>
<configuration>
<src>src/main/resources/i18n</src>
<dest>target/classes/i18n</dest>
</configuration>
<executions>
<execution>
<id>native2ascii-utf8</id>
<goals>
<goal>native2ascii</goal>
</goals>
<configuration>
<encoding>UTF8</encoding>
<includes>lift-core_de_DE.properties</includes>
</configuration>
</execution>
</executions>
</plugin>

But if you look into target/classes/i18n/ after a compile you still can see the old data… The problem is that the maven resource plugin overwrites the converted file. Use this in your pom.xml file :

<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/lift-core_de_DE.properties</exclude>
</excludes>
</resource>
</resources>

Posted in Java, Sprache: Englisch | No Comments »

How to solve a “java.lang.LinkageError: <some class>” between two JAR files?

June 17th, 2008 by matthias

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.

Posted in Eclipse, Java, Sprache: Englisch, alle Artikel | No Comments »

How to correct wrong / missing SVN annotation icons in Subclipse 1.2.4?

June 16th, 2008 by matthias

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.

Posted in Eclipse, Java, Sprache: Englisch, alle Artikel | No Comments »

How to correct the error “dir .svn missing” when using “Team -> Share project …” (of Subclipse 1.2.4)?

June 16th, 2008 by matthias

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.

Posted in Eclipse, Java, Sprache: Englisch, alle Artikel | No Comments »

How to create a Java project in Eclipse from an existing JAR file, that way that the JAR is not uncompressed?

June 16th, 2008 by matthias

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.

Posted in Eclipse, Java, Sprache: Englisch, alle Artikel | No Comments »

How can I register a JAR library that’s part of my Eclipse plugin so that it’s accessible from the plugin and so that “PDE-Tools > Update classpath…” can be done without losing this registration?

June 16th, 2008 by matthias

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.

Posted in Eclipse, Java, Sprache: Englisch, alle Artikel | 1 Comment »

Java: Which library should I know?

May 2nd, 2008 by joachim

You should definitely know the Google Collections Library. A very useful collection of classes which can be used in all sorts of places in an application. The library is licensed under the Apache License 2.0 so that shouldn’t be a problem, I think.

Personally I love the classes Preconditions, Lists, Sets, and Maps. Have a look at the other classes - there are some more. It’s absolutely worth it!

Posted in Java | No Comments »

Java: How do I simplify handling of booleans?

May 2nd, 2008 by joachim

Working with booleans is simple and easy, right? Right. But sometimes it’s quite redundant. Conside a simple class called Human, which consists of a firstname, lastname and a weight.

The code on this page is trivial but in my experience very useful. There are many places where you can use the BooleanWorker class. Here’s an example for such a case:

  1. public class Human {    
  2. private Integer weight;    
  3. private String firstname;    
  4. private String lastname;
  5. //… skipped constructor, equals, hashCode, setters and getters
  6. }
  7.  

And this is what IntelliJ 7 generates for the equals() method:

  1. public boolean equals(Object o) {
  2.     if (this == o) return true;
  3.     if (o == null || getClass() != o.getClass()) return false;
  4.  
  5.     Human human = (Human) o;
  6.  
  7.     if (firstname != null ? !firstname.equals(human.firstname) : human.firstname != null)
  8.         return false;
  9.     if (lastname != null ? !lastname.equals(human.lastname) : human.lastname != null)
  10.         return false;
  11.     if (weight != null ? !weight.equals(human.weight) : human.weight != null)
  12.         return false;
  13.  
  14.     return true;
  15. }
  16.  

Quite nice code but not very good to read.
I prefer something like this:

  1.  
  2. public boolean myEquals(Object o) {
  3.     if (this == o) return true;
  4.     if (o == null || getClass() != o.getClass()) return false;
  5.  
  6.     Human human = (Human) o;
  7.  
  8.     BooleanWorker w = new BooleanWorker();
  9.     w.rememberEquals(firstname, human.firstname);
  10.     w.rememberEquals(lastname, human.lastname);
  11.     w.rememberEquals(weight, human.weight);
  12.     return w.isValid();
  13. }
  14.  

Of course, in comparision there’s one object creation and several method calls. But hey - I don’t care. It’s better to read now and more DRY at the same time. And the Java VM is optimizing anyway, so I think most of the code will be inlined. But I’m too lazy to check that.

Here’s the implementation.

  1. package de.ansorgs.common.util;
  2.  
  3. /**
  4.  * This class helps building equals methods.
  5.  * It is not thread safe.
  6.  * <p/>
  7.  * License: Public domain. If you like please mention me as the original author.
  8.  *
  9.  * @author Joachim Ansorg, java at joachim-ansorg . de
  10.  */
  11. public class BooleanWorker {
  12.     private boolean result = true;
  13.  
  14.     public boolean isValid() {
  15.         return result;
  16.     }
  17.  
  18.     public final void remember(final boolean value) {
  19.         this.result = this.result && value;
  20.     }
  21.  
  22.     public void remember(final Boolean value) {
  23.         remember(value.booleanValue());
  24.     }
  25.  
  26.     /**
  27.      * Compares two objects. If a equals b the result stays the same, if they
  28.      * don’t equal the result is set to false.
  29.      * This method accepts null values.
  30.      *
  31.      * @param a First object. May be null.
  32.      * @param b Second object. May be null.
  33.      */
  34.     public void rememberEquals(final Object a, final Object b) {
  35.         if (!result) {
  36.             return;
  37.         }
  38.  
  39.         if (a != null && b != null) {
  40.             remember(a.equals(b));
  41.         } else {
  42.             //at least a or b is null, so we return true if both are null
  43.             //otherwise we return false
  44.             remember(a == b);
  45.         }
  46.     }
  47. }
  48.  

Posted in Java | No Comments »

Wie lerne ich am schnellsten eine neue Sprache / Technologie / Bibliothek?

May 1st, 2008 by joachim

Wie kann sich ein Softwareentwickler am schnellsten und besten in eine neue Technologie (Programmiersprache, Framework, Bibliothek, etc.) einarbeiten?

Hierbei kommt es zu Beginn etwas auf den persönlichen Kenntnisstand an. Je nach Person bieten sich unterschiedliche Wege an. Im folgenden folgt mein persönlicher Eindruck der besten Lernmethoden.

Read the rest of this entry »

Posted in Java | No Comments »

Welche Java-Entwicklungsumgebung sollte ich verwenden?

May 1st, 2008 by joachim

Die Wahl einer guten Java-Entwicklungsumgebung stellt sich sobald man anfängt ernsthaft Software zu entwickeln. Im Vergleich zu einem einfachen Texteditor bietet eine IDE große Vorteile:

  • Unterstützung bei der Navigation und Compilierung des Quellcodes
  • Unterstützung durch automatisierte Refactorings
  • Unterstützung bei der Programmierung durch Code-Vervollständigung, Anzeige von Fehlern, Fehlerkorrekturen, Code-Generierung, usw.

Ich denke man sollte einer der folgenden Umgebungen verwenden, in der Reihenfolge meiner persönlichen Vorliebe:

  1. Jetbrains IntelliJ IDEA: Die meines Erachtens beste Java-Entwicklungsumgebung, die ich nun schon einige Monate verwende. IDEA überrascht mich immer wieder durch die scheinbare Intelligenz. Der Prduktivitätsgewinn ist unübersehbar. Die besten Features für mich: sehr gute Refactorings, “intelligente” Codegenerierung, Codemetriken, sehr gute Navigationsmöglichkeiten, sehr gute Bedienung mit Tastenbefehlen, gute Erweiterungen für z.B. Spring, Groovy, Javascript, HTML und CSS.
    Die Programmierung macht einfach großen Spaß mit IntelliJ.
    Ein kleiner Nachteil ist der Preis, IDEA kostet nämlich etwas. Aber die paar Euros sind schnell vergessen, wenn man erstmal damit gearbeitet hat :) Außerdem kann man die Software für 30 Tage testen.
  2. Eclipse. Falls man IntelliJ nicht mag, ist Eclipse die große Alternative, zumal es auch noch kostenlos ist. Eclipse ist sehr mächtig und bietet ähnliche Features wie IDEA, allerdings meist nicht ganz so gut.
  3. Netbeans. Die dritte große Alternative. Hab ich allerdings kaum verwendet, gefiel mir nicht wirklich.
  4. Oracle JDeveloper. Gute Java-IDE von Oracle Ein paar Monate verwendet, ist mir allerdings zu sehr auf Oracle-Produkte gemünzt. Aber durchaus interessante Ansätze.

Man sieht, es gibt genügend Alternativen. Mein persönliches Fazit: Möchte man etwas Geld ausgeben: IntelliJ IDEA, ansonsten: Eclipse.

Posted in Java | No Comments »