JTable HeaderRenderer mit System LookAndFeel (PLAF)

Ach, es ist schon ein Kreuz mit Plattform-Designs. Insbesondere mit Swing. Will man für Tabellen die Spaltenköpfe etwas optisch anpassen, aber zugleich das System-Design nicht verlieren, muss man ein paar kleine Tricks anwenden, die gar nicht mal so gut dokumentiert sind.

Hier mal ein Beispiel wie es für Windows 7 aussieht, wenn man des Standard-Renderer nutzt:

JavaHeaderWin7

So sieht es aus, wenn man nach den üblichen Rezepten vorgeht und einen eigenen Renderer verwendet:

JavaHeaderWin2k

Sogar wenn man den original installierten Renderer (der durch das PLAF gesetzt wurde) aus dem JTableHeader nimmt und diesen ändert, wird man feststellen, dass die Tabellenköpfe trotzdem wie aus den 90′er Jahren aussehen.

Der eigentliche Grund ist, dass man i.d.R. es verpasst UI-Änderungen des UIManager an den Header-Renderer weiterzuleiten.

Generell ist es gut dem eigenen Renderer im Constructor den als Standard installierten Renderer mitzugeben, der von Java Swing sowieso gesetzt wird:

public class DBTableHeaderRenderer 
            extends DefaultTableCellRenderer 
            implements TableCellRenderer {
private final TableCellRenderer headerRendererUI;
public DBTableHeaderRenderer(TableCellRenderer headerRenderer) {
  this.headerRendererUI = headerRenderer;
}

Nun holt man in der getTableCellRendererComponent Methode aus dem headerRendererUI die Renderer-Komponente, die man anpassen möchte:

@Override
 public Component getTableCellRendererComponent(
   JTable table, Object value,
   boolean isSelected, boolean hasFocus, int row, int column) 
 {
   Component resUI = headerRendererUI
                    .getTableCellRendererComponent (table, value,
                                  isSelected, hasFocus, 
                                  row, column);
  if (resUI instanceof JLabel) {
    JLabel label = (JLabel) resUI;

Wenn man das debugged, stellt man fest, dass in resUI tatsächlich die UI-Komponente aus dem System-PLAF ist, aber trotzdem sieht es aus, als würden die Header wie in Windows 2000 gezeichnet.

Änderungen beim PLAF werden allen Komponenten via updateUI mitgeteilt. Im unseren Renderer können wir die Methode überschreiben und die Benachrichtigung an headerRendererUI delegieren:

 @Override
 public void updateUI() {
   TableCellRenderer tcr = headerRendererUI;
   if (tcr instanceof JComponent) {
     ((JComponent) tcr).updateUI();
   } else {
     super.updateUI();
   }
 }

Obwohl dies das exakt richtige Vorgehen ist, wird man beim nächsten Test sich die Haare raufen. Der Renderer sieht immer noch altbacken aus.

Wir müssen unseren Renderer noch mit einem Marker-Interface ausstatten, damit auch wirklich updateUI aufgerufen wird. Also muss die Klassen-Deklaration ergänzt werden:

public class DBTableHeaderRenderer 
       extends DefaultTableCellRenderer 
       implements TableCellRenderer, javax.swing.plaf.UIResource {

Mit dem UIRessource-Interface ist der Renderer nun endlich optisch auf Höhe der Zeit und man kann das JLabel nun nach eigenen Wünschen anpassen.

 

Veröffentlicht unter API, Java | Verschlagwortet mit , , , , | Hinterlasse einen Kommentar

NetBeans Platform Anwendungen mit Maven Deploy zu Artifactory

Wer schnell auf Artifactory deployen will, ohne den nächtlichen Build (z.B. mit Hudson oder Jenkins) abzuwarten, kann das natürlich für die NetBeans IDE einrichten.

Zunächst muss in den settings.xml der Artifactory-Server mit Credentials hinterlegt werden. Die settings.xml findet man in beliebigen Maven-Projekten unter “Project Files”. Alle Projekte zeigen da immer die gleiche settings.xml an. Sollte sie noch nicht existieren, bietet das Kontextmenü von “Project Files” den Punkt “Create settings.xml” an.

In die settings.xml kommt nun der Server-Eintrag:

<servers>
  <server>
    <id>{repo-id}</id>
    <username>{repo-benutzer}</username>
    <password>{kennwort/verschlüsseltes kennwort}</password>
  </server>
</servers>

Die repo-id ist z.B. libs-releases-local.Der Username sollte im Artifactory angelegt sein und Deployrechte haben. Das Kennwort ist ein grundsätzliches Problem von Maven. Das kann üblicherweise nur Plaintext sein. Artifactory in aktuellen Versionen erlaubt aber explizit auch verschlüsselte Passwort-Token zu verwenden. Wie das geht, wird hier erklärt.

Nun benötigt man noch das passende Maven Plugin für den Deploy-Vorgang. Das wird entweder im application Projekt-Pom eingetragen oder im darüber liegenden super-pom (soweit verwendet):

<build>
  <pluginManagement>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-deploy-plugin</artifactId>
        <version>2.8.1</version>
     </plugin>
...

Den oben definierten Server kann man in der selben pom.xml als Distribution Management eintragen:

<distributionManagement>
  <repository>
    <id>{repo-id}</id>
    <name>{repo-id}</name>
    <url>http://{server}:{port]/artifactory/{repo-id}/</url>
  </repository>

</distributionManagement>

Für ein mvn deploy würde es auf der Kommandozeile reichen. Aber wir nutzen ja die NetBeans IDE. Da der Befehl nicht für jedes Projekt eingetragen werden soll (es gibt da nicht die Möglichkeit des Super-Pom, sondern es sind NetBeans Konfigurationen), kann man das in der IDE global hinterlegen.

Dafür das Menü Tools -> Options öffnen. Zu Java wechseln und Maven in der Registerzunge auswählen. Unter der Kategorie Executions gibt es den Button [Edit Global Custom Goal Definitions...]. Den Anklicken. Im Dialog [Add...] anklicken und die Action einfach “Deploy” benennen. Diese in der Actions-Liste auswählen und bei Execute Goals deploy eintragen. Mit [Ok] bestätigen. Aus den Optionen wieder raus.

Nun hat man in jedem Maven-Projekt im Kontextmenü unter Custom die Action Deploy. Die funktioniert natürlich nur in den konfigurierten Projekten.

Veröffentlicht unter Maven, NetBeans, NetBeans Plattform | Verschlagwortet mit | Hinterlasse einen Kommentar

ZFS Ubuntu Root Installation

Heute mal was komplett Java-fremdes. Ich möchte für ein NAS Experiment ein Ubuntu 13.04 (raring ringtail) auf zwei gespiegelten Festplatten (je 2TB) auf einem ZFS Dateisystem laufen lassen. Das Linux, wie auch die Daten sollen dann per Snapshots vereinfacht gesichert werden.

Die folgende Anleitung bezieht sich auf das bekannte HowTo, was aber auf Ubuntu 12.04 basiert.

ACHTUNG: Die Einrichtung eines ZFS als Root gilt noch als experimentell. Man sieht das deutlich, wenn man die Grub2 Probleme mit raring sieht. Aber das System bootet mit dieser Anleitung komplett bis in das Login und ist damit als ZFS on Root nutzbar. Viel Spaß beim Ausprobieren.

Systemvoraussetzungen

  • 64-bit Ubuntu Live CD (13.04/raring). (Keinen Alternate Installer und nicht den 32-bit Installer! ZFS läuft nur unter 64Bit wirklich stabil)
  • AMD64 oder EM64T kompatible Computer. (z.B: x86-64). Das darf auch eine virtuelle Maschine sein, sofern sie mit dem Host 64Bit Gastsysteme erlaubt.
    • VMWare (Player reicht) oder VirtualBox neuester Version
  • 8GB Festplattenplatz, mindestens. Bis 2TB kann man für den ZFS Pool ashift=9 verwenden. Darüber ashift=12. Das führt aber wohl noch zu Problemen.
    • Unter VMware sind raw devices (d.h. richtige Festplatten, ausschließlich für die VM) sehr schnell. Wenn man sowas zur Verfügung hat, sollte man sie nutzen. Spart eine Menge Zeit, wenn man viel experimentieren will.
  • 2GB Arbeitsspeicher. Weniger Arbeitsspeicher ist nicht zu empfehlen. Insbesondere mit Deduplizierung (die ich abschalten werde) benötigt man sehr viel RAM. Deduplizierung kann man nachträglich nicht einfach deaktivieren. Man muss die Daten zwischen Pools hin und herkopieren.
    Bei nur einem Gigabyte RAM schlägt teilweise schon die Installation im chroot fehl (es muss kompiliert werden!) oder dauert so lange, dass es sich nicht lohnt.
  • Kann man es sich vom Host-System erlauben, dann aktiviert man am besten 2 CPU.

Getestete Versionen

  • Ubuntu 13.04 Raring Ringtail (raring)
  • spl-0.6.2 Poolversion: 5000 Filesystemversion: 5; Veröffentlicht: 23.8.2013
  • zfs-0.6.2 Poolversion: 5000 Filesystemversion: 5; Veröffentlicht: 27.5.2013

Hinweise für das Tutorial

  • $
    • Ubuntu-Terminal-User des Live-Systems
  • #
    • sudo-Root Terminal User (sudo -i)
  • ##
    • Terminal im chroot
  • $
    • Kennzeichnet am Ende der Zeile, dass es auf der nächsten Zeile ohne Umbruch weitergeht.

Schritt 1: Das System vorbereiten

1.1 Die Ubuntu-Live CD booten, in den Live-Modus umschalten (ggf. vorher die deutsche Sprache einstellen, wenn man ein deutsches Keyboard-Layout im Terminal bevorzugt). Wer die Unity-Oberfläche nicht kennt/hasst: Auf den Ubuntu-Button links klicken, Terminal eingeben, Enter.

1.2 Im Terminal dauerhaft nach sudo wechseln, zfs und debootstrap installieren

Das müssen wir aus einem PPA holen.

$ sudo -i
# apt-add-repository --yes ppa:zfs-native/stable
# apt-get update
# apt-get install debootstrap ubuntu-zfs

Das dürfte eine Weile dauern, je nach Online-Verbindung zum Repository, Festplattengeschwindigkeit, Arbeitsspeicher und CPU. Es wird nämlich kompiliert. Da kann man sich den ersten Kaffee gönnen.

1.3 Nun schauen, ob das ZFS Dateisystem läuft

# modprobe zfs
# dmesg | grep ZFS
ZFS: Loaded module v0.6.2-1~raring, ZFS pool version 5000, $
ZFS filesystem version 5

Schritt 2: Festplatten partitionieren

Es wird empfohlen eine Grub-MBR Installation durchzuführen. Zwar hat man damit eine extra Partition, kann aber bei Problemen mit dem Pool immer noch booten. In einer Mirror-Konfiguration bedeutet das natürlich mehr Arbeit. Alternativ kann man mit GPT booten, wird hier aber nicht beschrieben.

2.1 Mit dem bevorzugten Disk-Partitionierer die Festplatten einrichten. Nimmt parted oder cfdisk. Gparted ist nicht geeignet.

Es wird immer die /dev/disk/by-id/-Notation der Festplatten verwendet. Das verhindert ein paar Probleme beim Austausch von Platten, bei Hardwareproblemen. Das ZFS kann zwar Platten normalerweise selber identifizieren, aber das funktioniert nur unter Solaris sehr gut.

Hier wird eine mirror-Konfiguration beschrieben. Wir hantieren also mit zwei Festplatten und vier Partitionen.

/dev/disk/by-id/scsi-SATA_disk1
/dev/disk/by-id/scsi-SATA_disk1-part1
/dev/disk/by-id/scsi-SATA_disk1-part2
/dev/disk/by-id/scsi-SATA_disk2
/dev/disk/by-id/scsi-SATA_disk2-part1
/dev/disk/by-id/scsi-SATA_disk2-part2

Dabei ist scsi-SATA_disk(1|2) die UUID der Festplatte. Wer mit VMware (Player) spielt, muss UUID  für Disks aktivieren. Das geht beim Player nur mit dem Editieren der *.vmx-Datei. Einfach am Ende (im ausgeschalteten Zustand der VM)

disk.EnableUUID = "TRUE"

anfügen.

Die Partitionen -part1 und -part2 ist bei beiden Platten exakt gleich groß zu halten.

Auf -part1 kommt Grub und liegt am Anfang der Platten. Sie sollte zwischen 100MB und 256MB groß sein.

Auf -part2 kommt der Pool-mirror

2.2 /dev/disk/by-id/scsi-SATA_disk1-part1 wird 100MB groß und befindet sich am Anfang

2.3 Die Partition erhält das Flag bootable, Type = BE (Solaris Boot)

2.4 Nun den Rest der Platte (mindestens 4GB) mit der größeren Partition anlegen.

2.5 Die Partition ist nicht bootable und erhält als Type = BF (Solaris)

Exakt das gleiche wird mit der zweiten Festplatte gemacht. Den Partitionierer cfdisk muss man dafür mit dem Parameter /dev/sdb aufrufen.

Ruft man fdisk -l nach dem Partitionieren auf, erhält man (ungefähr) folgendes Ergebnis:

Trotz der Angaben mit /dev/sd(a|b)(1|2) wird im folgenden immer mit der by-id-Angabe gearbeitet. Ich empfehle dringend die [TAB] Taste zum vervollständigen zu nehmen.

Schritt 3: Die Partitionen formatieren

3.1 Die -part1 Partitionen für Grub auf beiden Disks vorbereiten.

# mke2fs -m 0 -L /boot/grub -j /dev/disk/by-id/scsi-SATA_disk1-part1
# mke2fs -m 0 -L /boot/grub -j /dev/disk/by-id/scsi-SATA_disk2-part1

3.2 Nun den Root-Zpool als mirror aus dem -part2 Partitionen einrichten:

# zpool create -o ashift=12 datpool mirror /dev/disk/by-id/scsi-SATA$
_disk1-part2 /dev/disk/by-id/scsi-SATA_disk2-part2

Das ashift sollte man mit Bedacht wählen. Es sollte zur Blockgröße der Festplatten passen und noch von Grub zu lesen sein. Grub2 kann inzwischen 4K Blöcke lesen. Es gibt aber unterschiedliche Performance-Ergebnisse, was ashift=9 (512Byte) und ashift=12 (4096Byte) betrifft. Dazu muss man sagen, dass 4K dazu führt, dass gerade die Metadaten einen großen Overhead haben. Das System wird weniger Daten speichern können, wenn man viele kleine Dateien hat.

Schwierig ist, dass zwar auch große Festplatten 512 Byte Blöcke vortäuschen (fdisk wird nichts anderes sehen), aber tatsächlich 4K schreiben/lesen. Da ist es je nach Hersteller sogar unterschiedlich, ob ashift=9 oder ashift=12 schneller ist. Keine Gedanken muss man sich machen, wenn man virtuelle Drives (für eine VM) zum Testen erzeugt. Die sind an sich schon sehr langsam. Auch wird ein Pool deutlich langsamer, wenn man über 80% belegt hat.

Letztendlich muss man es ausprobieren, besonders wenn man ein produktives System vorbereitet. Da lohnt es sich schon eine Installation zwei mal durchzuführen, wenn man dadurch später ein schnelleres System hat.

In vielen Tutorials wird für den Poolnamen “rpool” oder “tank” verwendet. Seit kreativer, damit es zu keinen Verwechslungen kommt. Besonders, wenn man mal andere Pools importiert, können gleiche Namen zu großen Problemen führen. Ich verwende hier den Namen datpool (auch nicht kreativ).

Da wir zwei Grub-Partitionen auf zwei Platten verteilt haben, muss nachher die Installation auf der zweiten Platte angepasst werden. Ansonsten wird beim Ausfall der disk1 die disk2 nicht booten, da Grub das Root-System auf der ausgefallenen Platte sucht. Dazu komme ich aber noch später.

3.2.1 Deduplikation abschalten

Bei kleinen Systemen mit begrenztem Arbeitsspeicher sollte man unbedingt die Deduplikation abschalten. Das gleich auf Pool-Ebene, damit kein Dateisystem damit angelegt wird.

# zfs set dedup=off datpool

3.3 Das ROOT Dateisystem in dem Pool anlegen

# zfs create datpool/ROOT

3.4 Für das Ubuntu-System ein Unterfilesystem anlegen. Für extra home- und Datenpartitionen werden weitere Dateisysteme unter datpool/ROOT angelegt. Damit kann man getrennte Snapshots durchführen. Das ist aber Basis des zweiten Tutorials und wird hier nicht behandelt. Ich verweise da gerne in der Zwischenzeit auf ein anderes Tutorial.

# zfs create datpool/ROOT/ubuntu-1

3.5 Die erzeugten Dateisysteme werden nun erst mal ausgeworfen

# zfs umount -a

3.6 Den Mountpoint für das Root-Dateisystem setzen (sehr wichtig!)

# zfs set mountpoint=/ datpool/ROOT/ubuntu-1

3.7 Die bootfs Eigenschaft im Pool setzen (auch sehr wichtig!)

# zpool set bootfs=datpool/ROOT/ubuntu-1 datpool

Der Bootloader benötigt unbedingt* diese beiden Eigenschaften, ansonsten kann Ubuntu nicht automatisch gebootet werden. Man kann diese Eigenschaften auch in der Grub-Shell eingeben (rpool=datpool, bootfs=datpool/ROOT/ubuntu-1). Das würde die ZFS-Eigenschaften überschreiben. Wie Grub2 funktioniert, erklärt dieses Tutorial.

*) Wir werden feststellen, dass Grub2 einen Bug hat und das “unbedingt” nur bedingt gilt. Trotzdem die Eigenschaften setzen. Wenn Grub2-zfs3 korrigiert ist, sind diese Properties wieder notwendig.

3.9 Pool exportieren

# zpool export datpool

Das muss klappen, ohne die -f Option (force). Ansonsten hat der Pool schon jetzt einen inkonsistenten Status. Ggf. sind Eigenschaften noch nicht geschrieben oder es gibt andere Probleme.

Schritt 4: System installieren

4.1 Pool importieren

# zpool import -d /dev/disk/by-id -R /mnt datpool

Man muss keine Festplatten angeben. zpool sucht mit dem Pool-Namen die passenden Partitionen der verfügbaren Festplatten heraus und importiert diese. Der Befehl zpool list zeigt dann die importierten Pools.

4.2 Grub-Partition mounten

# mkdir -p /mnt/boot/grub
# mount /dev/disk/by-id/scsi-SATA_disk1-part1 /mnt/boot/grub

4.3 Nun das Minimalsystem installieren

# debootstrap raring /mnt

Das debootstrap Kommando hinterlässt ein komplett unkonfiguriertes System. In Schritt 5 wird dieses System gerade mal zum Booten eingerichtet. Auch dieses Installieren dauert je nach Bandbreite und Maschinen-Geschwindigkeit etwas. Es wird nicht kompiliert, aber für eine halbe Tasse Kaffee reicht es.

Schritt 5: Systemkonfiguration

5.1 Die Dateien hostname und hosts aus dem Live-System kopieren

# cp /etc/hostname /mnt/etc/
# cp /etc/hosts /mnt/etc/

5.2 fstab für die Grub-Partition vorbereiten

fstab sollte, bis auf eine Kommentarzeile, leer sein. Die direkt zu editieren ist aufwändig, wegen der langen UUID-Namen. Also wird die notwendige Zeile per echo angefügt.

# echo '/dev/disk/by-id/scsi-SATA_disk1-part1  /boot/grub  auto $
defaults  0  1' >> /mnt/etc/fstab

Die Partition per [TAB]-vervollständigen einfügen.

Das Mounten der Grub-Partition ist im Prinzip optional, wenn das System funktioniert. Wir brauchen aber nach den Zugriff auf die grub.cfg, damit wir einen Fehler des Grub2 Bootloaders mit ZFS-Unterstützung umgehen können. Zudem sieht man, dass das sowieso nur funktioniert, wenn Platte 1 aus dem Mirror läuft.

Die weiteren dev, proc, sys oder tmp Zeilen lassen wir weg. Das ist redundant, wenn /lib/init/fstab existiert.

5.3 Die interfaces Datei sollte noch erweitert werden, damit nach dem Booten ein Netzwerk gefunden wird. In einer VM ist es einfach per DHCP sich zu verbinden. Bei anderen Konfigurationen, die Datei anders füllen.

Zu finden unter /mnt/etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

5.4 Für eine chroot Umgebung werden nun einige virtuelle Dateisysteme des Live-Systems eingebunden. Die Option –bind ist da zwingend notwendig.

# mount --bind /dev  /mnt/dev
# mount --bind /proc /mnt/proc
# mount --bind /sys  /mnt/sys

Nun an dem chroot-System anmelden:

# chroot /mnt /bin/bash --login

Alle Kommandos im chroot werden nun mit dem Präfix ## gekennzeichnet.

5.5 PPA-Unterstützung und Sprachdateien für en_US installieren

## locale-gen en_US.UTF-8
## apt-get update
## apt-get install ubuntu-minimal software-properties-common

Das US-amerikanische Locale muss existieren, ansonsten wird man mit Warnungen überhäuft*. Damit ZfsOnLinux läuft, wird ubuntu-minimal benötigt.

*) Ich hatte die Warnungen trotzdem, da muss noch was nachkonfiguriert werden. Muss ich noch prüfen. Am Installationserfolg ändert das nichts.

5.6 ZFS in der chroot Umgebung installieren

Im Live-System hatten wir es schon installiert (ansonsten hätten wir keinen Pool und Dateisysteme anlegen können), trotzdem benötigen wir ZFS natürlich auch auf unserem neuen System.

## apt-add-repository --yes ppa:zfs-native/stable
## apt-add-repository --yes ppa:zfs-native/grub
## apt-get update
## apt-get install --no-install-recommends linux-image-generic $
linux-headers-generic
## apt-get install ubuntu-zfs
## apt-get install grub2-common grub-pc
## apt-get install zfs-initramfs
## apt-get dist-upgrade

Der Download von linux-image-* wird ein Weilchen dauern. Da kann man die halbe Tasse Kaffee zu Ende trinken, bevor er kalt wird.

Die SPL- und ZFS-Module werden kompiliert. Das dauert auch. Auf keinen Fall die Sache abkürzen und was aus der LiveCD-Umgebung kopieren. Das wird vermutlich nicht funktionieren. Lieber noch eine Tasse Kaffee besorgen und dem System bei der Arbeit zuschauen.

Mit der Aktion werden gepatchte mountall und dkms-Packages installiert. Diese müssen unbedingt aus dem obigen PPA kommen. Ansonsten wird nachher nichts booten!

Mit dem grub-pc Paket wird ein Dialog kommen, der nach den Installationsort des MBR nachfragt. Bei der Mirrorkonfiguration zeigt der Dialog ungewöhnlicherweise nur sda, sdb, sdb1 und den Pool an. Wie auch immer, es ist die Disk1 (/dev/sda) zu wählen. Nicht eine Partition! Später installieren wir sowieso manuell.

Zudem erscheinen eine Menge Warnungen, weil Schreiboperationen fehlschlagen, oder Partitonstabellen nicht ausgelesen werden können. Ignorieren. Das liegt an der chroot-Umgebung.

5.7 Kennwort für root festlegen (Sehr sehr wichtig!)

## passwd root

Ohne dieser finalen Einrichtung, steht man beim reboot wie ein Ochs vor dem Scheunentor.

Schritt 6: Grub installieren

Bitte daran denken, wir sind immer noch in der chroot-Umgebung!

6.1 Überprüfen, ob das ZFS Root-Dateisystem von Grub erkannt wird

## grub-probe /
zfs

Sind die Module installiert?

## ls /boot/grub/i386-pc/zfs*
/boot/grub/i386-pc/zfs.mod  /boot/grub/i386-pc/zfsinfo.mod

(evt. wird mehr angezeigt, z.B. zfscrypt.mod, weniger hoffentlich nicht)

6.2 Nun die initrd Dateien aktualisieren

## update-initramfs -c -k all
update-initramfs: Generating /boot/initrd.img-3.8.0-19-generic

6.3 Die Boot-Konfiguration erzeugen

## update-grub
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.8.0-19-generic
Found initrd image: /boot/initrd.img-3.8.0-19-generic
done

Das glauben wir nur, wenn wir es sehen:

## grep boot=zfs /boot/grub/grub.cfg
linux /ROOT/ubuntu-1@/boot/vmlinuz-3.8.0-19-generic root=ZFS=$
datpool/ROOT/ubuntu-1 ro boot=zfs $bootfs quiet splash $vt_handoff
linux /ROOT/ubuntu-1@/boot/vmlinuz-3.8.0-19-generic root=ZFS=$
datpool/ROOT/ubuntu-1 ro single nomodeset boot=zfs $bootfs 

Unter raring sind es drei Einträge, der erste Eintrag ist aber der entscheidende.

Es dürfte nicht passieren, aber in älteren SPL/ZFS Paketen (für raring) gibt es ein Bug, der den linux und initrd-Eintrag falsch anlegt (Verdopplungen einzelner Pfadangaben) . Dann muss man händisch an die Sache ran und korrigieren (siehe auch https://github.com/zfsonlinux/zfs/issues/1441).

Ein aktueller Bug verhindert trotzdem das Booten. Das korrigieren wir aber in Schritt 8, nicht schon jetzt. Wenn der Bug weg ist, bleibt die Anleitung wie jetzt, nur ohne Schritt 8.

Wenn nun in der grub.cfg bei root tatsächlich /dev/sda2 stehen hat, muss man (für unsere Mirror-Konfiguration) die Konfigurationsdatei später manuell editieren, bevor man grub-install auf sdb2 durchführt. Steht da der korrekte Pool, ist das nicht notwendig. Auf der gespiegelten Platte wird der Pool anhand des Namens gefunden.

6.4 Nun den Groub-Bootloader in den MBR Bereich beider Festplatten installieren

6.4.1 Auf Disk1

## grub-install $(readlink -f /dev/disk/by-id/scsi-SATA_disk1)

6.4.1 Auf Disk2

Ggf. vorher die grub.cfg bearbeiten, wenn dort sda drin steht (muss dann sdb sein) und das update-grub nicht vergessen!

## grub-install $(readlink -f /dev/disk/by-id/scsi-SATA_disk2)

Da ich nicht weiß, ob Grub inzwischen Symlinks auflösen kann, empfehle ich die readlink-Variante, die funktioniert garantiert.

Jetzt befinden sich zwei Grub-Loader auf beiden Festplatten, die hoffentlich das System booten. Egal welche Platte ausfällt.

Ganz wichtig ist, dass die Meldung erscheint:

Installation finished. No error reported.

Ansonsten hat ein Reboot keinen Sinn.

Schritt 7: Aufräumen und der erste Reboot

7.1 Zunächst die chroot Umgebung verlassen

## exit
logout

7.2 Die LiveCD Umgebung aushängen

# umount /mnt/boot/grub
# umount /mnt/dev
# umount /mnt/proc
# umount /mnt/sys

Auch das ZFS Dateisystem und den Pool aushängen

# zfs umount -a
# zpool export datpool

Und wieder: zpool export darf keinen Fehler melden und zur Option -f (force) auffordern. Sonst könnte der Pool inkonsistent sein.

7.3 Das ist es gewesen

Terminal schließen, Live-System sauber herunterfahren. CD entnehmen (oder aus der VM die iso-Datei austragen)! Dann das System wieder starten.

Es erscheint ein einfaches Grub-Menü mit zwei Einträgen. Den ersten wählen. Danach ist man im Login. Username ist root und Kennwort, das oben gewählte. Hoffentlich wurde das nicht vergessen ;-)

Sollte man nicht zum Login vordringen, ist im Grub2 für ZFS noch ein Bug. Das umgehen wir nun mit Schritt 8. Ansonsten: Herzlichen Glückwunsch. Geschafft! Am Ende weiterlesen, um zu sehen wie es weiter geht.

Schritt 8: Grub2 auf die Sprünge helfen

Leider funktioniert ein Booten erstmal nicht! Aber das reparieren wir jetzt:

Folgende Fehler kommen beim Booten:

Dann:

Man sieht, dass ein rpool angefordert wird. Schaut man in die Menu-Konfiguration, scheint es aber zu stimmen. Auch ein set in der Grub-Shell zeigt eine korrekte Konfiguration. Aber Grub versteht die übergebenen Parameter nicht. Da hat sich ein Bug in dem aktuellen Stable eingeschlichen (siehe Diskussion zum Issue #1441).

8.1 Manuell den Pool und das Dateisystem importieren und mounten

Man muss nun den Pool manuell importieren, soweit das nicht schon passierte (zpool list zeigt es an):


zpool import -d /dev/disk/by-id -f -N datpool

Danach muss man manuell mounten:


mount -t zfs -o zfsutil datpool/ROOT/ubuntu-1 /root

Jetzt drei(sic!) mal exit eingeben und das System bootet in das Login:

8.2 Grub Konfiguration anpassen

Jetzt muss man ein Workaround verwenden, damit Grub2 die Parameter für den Pool und den Mountpoint des Filesystems versteht. Im Prinzip setzen wir die (alten) Parameter manuell, die Grub2 eigentlich über neue Parameternamen ermitteln sollte.

Da die Installation extrem minimal ist, muss man ggf. einen Editor seiner Wahl installieren (ich nutze gerne nano, jaja nicht lachen).

Die Datei /etc/default/grub öffnen.

Nach der Option GRUB_CMDLINE_LINUX_DEFAULT suchen und am Anfang der Optionen folgendes hinzufügen: rpool=datpool bootfs=datpool/ROOT/ubuntu-1

Damit sieht es ungefähr so aus (in einer Zeile!):

GRUB_CMDLINE_LINUX_DEFAULT="rpool=datpool $
bootfs=datpool/ROOT/ubuntu-1 ..."

Die drei Punkte stehen für die bereits existierenden Optionen, die man nicht entfernen sollte. Speichern.

8.3 Auf der Konsole ein Grub Update ausführen:

# update-grub

Eigentlich sollte ein grub-install nicht notwendig sein, habe ich aber zu Sicherheit auch noch gemacht. Siehe dafür Punkt 6.4ff

Dann reboot und es klappt! Leider bleibt der Label-Fehler und verzögert das Booten um einige Sekunden, aber dann ist man im Login.

Das ist erstmal schon nicht schlecht.

Abschluss

Das Ubuntu-System ist absolut minmal eingerichtet. Für die Einrichtung eines NAS-System kommt ein weiteres Tutorial. Bis dahin empfehle ich Konfigurationen nach diesen Tutorials (die entweder kein Root-ZFS haben oder eine andere Distri nutzen):

http://d24m.de/2011/05/03/howto-freebian-debian-auf-zfs-installieren/

http://blog.themilkyway.org/2013/05/how-to-setup-a-nas-using-debian-7-0-wheezy-with-zfs-and-smb-and-nfs-share/

Weiterhin empfehle ich für alle, die bei ZFS an Wunder glauben, diesen Artikel:

http://nex7.blogspot.de/2013/03/readme1st.html#!

Für Performance Tipps:

https://calomel.org/zfs_raid_speed_capacity.html

Veröffentlicht unter Dateisysteme, Linux, ZFS | Verschlagwortet mit , , , , | Hinterlasse einen Kommentar

Build offline with maven

Sometimes I work at home and sometimes I’ve no VPN connection to my company. Sometimes I sit in a hotel without any internet connection. But I want to compile my projects with maven.

The first step is to set the –offline flag in my NetBeans Maven settings. This works fine with my local .m2 repository. But.

But for few (only in my company hosted) artifacts I get a really bad error message:

The POM for (artifact name) is missing, no dependency information available

This message sucks a lot. The named artifact *is* available in my local repository. After investigating some hours with searching the web, I found this interesting JIRA issue: Improve “missing dependency” error message when _maven.repositories/_remote.repositories contains other repository ids than requested. Ok, improving the error message is a good idea, but a better idea is (for this case) to remove the _maven.repositories file. The file contains a pointer to my company repository (only available via VPN) and maven3 use this pointer to resolve the pom file (and ignores the –offline flag).

After removing this file, anything works fine. I can build my NetBeans platform projects without any internet connection.

Veröffentlicht unter Maven, NetBeans, NetBeans Plattform | Verschlagwortet mit , , | Hinterlasse einen Kommentar

Mavenization of NetBeans Platform projects (7.x releases)

Currently I’m testing some bugs in the NetBeans development build (localisation bugs). But for some issues it’s not enough to have the platform sources and a build. To test maven-driven platform apps, I need all updated artifacts in my local repository.

This tutorial is updated from an old tutorial by Chas Emerick. You can find his version here. I’ve copied anything and changed the steps to the current versions.

  1. Pull the NetBeans Platform sources from the associated hg repo (I used the development repo). It appears that populating your repo with NB RCP artifacts from a binary download is possible, but then you’ll not have the associated javadoc, source artifacts, etc. (see https://netbeans.org/community/sources/hg.html)
    1. First time
      1. hg clone http://hg.netbeans.org/main-silver
    2. Update
      1. hg pull
      2. hg update
  2. Build the entire project – It’s possible to restrict the build to certain clusters, but I don’t see any reason to optimize this process since doing so only saves a little bit of disk (and time).
    1. You must set your JAVA_HOME environment variable and should point to a Oracle JDK, especially in linux environments that often come with non-Oracle JDKs. Not doing this can result in very strange compilation errors.
    2. You must set your ANT_HOME environment variable (please use a version equal or higher than 1.9)
    3. You must set your ANT_OPTS environment variable to specify a higher-than-default maximum heap (export ANT_OPTS=-Xmx1024m worked for me).
      1. Best results with:
        1. -Xmx1024m
          -XX:+CMSClassUnloadingEnabled
          -XX:MaxPermSize=512m
    4. Within the top-level of your NetBeans Platform source checkout, run
      1. ant
      2. ant build-nbms
      3. ant build-source-zips
      4. ant build-javadoc
        This will build everything you care about in order to populate your maven repo.
  3. You want to have the NBMs in your repository to have appropriate dependency relationships established with third-party artifacts, right?
    1. Downloading via nb-repository-plugin
      1. mvn org.codehaus.mojo:nb-repository-plugin:1.1:download
        -DnexusIndexDirectory=/tmp/nexus-index
        -DrepositoryUrl=
        http://repo1.maven.org/maven2
    2. or achieving this is easy if you have nexus
      1. unzip sonatype-work/nexus/storage/central/.index/nexus-maven-repository-index.zip somewhere (I used /tmp/nexus-index).
    3. Or use the NetBeans cache folder (the content is unzipped!)
      1. Under Windows: e.g.
        %HOMEPATH%\AppData\Local\NetBeans\Cache\dev\mavenindex\central
    4. set the nexusIndexDirectory property in the last step to that the path where you unzipped central’s index; the nbm-maven-plugin will search that Lucene index to find dependencies referred to within the Platform’s NBMs
  4. set MAVEN_OPTS to specify a higher-than-default maximum heap
    1. MAVEN_OPTS=-Xmx512m
      I’m not sure why this would be required, but I got OutOfMemoryErrors with max heap set to anything less than 512MB. Perhaps searching the maven central repo index is what pushed allocation so high.
  5. Make sure you don’t have a pom.xml in your current directory. Bad things will happen.
  6. Decide on a version number for the deployed artifacts, and use it as the value of the forcedVersion property. I used RELEASE731-patched to go along with the pattern established at http://bits.netbeans.org/maven2
  7. Assuming you’re deploying to a (nexus) release repository, make absolutely sure that you’ve (temporarily) enabled redeployment for that repository! nbm-maven-plugin deploys some NBMs multiple times (presumably while traversing various dependency graphs), and not enabling redeployment will result in errors (400 errors from Nexus, specifically – I can’t say what might happen with different repository managers).
  8. Now for the big finish (please set the correct index-folder from step 3):
    1. Deploying to a repository (e.g. nexus)
      1. mvn org.codehaus.mojo:nb-repository-plugin:1.1:populate
        -DforcedVersion=RELEASE731-patched
        -DnetbeansInstallDirectory=nbbuild/netbeans
        -DnetbeansSourcesDirectory=nbbuild/build/source-zips
        -DnexusIndexDirectory=/tmp/nexus-index
        -DnetbeansJavadocDirectory=nbbuild/build/javadoc
        -DnetbeansNbmDirectory=nbbuild/nbms
        -DdeployUrl=<nexus_repo_url>
        -DskipLocalInstall=true
    2. or deploying local for tests
      1. mvn org.codehaus.mojo:nb-repository-plugin:1.1:populate
        -DforcedVersion=RELEASE731-patched
        -DnetbeansInstallDirectory=nbbuild/netbeans
        -DnetbeansSourcesDirectory=nbbuild/build/source-zips
        -DnexusIndexDirectory=/tmp/nexus-index
        -DnetbeansJavadocDirectory=nbbuild/build/javadoc
        -DnetbeansNbmDirectory=nbbuild/nbms



All this steps together needs two or more hours, depending on your machine and finished old builds.

Veröffentlicht unter Maven, NetBeans, NetBeans Plattform | Hinterlasse einen Kommentar

Lookup und Swing-Tricks: Wie ich Events zu Lookup-Changes bekomme

Ich melde mich mal mit einer Kleinigkeit zurück.

Der Kunde wünscht sich bei der Auswahl von Nodes auch die Modifier der Tastatur zu ermitteln. Üblicherweise ist das gar nicht möglich, wenn man nur mit Lookup-Listener auf Results arbeitet (was ja die Regel sein sollte).

Da Swing ja singlethreaded ist und die meisten Lookup-Benachrichtigungen sich auch daran halten (außer man erzwingt Mutlithreading – was böse ist), kann man einfach über das AWT das aktuelle Event ermitteln:


AWTEvent currentEvent = EventQueue.getCurrentEvent();

Da AWTEvent recht schmalbrüstig ist, müssen wir es noch casten. Beispiel:


if ( currentEvent instanceof InputEvent ) {
  mods = ((InputEvent)currentEvent).getModifiers();
}

Ist kein aktuelles Event vorhanden, wird null zurückgegeben, was mit instanceof ohne NPE abgefangen wird. Dann erhalten wir aber auch keine Modifier.

Veröffentlicht unter Java, NetBeans Plattform | Verschlagwortet mit , , | Hinterlasse einen Kommentar

JavaFX 2 Multiplatform in einer NetBeans Platform App

Da auch JavaFX 2 mit einem eigenen Native-Loader kommt, haben wir in einer NetBeans Platform wieder das Problem, die DLL/SO/… Bibliotheken an die richtige Stelle zu bekommen.

Man kann natürlich den Anwender JavaFX installieren und bin-Pfade einrichten lassen. Aber bequemer ist es natürlich, wenn sich die Platform Application darum kümmert.

Hier eine extrem simple (und nicht für alle Plattformen gültige) Lösung.

Es wird davon ausgegangen, dass sich die javafx-2.0.jar in dem Ordner cluster/modules/ext/somename befindet. Cluster ist der suite-Name. Der Pfad modules/ext ist Standard für externe Bibliotheken und somename ist (ggf.) ein Codename-Base-Name der externen Bibliothek oder “lib” (das ist JavaFX aber egal). Ich habe z.B. com.oracle verwendet (die aus der Gruppen-ID meiner Maven-Artifakte kommt).

Will ich nun (nur) Windows in 32bit und 64bit unterstützen, lege ich in dem ext-Order noch bin und darunter amd63 und x86 an. Also: cluster/modules/ext/bin/amd64 und cluster/modules/ext/bin/x86. Der Native Loader von JavaFX sucht immer (von der javafx-2.0.jar) in ../bin. Ich muss also nun die DLL’s kopieren.

Hier ein Beispiel meiner Dateistrukturen:

Da JavaFX fast mit Java7 verheiratet ist, werde ich auch nur mit Java7-nio den Weg beschreiten:


public class Installer extends ModuleInstall {

  @Override
  public void restored() {
    Class c = Installer.class;
    URL u = c.getProtectionDomain().getCodeSource().getLocation();
    String path = u.getPath();
    if ( path.startsWith("file:/") && path.endsWith(".jar!/")) {
      path = path.substring(6);
      path = path.substring(0, path.length()-2);
      int pos = path.lastIndexOf("/");
      if ( pos >= 0 ) {
        path = path.substring(0, pos);
        FileSystem fs = FileSystems.getDefault();
        Path dest = fs.getPath(path, "ext", "bin");
        Path source = fs.getPath(path, "ext", "bin", System.getProperty("os.arch"));
        try {
          for (Path toCopy : Files.newDirectoryStream(source)) {
            Path destFile = fs.getPath(dest.toString(), toCopy.getFileName().toString());
            Files.copy(toCopy, destFile, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
          }
        } catch (IOException ex) {
          Exceptions.printStackTrace(ex);
        }
      }
    }
  }
}

Am aufwendigsten ist die Ermittlung des Modulpfades per URL u = c.getProtectionDomain().getCodeSource().getLocation(); mit dem Extrahieren des eigentlichen Pfades (man sieht, WebStart wird nicht unterstützt). Den Path “source” ermittle ich ausschließlich über os.arch. Das ist natürlich nicht wirklich nützlich für Plattformen wie Linux. Wer weitere Plattformen unterstützen will, sollte noch zusätzliche Systemparameter ermitteln und weitere Unterordner anlegen. Ich würde aber explizit die Methoden aus org.openide.util.Utilities (isMac, isUnix, isWindows) verwenden. Die System Properties sind da zu geschwätzig.

Nehmen wir an, es würde alles fehl schlagen (weil wir Bibliotheken nicht mitliefern), dann sollte man noch eine eigene Hilfsklasse basteln, die den erfolgreichen (oder nicht erfolgreichen) Kopiervorgang an andere Module liefern kann (z.B. JavaFXHelper.isJavaFXAvailable()). Wenn man das nämlich nicht abprüft und doch JavaFX verwendet, sind die Abstürze so hart, dass häufig nicht mal das Hauptfenster angezeigt wird. Im Log findet ihr dann Fehler wie: java.lang.UnsatisfiedLinkError: Can’t load library: …

Was allerdings schön ist: mehr ist nicht zu machen. Man muss nicht (wie in einem alten Artikel von mir beschrieben) eine Startup-Klasse der Platform unterschieben, um JavaFX zu nutzen.

Einen Mini-WebBrowser fügt man so in eine TopComponent ein:


    final JFXPanel fxPanel = new JFXPanel();

    add(fxPanel);
   
    Platform.runLater(new Runnable() {

      @Override
      public void run() {
        Group group = new Group();
        Scene scene = new Scene(group);
        fxPanel.setScene(scene);
       
        view = new WebView();
        view.setMinSize(1024, 768);
        view.setPrefSize(1024, 768);
        group.getChildren().add (view);
      }
    });

view ist eine Feldvariable der TopComponent. Mit der Methode:


  public void browseTo (final String url) {
    Platform.runLater(new Runnable() {
      @Override
      public void run() {
        view.getEngine().load(url);
      }
    });
  }

kann man eine Webseite öffnen (http:// muss aber am Anfang der URL stehen).

Viel Spaß mit JavaFX in der NetBeans Platform.

Veröffentlicht unter JavaFX, NetBeans Plattform | 4 Kommentare

NetBeans Release 7.1.1 ist da

Seit kurzer Zeit ist ein neues Release von NetBeans fertig und kann hier heruntergeladen werden.

Die Version 7.1.1 bring kleinere Neuerungen:

  • Java ME SDK 3.0.5 Unterstützung
  • Bundle GlassFish 3.1.2 Update
  • JavaFX 2.0.3 SDK Unterstützung
  • Maven 3.0.4 Upgrade

Dazu wurden 123 Fehler berichtigt, die noch in 7.1 waren oder bis 7.1.1 entdeckt wurden. Hier eine Liste der P1 Fehler:

All [71cat] ArrayIndexOutOfBoundsException: -72
All Closing editor clone not handled correctly;
editor TC out of sync with disk file
All [regression] Use of FindUsages modifies all
documents with references
Wind Applications not using OSGi don’t start on NbP 7.1
Linu Can’t deploy to remote GlassFish 3.1.1 server
Wind Mercurial gives getaddrinfo failed
Wind Insufficient CSS parser error recovery
All [71cat] Scanning projects never ends
All Add friend dependency for Java ME
Wind Find Occurences (Alt+F7) tries wrongly to modify the file
Mac Evaluate org.openide.awt
.ActionsTest.testTooltipsContainAccelerator
failure on Mac
All ScriptingCreateFromTemplateTest
.testCreateFromTemplateEncodingProperty failure
Wind ME 3.0.5 emulator never starts on Win 7 64bit
All Failing test org.netbeans.modules.apisupport.project.
NbModuleProviderImplTest.testGetDependencyVersion
Wind Failing tests in release71_fixes branch
Wind REST sample cannot be deployed to GlassFish 3.1.2.
Veröffentlicht unter NetBeans IDE | Verschlagwortet mit , | Hinterlasse einen Kommentar

Die wichtigsten Tastatur-Tricks in der NetBeans IDE

Es gibt ein paar kleine Tricks, um mit der IDE etwas schneller arbeiten zu können. Die folgende Liste ist bei weitem nicht vollständig, sondern beschreibt nur die Shortcuts, die ich gerne nutze (auch die Verwendung von einigen Assistenten).

Zwischenablage / Clipboard

Mehr durch Zufall bekommt man mit, dass Strg+C / Ctrl-C die komplette Zeile in die Zwischenablage kopiert, wenn man kein Zeichen selektiert. Das ist sehr praktisch, weil man sich die Tastenkürzel für das Markieren einer kompletten Zeile ersparen kann.

Strg-V / Ctrl-V fügt die Zwischenablage ein. Aber mit der Umschalt/Shift Taste wird der importierte Quelltext noch zugleich formatiert. Umschalt+Strg+V ist damit meine häufigst verwendete Tastaturkombination.

Löschen

Strg+E löscht eine komplette Zeile, ohne sie markieren zu müssen.

Auskommentieren

Schnell muss mal eine Zeile raus aus den Programmablauf, löschen will man sie aber nicht. Toggle Comment [Strg+Umschalt+C] hilft hier, um selektierte Zeilen schnell auszukommentieren oder die Kommentare wieder zu entfernen.

Zeilen bewegen / duplizieren

Mit den Pfeil/Cursor Tasten und Alt+Umschalt / Alt-Shift, kann man die aktuelle Zeile oder die markierten Zeilen nach oben oder unten verschieben, bzw. ein- oder ausrücken.

Sehr praktisch ist auch das Kopieren der aktuellen Zeile (oder der markierten Zeilen). Pfeil / Cursor auf und ab mit Strg+Umschalt / Ctrl+Shift erzeugt eine Kopie über oder unter dem Original. Dabei wird die Zwischenablage / Clipboard nicht verändert.

So kann man z.B. relativ schnell Felder in Klassen duplizieren, um dann nur den Namen zu ändern.

Actions für “Java-Zeile beenden”

Das sind Shortcut-Actions, die auf deutschen Tastaturen nicht funktionieren. Bevor man diese Funktionen nutzen kann, muss man diese in den Options neu zuweisen. Dazu geht man in die Optionen (Tools -> Options), dort auf die Keymap. Im Suchfeld gibt man “Complete Line” ein. Man bekommt zwei Editor Actions die auf Ctrl+SEMICOLON und Ctrl+Shift+SEMICOLON hören. Die eine Action (Complete Line) wird auf ALT+COMMA geändert, die andere (Complete Line and Create New Line) auf Ctrl-Alt-COMMA.

Complete Line in NetBeansJetzt kann man mitten im Bearbeiten der Zeile die Shortcuts eingeben. Die IDE fügt dann ein ; an das Ende der Zeile an und fügt (auf Wunsch) eine neue Zeile ein.

Rechteckige Selektion im Editor

Die Texteditoren haben neuerdings zu der klassischen Zeichen/Zeilen-Selektion nun eine rechteckige Selektion. Die kann man mit Strg+Umschalt+R aktivieren und deaktivieren. Man kann dann mit der Maus oder Umschalt+Pfeiltaste einen rechteckigen Bereich markieren. Das Besondere ist nicht das Kopieren des Bereiches, sondern die Eingabe von neuen Daten in den Bereich. Jede Zeile aus dem rechteckigen bereich erhält die neue Eingabe. Somit kann man z.B. sehr schnell einen Bereich von public Feldern in private ändern.

public int a;
public String b;
public double c;

Rectangular Selection ManipulationNun mit Strg+Umschalt+R den Selektionsmodus auf Rechteckig ändern und alle drei public’s selektieren. Dann einfach private eingeben. Alle drei Felddeklarationen haben nun private als Modifier. Es ist zu empfehlen die Selektion nach solchen Operationen wieder zurückzusetzen.

Alles hybsch machen

Mit Strg+Umschalt+F wird der selektierte Bereich (oder alles, wenn keine Markierung existiert) neu durchformatiert.

Quelltextvervollständigung / Codecompletion

Import Statements aufräumen und ergänzen

Die Tastenkombination Strg+Umschalt+I wirft ungenutzte Imports raus, löst *-Imports auf und fügt fehlende Imports hinzu. Wenn Klassennamen doppelt existieren, dann muss man die passenden Klassen in einem Dialog bestätigen. Man braucht die Kombination seltener, seit dem Strg+V und Strg+Umschalt+V automatisch die Imports mit übertragen. Aber manchmal braucht man es doch noch.

Methoden überschreiben

Man kann den Alt-Einf / Alt-Insert Assistenten verwenden, oder direkt den Namen der zu überschreibenden Methode eingeben und dann Strg+Leertaste / Ctrl-SPACE drücken (natürlich im Body der Klasse). Es wird dann vorgeschlagen, eine Methode aus der Liste zum Überschreiben auszuwählen. Mit Enter bestätigen, erzeugt die Methode mit dem super-Aufruf der überschriebenen Methode.

Variablenzuweisungen von der IDE

Ma sollte möglichst nicht mit einer VAriablenzuweisung beginnen, sondern erst den Methodenaufruf  schreibe. Beispiel:

getDimension();

Man bleibt mit dem Eingabecursor hinter den Semikolon. Die IDE wird schon jetzt eine gelbe Lanpe (Hint) bei der Zeilennummer einblenden. Nicht mit der Maus anklicken (dauert zu lange), einfach Alt+Enter. Es erscheint idR. nur ein Hinweis: Einen Rückgabewert einer neuen Variable zuordnen. Einfach mit Enter bestätigen und die IDE erzeugt:

Dimension dimension = getDimension();

Dazu den passenden Import. Außerdem ist der Variablenname dimension markiert, so dass man ihn ggf. überschreiben kann.

POJOs erzeugen

Ein sehr einfacher Weg, um Plain Old Java Objects zu erzeugen, ist wieder per Assistent. Erstmal eine Klasse anlegen. Im Body der Klasse nur Alt+Einfügen / Alt+Insert tippen.

In der Auswahlbox “Add Property” auswählen. Der Assistent erlaubt nun neben den Namen und Typ auch weitere nützliche Optionen zu aktivieren. Insbesondere “Bound” erleichtert viel Arbeit, weil damit das PropertyChangeSupport für die set’er Methoden erzeugt wird.

Nie wieder muss man diesen Boilerplate Code schreiben:

/**
 * Set the value of name
 *
 * @param name new value of name
 */
public void setName(String name) {
   String oldName = this.name;
   this.name = name;
   propertyChangeSupport.firePropertyChange(PROP_NAME, oldName, name);
}

Nun kann man mit den Klassen erstmal arbeiten. Wenn man später die Architektur etwas aufmöbeln will, kann man aus der Klasse ein Interface extrahieren (Im Kontextmenü: Refactor -> Extract Interface).

Navigation

Hyperlinks für Klassen, Methoden und Felder

Hyperlink Navigation in NetBeansStrg-Taste / CTRL  halten und mit dem Mauszeiger über einen Namen (Methode, Feld, Klassenname) gehen. Es erscheint ein Hyperlink. Ein Klick darauf und man springt zur Deklaration (öffnet dabei ggf. einen neuen Editor).

Aktuelle Editor-Datei im Projektfenster markieren

Wenn man keine sofortige Synchronisation aktiviert hat (View -> Synchronize Editor with Views), dann stimmt die markierte Datei im Projektfenster nicht mit der aktuell bearbeiteten Datei im Editor überein. Strg+Umschalt+1 markiert die Datei im Projektfenster (und öffnet ggf. das zugehörige Projekt). Das ist dann besonders nützlich, wenn man in eine Klasse per Strg+Mausklick (wie ein Browser-Hyperlink) über Methodennamen gesprungen ist oder der Debugger die Quelltexte geöffnet hatte.

Klasse suchen

Strg+O (Goto Type) ist ein Suchdialog für Klassennamen. In dem Dialog den Suchbegriff eingeben, Doppelklick auf eines der Ergebnisse öffnet die Datei. Strg-Umschalt-1 zeigt die Datei dann in der Projekts-Struktur.

Zu Zeilennummer springen

Strg+G (Goto Linenumber) öffnet einen Dialog, um eine Zeilennummer einzugeben. Dorthin springt dann der Eingabecursor. Wer Exceptions per Mail zugeschickt bekommt, wird das Feature lieben.

Alle Implementationen eines Interfaces

Vor der Deklarationszeile eines Interfaces, abstrakter Klassen und überschriebener Klassen erscheint in der Zeilennummer ein kleines (i). Klickt man darauf, wird eine Liste aller bekannten Implementationen angezeigt. Per Klick kann man in die einzelnen Implementationen springen. Das ist nützlich, wenn man Interface erweitert (neue Methoden-Signaturen) und damit die Kassen angepasst werden müssen.

Editor maximieren

Eigentlich ist der Editor immer zu klein, zumindest geht es mir so. Der Doppelklick auf die Registerzunge zum Maximieren des Editors ist nett aber umständlich. Das Tastenkürzel Maximize Windows [Strg+ESC] ist da schneller. Entgegen des Namens setzt [Strg+ESC] die vergrößerte Registerzunge auch wieder zurück.

Generelle Probleme mit Tastenkürzel

Wer Ubuntu verwendet, wird mit allen Tastenkürzeln unglücklich werden, die mit Alt+Umschalt / Alt+Shift eingeleitet werden. Das klappt unter Ubuntu nicht, da Alt+Umschalt schon vom System belegt ist. Man muss diese Kürzel unter Tools -> Options -> Keymap ändern.

Nutzer deutscher Tastenlayouts kämpfen mit den Shortcuts, deren Keycodes sowieso per Umschalt / Shift zu erreichen sind (Komma, Semikolon, Stern) oder per AltGr (geschweifte und Eckige Klammern). Da muss man meistens die Zugriffs-Kürzel der Actions ebenfalls unter Tools -> Options -> Keymap anpassen.

Veröffentlicht unter NetBeans IDE | 8 Kommentare

BeanDev: New DZone Refcard for NetBeans 7.0 Platform

Hi!

The new updated Refcard #80 by Heiko Böck, Anton Epple, Miloš Šilhánek, Andreas Stefik, Geertjan Wielenga, and Tom Wheeler for the brand new NetBeans 7 Platform is published.

You can find many informations about the NetBeans Platform, a getting started intro, main features, NetBeans Platform modules,  NetBeans Platform APIs, reusable GUI components and  more.

In this Refcard, you are introduced to the key concerns of the NetBeans Platform so that you can save years of work when developing robust and extensible applications.

Six pages packed with many informations, download this Refcard #80 now!

Veröffentlicht unter NetBeans, NetBeans Plattform | Verschlagwortet mit , , , , | 1 Kommentar