home | tech | misc | code | bookmarks (broken) | contact | README


Java notes

Developing a Java EE application without an IDE

With Java popularity, Java IDEs also arose as de facto standards for Java development. NetBeans and Eclipse emerged as the most known IDEs in the Java world and later have added support for other languages.

Companies have standardized those (or other) IDEs as the unique development environment developers could use, to the detriment of other tools like simple text editors (Vim or Emacs) and, sometimes, have prohibit developers to use tools other than the IDE they have chosen. IDEs also provide a tight integration with other tools (compilers, deploy tools, source code review, etc.) that makes it difficult for text editors users to know how to to integrate than besides the traditional way (editor + Makefile).

The idea of this section is to document my experience regarding using a project developed in Eclipse using nothing more than Vim and command line tools to build and making a full deploy of a Java EE (.ear) application. I believe that the procedure may be similar for NetBeans or other IDEs.

The scenario

My scenario is: I started to work in a relatively small team with around 8 developers developing a Java EE application with around 1 million of lines of code. The code base was bought from another company and all of it was developed from Eclipse. The (poor) documentation was fully written taking Eclipse as a starting point and all related tools are integrated with Eclipse. Want to generate a simple EAR file? You need Eclipse. Want to run JBoss to show up your application? You need to open Eclipse and launch JBoss from there.

The application we were developing was heavy. It spawns dozens of threads on startup, it used lots of different frameworks and it needs at least 4 GB to run basic features. Worse: JBoss and Java are itself bloated stuff that made things worse. How someone could still use Eclipse in this environment? We cannot get rid of the application or JBoss, but we can get rid of Eclipse.

To get things worse, all developers used either Microsoft Windows or Ubuntu GNu/Linux, which Eclipse supports, but I used NetBSD.

The procedure to eliminate Eclipse and use Apache Ant to compile the project

First of all, Eclipse does not use the javac compiler that you will find in a plain JDK installation. It uses its own compiler called Eclipse Compiler for Java (ECJ) and they do that because of tighter integration with the IDE (see this for more details).

For a reason I don't remember, I couldn't use the javac compiler that comes with JDK. So I had to use Eclipse compiler. Because of that, you will need to copy Eclipse plugins directory anywhere, where package org.clipse.jdt.core.* and dependencies belong to. To avoid dependency problems, I copied the full plugins directory. In this example, it was copied to /opt/eclipse-kepler-plugins (yes, it is a past version of Eclipse but it is what the team is using).

Eclipse also builds the project automatically, without a explicit build file (like a Makefile or Apache Ant build.xml). Since we will build the project manually after editing files in the text editor, we will need to generate this script. This is an Apache Ant script. To generate that, in Eclipse, click the File menu, and then Export. Chose option Ant build file and export it. It will generate a file build.xml.

Note

Since I didn't want to install Eclipse just to generate this file, I asked one of my colleagues to generate it for me.

Note

In the project we were working on, there was already a build.xml file used to generate EAR files. Because of that I exported to a different name, make.xml and had to explicitly pass its name to ant as ant -f make.xml.

So, after generating the build.xml file, you'll need to add a line to it, specifying that you are going to use the Eclipse compiler. According to this page you just need to include the following line just before the <javac ...> tag:

<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter" />

An important thing is to add the JAR files of the eclipse plugins directory to your class path. It can be done within the build.xml file. In your project's <path ...> tag, add it:

<fileset dir="/opt/eclipse-kepler-plugins" includes="*.jar"/>

It may be enough! A call to ant should now compile every .java file and generate .class files. Minor tweaking may be necessary in build.xml to match your system configuration.

Note

How to generate .ear files is beyond the scope of this text, since there was a separated ant file in the project that did that and I just called it, never needing to see how it worked.

Troubleshooting

error: type Pair does not take parameters

In my case I was compiling a project in 1.7 where I should use 1.6. Maybe the Pair type changed between these versions?

package com.sun.istack.internal does not exist

An error like that means that you are using a type that exists, but your are not allowed to access it, mostly because it is internal to the Java language. javac forbids it (see this link to understand how) and the only way to override that is to use the -Dignore.symbol.table.

If you are using ant you may use the <compilerarg> tag to pass parameters to the compiler (see this for more information).

Important

Other compilers, like the Eclipse Java Compiler don't have this restriction.

SEVERE [application] java.lang.NoSuchFieldError: ALIAS_TO_ENTITY_MAP

According to this page this error happens when you compile your class using a version of a package and run using another.

The problem I had was that I was compiling it against one version of Hibernate and running it in JBoss with the version that comes with JBoss. The solution I found was to delete *hibernate* files from the lib directory of JBoss.

(Is there a non-destructive solution?)

The type <typename> cannot be resolved. It is indirectly referenced from required .class files

If you look for this error on the web you'll get lots of information regarding the binary compability of JRE/JDK you are using. Make sure your target binary has version that match your Java version. Normally this is a parameter passed to the java compiler and is configured either in IDE settings or in an Ant file (build.xml) or build system file.

My problem, though, was different and simple. When compiling a huge problem, I forgot to add a jar file to the CLASSPATH. Since I was using an Ant build file (build.xml), it was enough to add the following line to the place that defined classpath:

<pathelement location="location/of/the/jar/file" />