Sometimes AntiVirus Scanners just suck

Due to some very strange and non reproducible bugs I deleted my NetBeans profile to get back to a fresh post-install state. This mainly hat two very different results: A positive one and the one why I am writing this post. The positive one is/was that the mystery-bug disappeared.

After deleting the profile, NetBeans wants to update all its modules to the latest releases – which is okay.
The problem however was that NB never managed to download all the modules and just got stuck randomly between 0% and 100%. NB just said “downloading …” but the task manager showed 0 bytes/sec traffic. First I thought that the download/update servers might be overloaded. After 3 days of repeatedly trying –  I was very douptful about that first guess. Finally I sent an email to the NetBeans mailinglist, if s.o else also experienced such a problem.

The first answer came in just 70min after my question saying “I had this problem and found that if I turn off AVG I could get the plugins.”.
Uhoh – I didn’t mention my AV scanner in my post – yet I am using AVG, too. And – surprise – after disabling resident shield, mail-scanner, link-scanner and identity protection – NB suddenly was able to update to the latest version. Unfortunately AVG never said that it was doing something of that kind!

So the lesson learned: If some really weird stuff is happening, try to disable the AV scanner – but don’t forget to re-enable it!

Update: same happens with Eclipse when downloading/installing plug-ins. – At least AVG is consistent with blocking Java-IDEs.

Linking API and Sources to your IDE’s JARs (Part 2)

I tend to upload my complete project into version control. This includes the sources, tests, Jars and also the nbproject directory where NetBeans stores the project configuration. By doing so, I can check out the project on a different machine and start quickly without having to configure the project.

Sources and API Docs of external libraries are not commited as they’re are not requried for compiling. I usually keep sources and docs in a separate place outside my project (let’s say <userdir>javaLibs...).

When I check out the project on a different machine I can do coding but I do have neither the sources nor the API docs. Even worse: as I’ve commited the whole project including the configuration, I have also commited the nbproject/project.properties file which stores the pathes to the source and docs. Which is not a problem if the pathes on all the machines are the same. But when a new contributer wants to join in, (s)he either has to use the same directory structure (and possibly the same OS) or he has to overwrite the settings. Both not very desirable.

Continue reading Linking API and Sources to your IDE’s JARs (Part 2)

Linking API and Sources to your IDE’s JARs

For productive programming, I think it is absolutely crucial to also have both the API documentation and the source code of the according libraries available and integrated in the IDE in order to gain maximum productivity. Integrating the API and sources is pretty easy in NetBeans (as well as in other IDEs):

Right click the Project > Properties > Libraries > select the JAR for which you want to link source and API and hit the edit button on the right.
Now you can select a folder, Zip file or Jar file for the API and sources, hit OK and you’re done.

Whenever you’re using a class from this library, you now can step into this class (by Ctrl-Clicking for example) or quickly jump to the API by pressing ALT+F1 when the curser is at the corresponding class/method.

If you are annoyed by swithing between IDE and Browser or if you just forget the Alt+F1 key combo that opens the browser with the correct API page, just enable the NetBeans inline Java-Doc viewer by selecting:
Window > Other > JavaDoc
This brings up a new panel which shows the JavaDoc comment of the class/method which is curently selected by the cursor. And you don’t even need to press any key for updating the view as it is updated automatically.

If it doesn’t work, I usually experience the following two errors:

  1. JavaDoc doesn’t work: If I perform Alt+F1, the browser doesn’t open and the status bar on the bottom of the NetBeans window shoes a “Cannot perform Show Javadoc here”. Well – check the Path then. It should end in a directory that also contains the index.html, package-list, allclasses-frame.html etc.
  2. The source is not displayed – even though the path to the Jar/Zip is correct! In that case, The Zip/Jar often contains all the source code in src/mypackage/foo.java. NB expects only packagis in the Zip, so that the content list should look like: maypackage/foo.java. So simply build another src.zip with the contents of “src/” (in this case) and you’re done.

Speicherverbrauch in Java oder “Size does matter!”

Eines der Vorurteile gegenüber Java ist ja der (angeblich) enorme Speicherverbrauch. Frage ich dann, ob denn die entsprechende Applikation schon mal auf Speicherverbrauch geprofiled wurde und welcher Profiler verwendet wurde, gibt es große Augen und Gestammel über HeapSize, OutOfMemoryExceptions und dass in C ja eh alles besser sei. Na, da weiß man doch gleich dass nicht nur Java schuld sein muss. – Hat man mal mit ImageJ gearbeitet, ist man ab und an schon äußerst verwundert, wie schnell Java sein kann – und fühlt sich auch angespornt seine eigenen Kenntnisse  zu erweitern.

Generell gibt es zur Speicherdiskussion (mindestens) zwei Szenarien.

  1. Die Diskussion, wieviel Speicher eine Datenstruktur verbraucht und ob nicht eine andere Speicherstruktur besser ist.
  2. Wir haben eine OOME und müssen sie beseitigen.

Wieviel Speicher verbraucht meine Datenstruktur?

DAS ist jetzt mal wirklich ein Nachteil von Java wie er im Buche steht, denn es gibt per se keine wirklich einfache Möglichkeit, den Speicherverbrauch einer Struktur oder eines Objektes zu ermitteln. Der Artikel From Java code to Java heap ist hier definitiv anzuraten. Hier wird detailierter über den Speicherverbrauch von Klassen eingegangen.

Im Java Specialists Newsletter von 2001(!!) gibt es einen einen Workaround und ein paar weitere Erklärungen – es folgt eine teils Übersetzung aus dem Newsletter:

  1. Jede Klasse belegt mindestens 8 Bytes auf dem Heap (also auch ein new Object()).
  2. Jeder Datentyp belegt 4 Bytes, außer long und double, die 8 Bytes belegen. Achtung, das heißt, auch ein Datentyp byte benötigt dann 4 Bytes. Außerdem wird der Speicherverbrauch nur in 8 Byte Schritten erhöht. D.h eine Klasse mit einem byte Datentyp belegt 8 Byte für die Klasse + 8 Byte für die Daten = 16 Byte.
  3. Arrays sind speicherschonender  – der geneigte Leser darf das gerne selbst nachlesen.
  4. String#intern() kann ordentlich Speicher sparen.
  5. Boolean.TRUE und Boolean.FALSE benötigen weniger als new Boolean(true).

Okay, alles schön und gut. Aber eine komplexere Struktur benötigt dann wieviel genau? Im Java Specialists Newsletter ist dazu eine kleine aber feine Klasse, die hier weiterhilft:

public class MemoryTestBench {

    public long calculateMemoryUsage(ObjectFactory factory) {
        Object handle = factory.makeObject();
        long mem0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
        long mem1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
        handle = null;
        System.gc();System.gc();System.gc();
        System.gc();System.gc();System.gc();
        System.gc();System.gc();System.gc();
        System.gc();System.gc();System.gc();
        mem0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
        handle = factory.makeObject();
        System.gc();System.gc();System.gc();
        System.gc();System.gc();System.gc();
        System.gc();System.gc();System.gc();
        System.gc();System.gc();System.gc();
        mem1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
        return mem1 - mem0;
    }

    public void showMemoryUsage(ObjectFactory factory) {
        long mem = calculateMemoryUsage(factory);
        System.out.println(factory.getClass().getName() + " produced " + factory.makeObject().getClass().getName() + " which took " + mem + " bytes");
    }
}

Die ObjectFactory sieht so aus:

public interface ObjectFactory { public Object makeObject(); }

Und am Beispiel einer ByteFactory sieht das wiederum so aus:

public class ByteFactory implements ObjectFactory { 
   public Object makeObject() { return new Byte((byte)33); } 
}

Jup, etwas aufwändig. Aber immerhin ein Ausweg aus dem Dilemma um hypothetische Diskussionen was wohl besser sein könnte. Und ja, DAS ist in C wirklich einfacher – und trotzdem will ich weiter Java verwenden 😀

OMG, OOME – was tun?!

Regel 1: NICHT blindwütig irgendwo irgendwas irgendwie anders machen.
Regel 2: Auch nicht nachdenken und glauben zu wissen wo es weh tut.

Sondern? Messen!
Zum Beispiel mit der JVisualVM, die bei neueren SUN/Oracle JDKs (nicht JRE) bereits im bin-Verzeichnis der JVM mitgeliefert wird. Ist man eh mit NetBeans unterwegs, kann man das Programm auch nochmal von dort direkt profilen. Ich persönlich setze den erlaubten Speicher (also -Xmx) dann gleich kleiner an, damit die OOME schneller eintritt und weniger Daten betrachtet werden müssen.

Mit etwas Glück sieht man dann recht schnell, welche Datenstrukturen (zu) oft im Speicher sind und kann dann gezielter nach den Referenzen suchen, die es eigentlich gar nicht geben sollte.

How to use TableModels and ListModel with NetBeans GUI Builder

A default JTable or JList comes with it’s own pre initalized model. Okay – but: how can we modify this model? Which type of model is usually pre initialized?
In the following I’ll just list some of the may possible ways to work with tables and lists and the NetBeans Gui Builder:
Continue reading How to use TableModels and ListModel with NetBeans GUI Builder

How to pack multiple JARs into one using ANT (and NetBeans)

Eines der Features, die ich bei NetBeans eine ganze Zeit lang nicht realisiert hatte war die Tatsache, dass NetBeans beim Compilieren automatisch ein ausführbares JAR erstellt, und JAR nebst Libraries in das “dist”-Verzeichnis im Projektordner kopiert. Das heißt das sieht dann so aus:

Coole Sache eigentlich. Nur – um die Applikation einfach so online zu stellen oder jemandem aufs Auge zu drücken (oder in den Java Store hochzuladen), wäre es doch fein, wenn man nur noch ein einziges JAR hätte und nicht noch zusätzlich die ganzen Libs aus “/dist/libs/” mitschicken muss (und das können schon einige sein – in meinem Mini-Projekt zB schon 19).

Viele Leute ziehen ein Jar zB einfach auf den Desktop um es direkt dort per Doppelklick zu starten. Das geht in dem Fall nicht mehr, da ja der libs-Ordner auch auf dem Desktop liegen müsste. Klar, eine Möglichkeit wäre, die Applikation woanders hin kopieren und eine Verknüpfung auf den Desktop legen – aber wir wollen dem User ja entgegenkommen.

Also:  ein einziges JAR muss her. Im Sun Developer Network (SDN) findet sich dazu auch die passende Anleitung im Artikel: “Use NetBeans IDE 6.7 to Combine JAR Files Into a Single JAR File“. Dort wird schön erklärt, wie man die build.xml ändern muss um genau das zu erreichen.

In diesem Sinne: Viel Erfolg beim ausprobieren.

NetBeans mit mehr RAM starten

Gerade eine Frage auf der NetBeans Mailinglist die Frage gelesen, wie man NetBeans mit mehr Ram starten könne.

Eine Google-Anfrage später die Antwort:
Eine entsprechende Einstellung lässt sich in  [NetBeans Installationspfad]/etc/netbeans.conf vornehmen.
Aber .. welche Größe hat NetBeans denn nun per Default? Ein Blick in eben genannte Conf zeigt:

# Note that a default -Xmx is selected for you automatically.
# You can find this value in var/log/messages.log file in your userdir.
# The automatically selected value can be overridden by specifying -J-Xmx here
# or on the command line.

Aha. [Userverzeichnis]/.netbeans/6.7/var/log/messages.log soll also Auskunft geben – und tut es auch. Dort steht bei mir (unter anderem)  “-Xmx407m”.

Fragt sich, wann dieser Wert gesetzt wird. Zum Installationszeitpunkt hatte ich 1024Mb Ram verbaut – später auf 2048Mb erweitert. Auf meinem Arbeitsrechner (2048Mb Ram) steht der Wert auf “-Xmx409m” – also fast gleich. Die Vermutung liegt nahe, dass die Einstellung beim Start automatisch angepasst wird.