IOException.de

Icon

Ausgewählter Nerdkram von Informatikstudenten der Uni Ulm

Schnelle Quellcode-Navigation in Eclipse

Bei der Entwicklung größerer Java-Projekte kann schnell die Übersicht verloren gehen. Zum Glück bietet Eclipse eine Vielzahl von Shortcuts und Funktionen, um sich auch noch bei einer Vielzahl von Klassen zurecht zu finden.

  • Strg + 3
    Öffnet den intelligenten Quick Access Dialog.
  • Strg + Shift + R
    Öffnet einen Schnelldialog zum Öffnen einer Ressource. Ist insbesondere hilfreich, um eine Datei mit bekanntem Dateinamen direkt zu öffnen, ohne im Package Explorer zu suchen.
  • Strg + Shift + T
    Öffnet einen Schnelldialog zum Öffnen einer Java-Ressource. In der Auswahl kann der Name der Klasse/Interface/etc. direkt eingegeben werden.
  • Strg + Linksklick auf Klassenname
    Sprung zum Quelltext der Klasse, auf die im Editor geklickt wird.
  • Strg + T
    Übersicht der Vererbungshierarchie der Klasse, die sich im Fokus des Editors befindet. Nochmaliges Drücken von Strg + T dreht die Hierarchierichtung (Superklassen/Subklassen) um.
  • Strg + O
    Übersicht der Membervariablen und Methoden der aktuellen Klasse. Nochmaliges Drücken von Strg + O zeigt zusätzlich geerbte Member an.
  • Strg + Shift + G
    Sucht nach Verwendungen der Methode im Fokus des Editors in alles Klassen der Workspaces.
  • Strg + . und Strg + '+'
    Sprung durch die Quelltextzeilen mit Warnungen
  • Strg + L
    Öffnet Dialog für einen Sprung in eine bestimmte Codezeile.
  • Strg + E
    Zeigt Liste aller offenen Editors-Tabs an und ermöglicht Direktauswahl eines offenen Editorstabs per Texteingabe.
  • Strg + Bild Auf und Strg + Bild Ab
    Springen durch die offenen Editor-Tabs.
  • Alt + ← und Alt + →
    Springen durch die Historie der geöffneten Tabs.

Statische Code-Analyse für Java mit FindBugs

findbugs1FindBugs ist ein Open-Source Tool zur statischen Quellcode-Analyse für Java. Es sucht in Java-Code nach typischen Fehlermustern – hierbei wird lediglich der Java Bytecode betrachtet, der Code wird nicht ausgeführt. Hierfür besitzt FindBugs eine reichhaltige Sammlung von typischen Bugs. Diese basieren hauptsächlich auf schwierigen Sprachfeatures (z.B. fehleranfälliger Umgang mit intrinsischen Condition Queueswait/notify/notifyAll), häufig missverstandenen API Funktionen (z.B. Start eines Threads durch Aufruf der run()-Methode anstatt start() ) und markanten Fehlern wie Typos, falschen Vergleichsoperationen (Stringvergleiche mit == anstatt equals) etc. Auch Korrektheit und Korrektheit bei nebenläufigen Programmen sowie Performance- und Sicherheitsaspekte werden beachtet. Eine komplette Liste aller bekannter Fehlermuster gibt es auf der FindBugs Bug Descriptions Seite.

Ein solches Tool kann nie sorgfältiges Design & Implementierung, noch ausgebieges Testen und Debuggen ersetzen, jedoch ist es als weiteres Werkzeug bei der Suche nach Fehlern insbesondere in größeren Projekten sehr hilfreich. Neben einer Kommandozeilenvariante und einer GUI existiert außerdem ein Eclipse-Plugin, womit sich FindBugs vollständig in Eclipse integrieren lässt. Über den Package Explorer lassen sich Analyseprozesse starten, gefunden Fehlermuster werden sowohl in einem Bux Explorer als auch inline im Editor angezeigt.

Java VisualVM

jvisualvm1Seit Version 6 Update 7 besitzt das Java Development Kit ein weiteres hilfreiches Entwicklungstool, nämlich VisualVM. Die Anwendung ermöglicht das Überwachen und Profiling laufender Java-Anwendungen (auch entfernter) virtueller Maschinen. Neben Merkmalen wie dem aktuellen Verbrauch an Speicher, der Größe des Heaps, Anzahl von Threads und geladener Klassen laufender Prozesse lassen sich zusätzlich aus einem erzeugbaren Heapdump zur Laufzeit Informationen über instanziierte Objekte erfragen, wie es vom Eclipse-Debugger bekannt ist. Auch die Garbage Collection kann hier manuell ausgelöst werden. Threads werden inklusive ihrer Zustände chronologisch visualisiert. Dies ist insbesondere beim Debugging von Anwendungen interessant, die intensiv Gebrauch von Multithreading machen. Durch die Anzeige der Zustände der Threads werden Monitore (Locks) sichtbar gemacht. Außerdem können über einen Threadump die einzelnen Callstacks der Threads inspiziert werden.

jvisualvm2Im CPU-Profiling können die Anwendungen in Echtzeit daraufhin untersucht werden, welche Methoden wie oft aufgerufen werden und wieviel CPU-Zeit sie benötigen, was bei der Suche nach möglichen Optimierungsansätzen hilfreich sein könnte. Das Memory-Profiling zeigt die Anzahl von Instanzen, den Speicherverbrauch, sowie den prozentualen Anteil am gesamten Speicherplatz von Klassen und primitiven Datentypen an sowie Informationen zur Garbage Collection.

Durch Plugins lässt sich das Programm noch um weitere Funktionen ergänzen. Entstanden ist das Projekt aus der Sun-eigenen NetBeans-IDE und basiert auch heute noch auf dessen NetBeans-RCP Framework. Zu finden ist es bei jeder JDK Installation ab 6u7 im Ordner bin/jvisualvm. Es lässt sich für ältere JDK-Versionen über einen Download von der Projektseite separat installieren .

Originalartikel: Java VisualVM

Mit Working Sets Eclipse aufräumen

Working Sets im Package ExplorerJedem Eclipse-Benutzer dürfte es bekannt vorkommen, wenn langsam die ganzen Projekte den Package Explorer füllen und dabei die Übersicht verloren geht. Natürlich besteht hier die Möglichkeit, durch verschiedene Workspaces die einzelnen Projekte oder Projektgruppen zu separieren, jedoch stellt eine Unterteilung in Workspaces eine sehr restriktive Trennung dar.
Abhilfe schaffen in Eclipse die so genannten Working Sets – wie bei allen Eclipse-Funktionen muss man halt erstmal überhaupt davon wissen. Working Sets lassen sich über New => Java => Java Working Set erstellen und erzeugen Überordner, in denen sich Projekte gruppieren lassen. Um im Package Explorer die Ansicht nach Working Sets aufzuschlüsseln, müssen diese jedoch als Top Level Elements gewählt werden.

Originalartikel: Mit Working Sets Eclipse aufräumen

Zustandsautomat in Java mithilfe des State Patterns

Automaten sind nicht nur in der theoretischen Informatik ein wichtiges Werkzeug im Bereich der formalen Sprachen zur Überprüfung von Sprachzugehörigkeiten. Eine davon abgeleitete Anwendung ist die Mustererkennung in Zeichenketten mithilfe regulärer Ausdrücke. Aber auch viele Protokolle verteilter Systeme (z.B. TCP) greifen das Konzept von Zustandsautomaten auf, um abhängig von verschiedenen internen Zuständen auf Ereignisse differenziert zu reagieren. Natürlich müssen diese Zustandsautomaten bei der Implementierung von Protokollen auch in Software abgebildet werden. In diesem Artikel möchte ich anhand eines einfachen DFAs aufzeigen, wie solche Zustandsautomaten unter Anwendung des State Patterns in Java realisierbar sind.

In diesem Beispiel soll ein DFA konstruiert werden, der aus allen möglichen Zeichenfolgen bestehend aus Einsen und Nullen genau diejenigen akzeptiert, in denen die Teilworte 01 und 10 gleich oft vorkommen. Der nebenstehende Graph verdeutlicht die Funktionsweise des Automaten. Neben dem Startzustand (S) gibt es zwei gültige Endzustände (A,X) mit gleicher Anzahl von Vorkommen, sowie zwei Zustände (B,Y) die keinen gültigen Endzustand darstellen.

Möchte man nun eine solche Konstruktion implementieren, so muss man Zustände, Übergänge und gültige Kombinationen abbilden. Das State Pattern der GoF als Verhaltensmuster bietet sich bei objektorientierten Sprachen an, da es übersichtlicher, sauberer und erweiterbarer ist als Kaskaden von If-Abfragen oder Switch-Statements-Konstrukten. Die Grundidee hierbei ist, Zustände mit zugehörigen Übergängen in eigene Objekte auszulagern und dem zustandsbehafteten Objekt die entsprechende Referenz auf seinen aktuellen Zustand zu übergeben. Änderungen delegiert dieses zustandsbehaftete Objekt dann an sein aktuelles Zustandsobjekt, welches eventuell nach dem Übergang ersetzt wird. In Java bietet es sich an, die Zustände als Enum-Instanzen zu realisieren und diese ein Interface implementieren zu lassen, welches die Übergange definiert. Zusätzlich lassen sich die Zustände, also Enum-Instanzen, darauf hin abfragen, ob sie einen gülitgen finalen Zustand darstellen.
Die Automaton-Klasse stellt nun das eigentliche Objekt dar, was zustandsbehaftet ist, jedoch mit ausgelagerter Behandlung der Zustände:

Transitions.java – Auflistung der Übergänge als Interface

/**
 * Interface listing possible transitions to be implemented by states
 */
public interface Transitions
{
	public void readZero(Automaton a);

	public void readOne(Automaton a);
}

State.java – Zustände als Enum-Typen

/**
 * Enum type for states
 */
public enum State implements Transitions
{
	/**
	 * Initial State - S
	 */
	S
	{
		@Override
		public void readOne(Automaton a)
		{
			a.setState(X);
		}

		@Override
		public void readZero(Automaton a)
		{
			a.setState(A);
		}

		@Override
		public boolean isFinal()
		{
			return true;
		}
	},

	/**
	 * Final State - A
	 */
	A
	{
		@Override
		public void readOne(Automaton a)
		{
			a.setState(B);
		}

		@Override
		public void readZero(Automaton a)
		{
			a.setState(A);
		}

		@Override
		public boolean isFinal()
		{
			return true;
		}
	},

	/**
	 * State -B
	 */
	B
	{
		@Override
		public void readOne(Automaton a)
		{
			a.setState(B);
		}

		@Override
		public void readZero(Automaton a)
		{
			a.setState(A);
		}

		@Override
		public boolean isFinal()
		{
			return false;
		}
	},

	/**
	 * Final State - X
	 */
	X
	{
		@Override
		public void readOne(Automaton a)
		{
			a.setState(X);
		}

		@Override
		public void readZero(Automaton a)
		{
			a.setState(Y);
		}

		@Override
		public boolean isFinal()
		{
			return true;
		}
	},

	/**
	 * State -Y
	 */
	Y
	{
		@Override
		public void readOne(Automaton a)
		{
			a.setState(X);
		}

		@Override
		public void readZero(Automaton a)
		{
			a.setState(Y);
		}

		@Override
		public boolean isFinal()
		{
			return false;
		}
	};

	/**
	 * Is state final?
	 * @return true if final
	 */
	abstract public boolean isFinal();
}

Automaton.java – Das zustandsbehaftete Objekt inklusive Test in der Main-Methode.

/**
 * Automaton class
 */
public class Automaton
{
	//Initial state
	private State state = State.S;

	public void setState(State s)
	{
		this.state = s;
	}

	public void readZero()
	{
		//Delegate...
		state.readZero(this);
	}

	public void readOne()
	{
		//Delegate...
		state.readOne(this);
	}

	public boolean isInFinalState()
	{
		//Delegate...
		return state.isFinal();
	}

	public static void main(String[] args)
	{
		Automaton a = new Automaton();
		String s1 = "11010101";
		for (char c : s1.toCharArray())
		{
			switch (c)
			{
				case '1':
					a.readOne();
					break;
				case '0':
					a.readZero();
					break;
			}
		}
		System.out.println(a.isInFinalState()); //true...
	}
}


Dieses Beispielprogramm mit einem DFA habe ich zum leichteren Verständis gewählt, natürlich lassen sich mit diesem Pattern weit aus komplexere Abläufe modellieren. So könnte der Automat zum Beispiel ein Buch-Objekt einer Bücherei sein und die Übergänge Aktionen wie das Ausleihen, Verlängeren oder Zurückgeben des Buches. Die Zustände als Enum-Typen würden dann auch mehr Geschäftslogik enthalten als das bloße Verändern das Zustands wie hier in diesem Beispiel.

Originalartikel: Zustandsautomat in Java mithilfe des State Patterns

TinyURLs mit Java auflösen

Hier eine kleine Java-Methode, um Weiterleitungen des URL-Dienstes TinyURL aufzulösen. Der Methode wird die ID der URL als String übergeben, zurückgegeben wird ein URI-Objekt mit der entsprechenden Weiterleitung. Existiert die ID nicht, so wird eine IllegalArgumentException geworfen. Die Abfrage wird direkt auf HTTP-Ebene über die Methode HEAD durchgeführt. Aus diesem Grund sollte bei einem unsicheren Einsatz die ID zuvor überprüft werden, um Injektionen in den HTTP-Request zu verhindern.

	/**
	 * Resolves a TinyUrl redirect
	 * @author Benjamin Erb
	 * @param id http://tinyurl.com/{id}
	 * @return Redirected URI
	 * @throws IOException on network problems
	 * @throws IllegalArgumentException on unknown id 
	 */
	public static URL resolveTinyUrl(String id) throws IOException, IllegalArgumentException
	{
		Socket s = new Socket(InetAddress.getByName("tinyurl.com"),80);
		BufferedWriter w = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
		w.append("HEAD /"+id+" HTTP/1.0\r\nHost: tinyurl.com\r\n\r\n").flush();
		String response;
		Matcher m;
		Pattern p = Pattern.compile("^Location:\\s([^\\r\\n]+)"); 
		while((response = r.readLine())  != null)
		{
			if((m = p.matcher(response)).find())
			{
				w.close();
				r.close();
				s.close();
				return new URL(m.group(1)); 
			}
		}		
		w.close();
		r.close();
		s.close();
		throw new IllegalArgumentException("Unknown TinyURL id");
	}

Originalartikel: TinyURLs mit Java auflösen

Das Singleton-Pattern in Java

Das Singleton-Pattern ist ein Erzeugungsmuster aus dem Klassiker Design Patterns der Gang of Four. Es beschreibt, wie man von einer Klasse gezielt nur eine einzige Instanz erzeugt und darauf einen einfachen Zugriff möglich ist. Typische Einsatzzwecke des Patterns sind zum Beispiel Logger, die von überall im Programm Ereignisse protokollieren sollen oder Manager-Klassen, wie dem Toolkit.getDefaultToolkit(), das bei java.awt eine betriebssystemspezifische Instanz zurückgibt. Das Pattern ist nicht ganz unumstritten, da es Ähnlichkeiten mit unliebsamen globalen Variablen aufweist und außerdem die Testbarkeit von Klassen erschwert, doch hierum soll es an dieser Stelle nicht gehen, sondern viel mehr darum, wie man dieses Pattern in Java implementiert.
Zunächst muss man sicherstellen, dass von der Klasse keine neuen Instanzen erzeugt werden können. Hierfür setzt man die Sichbarkeit des Konstruktors auf private. Die einzige Instanz wird über eine statische Factory-Methode übergeben. Nun gibt es zwei mögliche Zeitpunkte, die Singleton-Instanz zu erzeugen. Entweder beim ersten Aufruf der Factory-Methode (lazy creation), oder aber bereits bei der nitialisierung der Klasse (eager creation). Beide Varianten haben aber zunächst einen kleinen Nachteil.
Die lazy creation ist interessant, weil sie das Objekt wirklich erst dann erstellt, wenn es benötigt wird. Allerdings muss bei der Erstellung der Objektes sichergestellt werden, dass wirklich nur eine Instanz erzeugt wird. Versuchen zeitgleich mehrere Threads, die Instanz zu erzeugen, kann es zu mehreren Instanziierungen kommen. Hier gibt es nun zwei Lösungsansätze: Entweder wird die statische Factory-Methode als synchronized gesetzt, wodurch dann immer nur ein Thread dedizierten Zugriff auf die Instanz hat, was alle anderen Threads blockiert und somit sehr ineffizient ist bei längeren Zugriffen auf die Instanz.

//Explizit synchronisierte lazy declaration Variante - ineffizient!
public class MyClass
{
	/** Feld für Singleton-Instanz */
	private static MyClass instance;

	/**
	 * Privater Konstruktor verhindert externe Instanzierung
	 */
	private MyClass()
	{

	}

	/**
	 * Statische, synchronisierte Factory-Methode
	 * @return Singleton-Instanz
	 */
	public synchronized static MyClass getInstance()
	{
		if (instance == null)
		{
			instance = new MyClass();
		}
		return instance;
	}

}

Eine Alternative wäre das double-checked locking, was allerdings in Java durch das Speichermodell nicht sicher ist und dringend vermieden werden sollte.

Empfehlerswerter bei Java ist also die eager creation, die zum Beispiel so aussehen könnte:

//einfache eager creation Variante - evenutell unnoetige Instanziierung!
public class MyClass
{
	/** Feld für Singleton-Instanz */
	private static final MyClass instance = new MyClass();

	/**
	 * Privater Konstruktor verhindert externe Instanzierung
	 */
	private MyClass()
	{

	}

	/**
	 * Statische Factory-Methode
	 * @return Singleton-Instanz
	 */
	public static MyClass getInstance()
	{
		return instance;
	}
}

Durch einen kleinen Trick kann man verhindern, dass die Instanz schon beim Laden der Klasse erzeugt wird. Hierfür wird eine innere, statische Holder-Klasse geschrieben, die die Instanz kapselt. Diese Varinate ist außerdem implizit threadsicher und deswegen empfehlenswert:

//elegante eager creation Variante - implizite Threadsicherheit 
public class MyClass
{
	/**
	 * Privater Konstruktor verhindert externe Instanzierung
	 */
	private MyClass()
	{

	}

	/**
	 * Innere statische Holder-Klasse
	 */
	private static class Holder
	{
		/** Gekapselte Instanz */
		private static final MyClass INSTANCE = new MyClass();
	}

	/*
	 * Statische Factory-Methode
	 * @return Singleton-Instanz
	 */
	public static MyClass getInstance()
	{
		return Holder.INSTANCE;
	}
}

Seit Java 5 besteht noch eine alternative Variante, die sich die Eigenschaften des Enum-Konstruktes zu eigen macht. Anders als bei C/C++ besitzen die Enum-Typen bei Java objektähnliche Eigenschaften. Somit lässt sich ein Enum als Singleton-Klasse missbrauchen. Dadurch verliert man zwar die Möglichkeit, davon weitere Klassen abzuleiten, dafür ist die Singleton-Instanz direkt serialisierbar.

//Variante mit Enum ab Java 5
public enum MyClass
{
	/** Singleton-Instanz als Enum-Typ */
	INSTANCE;
	
	/**
	 * Konstruktor
	 */
	MyClass()
	{
		
	}
}

Originalartikel: Das Singleton-Pattern in Java

ioexception.de

Benjamin Erb [] studiert seit 2006 Medieninformatik und interessiert sich insbesondere für Java, Web-Technologien, Ubiquitous Computing, Cloud Computing, verteilte Systeme und Informationsdesign.


Raimar Wagner studiert seit 2005 Informatik mit Anwendungsfach Medizin und interessiert sich für C++ stl, boost & Qt Programmierung, Scientific Visualization, Computer Vision und parallele Rechenkonzepte.


David Langer studiert seit 2006 Medieninformatik und interessiert sich für Web-Entwicklung, jQuery, Business Process Management und Java.


Sebastian Schimmel studiert seit 2006 Informatik mit Anwendungsfach Medizin und interessiert sich für hardwarenahe Aspekte, Robotik, webOs, C/C++ und UNIX/Linux.


Timo Müller studiert seit 2006 Medieninformatik. Er interessiert sich allen voran für Mobile and Ubiquitous Computing, systemnahe Enwticklung und verteilte Systeme, sowie Computer Vision.


Achim Strauß studiert seit 2006 Medieninformatik. Seine Interessen liegen in Themen der Mensch-Computer Interaktion sowie Webentwicklung und UNIX/Linux.


Tobias Schlecht studiert seit 2006 Medieninformatik und interessiert sich vor allem für Software Engineering, Model Driven Architecture, Requirements Engineering, Usability Engineering, Web-Technologien, UML2 und Java.


Fabian Groh studiert seit 2006 Medieninformatik. Seine Interessengebiete sind Computer Graphics, Computer Vision, Computational Photography sowie Ubiquitos Computing.


Matthias Matousek studiert seit 2007 Medieninformatik und interessiert sich besonders für Skriptsprachen, Echtzeitsysteme und Kommunikation.


Michael Müller [] studiert seit 2009 Medieninformatik. Er interessiert sich vor allem für Web-Technologien, Ubiquitous Computing, User-Interfaces, UNIX und Creative Coding.


Falco Nogatz [] studiert seit 2010 Informatik mit Anwendungsfach Mathematik. Er interessiert sich für Web-Technologien, Programmierparadigmen und theoretische Grundlagen.

Archiv

Februar 2015
M D M D F S S
« Mrz    
 1
2345678
9101112131415
16171819202122
232425262728