Danke für die Nutzung der Insel als Vorlage für Uni-Folien
11 Kommentar(e). Veröffentlicht von Christian Ullenboom am Dienstag, Juli 31, 2007.Hier möchte ich mich bei Ihnen, Herrn Dr. Ralf Kunze, und Team der Universität Osnabrück herzlich bedanken. Es freut mich sehr, dass Sie für ihre Vorlesungsunterlagen http://www-lehre.inf.uos.de/~binf/2007/index.html "Objekt-orientierte Programmierung in Java" im Sommersemester 2007 so viel Abschnitte der Insel gebrauchen konnten. Immer wieder beglückt es mich, wenn Referenten und Dozenten Abschnitte 1:1 übernehmen und damit die Qualität meines Buches „Java ist auch eine Insel“ auch für den wissenschaftlichen Alltag bestätigen. (Ich wusste auch nicht, dass Rechtschreibfehler im Buch ebenfalls zum Insel-Kult gehören, und sie deshalb auch immer mitkopiert werden müssen.) Dass Sie dabei die Insel erst an dritter Stelle Ihrer Literaturangaben platzieren, ist selbstverständlich zu verzeihen. Besonders gefallen hat mir auf Ihrer Uni-Seite die Aussage „Zum legalen online Lesen, herunterladen oder auch kaufen“. Das finde ich gut, denn „illegales Online-Lesen“ wäre ja quatsch. Natürlich habe weder ich noch mein Verlag Galileo-Computing etwas dagegen einzuwenden, wenn ohne Nachfrage die geglücktesten Abschnitte kopiert und ohne Kennung der Quellen übernommen werden – Seite für Seite als Zitat zu kennzeichnen ist natürlich lästig. Das ist Arbeiten im Sinne von Stanisław Jerzy Lec: „Von der Mehrzahl der Werke bleiben nur die Zitate übrig. Ist es dann nicht besser, von Anfang an nur die Zitate aufzuschreiben?“
Ich war so frei, einige Ihrer Folien auf meinen Blog aufzunehmen. Ich hoffe, Sie sehen von Klagen wegen Urheberrechtsverletzungen ab; immerhin kopiere ich Ihre Texte hier ohne Nachfrage. (Alles Aufzulisten wäre zu viel Arbeit.
Das sind nur einige Beispiele mit direkten Kopien ganzer Absätze
für je eine Folie.)
| Insel | Kopie |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Auch für zwei Beispiele durfte die Insel Vorlage sein. (Das ist rechtlich sicher, da die Insel im Vorwort erlaubt, dass alle Beispiele frei verwendet werden können.) Das eine ist JCheckBoxDemo, welches als CheckBoxDemo mit anderen Grafiken und Beschriftungen -- aus der Auswahl "Ein Colt für alle Fälle" und "MacGyver" wird "Informatik A und Informatik B" -- einer weiteren Zeile im Listener ein neues Leben führt.
Oder
package com.javatutor.insel.thread.group;
public class ShowThreadsInMain
{
public static void main( String[] args )
{
ThreadGroup top = Thread.currentThread().getThreadGroup();
while ( top.getParent() != null )
top = top.getParent();
showGroupInfo( top );
}
public static void showGroupInfo( ThreadGroup group )
{
Thread[] threads = new Thread[ group.activeCount() ];
group.enumerate( threads, false );
System.out.println( group );
for ( Thread t : threads )
if ( t != null )
System.out.printf( "%s -> %s is %sDaemon%n",
group.getName(), t, t.isDaemon() ? "" : "no " );
ThreadGroup[] activeGroup = new ThreadGroup[ group.activeGroupCount() ];
group.enumerate( activeGroup, false );
for ( ThreadGroup g : activeGroup )
showGroupInfo( g );
}
}
Und das Beispiel vom Doktor:
package threadgroup1;
/**
* Informationen ueber die laufenden Threads liefern.
*
* @author Ralf Kunze (rkunze@uos.de), Institut fuer Informatik, Universitaet
* Osnabrueck
* @date 06.05.2007
*/
public class ThreadInfo {
public static void main(String[] args) {
ThreadGroup top = Thread.currentThread().getThreadGroup();
while (top.getParent() != null)
top = top.getParent();
showGroupInfo(" ",top);
}
public static void showGroupInfo(String indent, ThreadGroup group) {
Thread[] threads = new Thread[group.activeCount()];
group.enumerate(threads, false);
System.out.println(indent + group);
for (Thread t : threads)
if (t != null)
System.out.printf("%s%s -> %s is %sDaemon%n",
indent ,group.getName(), t, t.isDaemon() ? "" : "no ");
ThreadGroup[] activeGroup = new ThreadGroup[group.activeGroupCount()];
group.enumerate(activeGroup, false);
for (ThreadGroup g : activeGroup)
showGroupInfo(indent+indent, g);
}
}
Das @author-Tag gefällt mir besonders. Die indent-Erweiterung ist natürlich anzuerkennen. Das habe ich gleich übernommen. Daher gefällt mir der wissenschaftliche Austausch so sehr. Leider gibt es das JavaDoc-Tag @date nicht (zumindest bis Java 6), aber man kann ja schon für die Zukunft programmieren.
Insgesamt finden sich sehr viele Abschnitte aus dem Kapitel IO, Thread, Reflection und Netzwerk in den Uni-Unterlagen, aber in der Reihenfolge, Satzbau und Formulieren sind auch in anderen Kapiteln deutliche Ähnlichkeiten zu erkennen. Danke für die Hommage.
Das ANTLR Eclipse-Plugin
0 Kommentar(e). Veröffentlicht von Christian Ullenboom am Dienstag, Juli 24, 2007.Für den beliebten Parsergenerator ANTLR gibt es unter http://www.javadude.com/tools/antlr3-eclipse/ ein praktisches Plugin. Der Update-Manger von Eclipse wird auf die URL http://javadude.com/eclipse/update gelegt, installiert und neu gestartet. Anschließend geht man im Projekt auf das Kontextmenü und aktiviert Add/Remove ANTLR 3 Nature.
Als nächstes kann man eine ANTLR-Datei ablegen. Auf der Doku-Seite vom Plugin wird eine Grammatik (Datei Expr.g3) angegeben, die hier -- leicht überarbeitet -- angegeben werden soll:
grammar Expr;
@header {
package com.tutego.script.fp;
import java.util.HashMap;
}
@lexer::header {
package com.tutego.script.fp;
}
@members {
HashMap<String,Integer> memory = new HashMap<String,Integer>();
}
prog:
stat +
;
stat:
expr NEWLINE
{
System.out.println( $expr.value );
}
| ID '=' expr NEWLINE
{
memory.put( $ID.text, $expr.value );
}
| NEWLINE
;
expr returns [int value]:
e = multExpr { $value = $e.value; }
(
'+' e = multExpr { $value += $e.value; }
| '-' e = multExpr { $value -= $e.value; }
)*
;
multExpr returns [int value]:
e = atom { $value = $e.value; }
(
'*' e = atom { $value *= $e.value; }
)*
;
atom returns [int value]:
INT
{
$value = Integer.parseInt($INT.text);
}
| ID
{
Integer v = memory.get( $ID.text );
if ( v!=null ) $value = v.intValue();
else System.err.println( "Undefined variable " + $ID.text );
}
| '(' expr ')' {$value = $expr.value;}
;
ID:
('a'..'z' | 'A'..'Z') +
;
INT:
'0'..'9' +
;
NEWLINE:
'\r' ? '\n'
;
WS:
(' ' | '\t') +
{
skip();
}
;
Bearbeiten lässt sich die Grammatik in Eclipse nicht ordentlich, doch dafür dient ja die ANTLRWorks: The ANTLR GUI Development Environment.
Das Schöne beim Plugin: Es generiert automatisch im Hintergrund den Parser und Lexer. Das Testprogramm ist schnell geschrieben:
package com.tutego.script.fp;import org.antlr.runtime.*;
public class FpRunner
{
public static void main( String[] args ) throws Exception
{
ExprLexer lex = new ExprLexer( new ANTLRStringStream("age=34\nage*2\n12*111\n") );ExprParser parser = new ExprParser( new CommonTokenStream( lex ) );
try
{
parser.prog();
}
catch ( RecognitionException e )
{
e.printStackTrace();
}
}
}
Die Ausgabe ist dann
68
1332
Labels: Eclipse, Entwicklungsumgebung
sun.misc.Unsafe zur Objekterzeugung ohne Standard-Konstruktor
0 Kommentar(e). Veröffentlicht von Christian Ullenboom am Montag, Juli 23, 2007.Inselupdate: Die Laufzeitumgebung von Sun liefert noch über 3000 Klassendateien in den Paketen sun und sunw aus. Diese internen Klassen sind nicht offiziell dokumentiert[1], aber zum Teil sehr leistungsfähig und erlauben selbst direkten Speicherzugriff oder können Objekte ohne Standard-Konstruktor erzeugen:
com/tutego/insel/sun/UnsafeInstance.java, Ausschnitt
Field field = sun.misc.Unsafe.class.getDeclaredField( "theUnsafe" );
field.setAccessible( true );
sun.misc.Unsafe unsafe = (sun.misc.Unsafe) field.get( null );
File f = (File) unsafe.allocateInstance( File.class );
System.out.println( f.getPath() ); // null
File hat keinen Standard-Konstruktor, noch nicht einmal einen privaten. Diese Art der Objekterzeugung kann bei der Deserialisierung (siehe dazu Kapitel 13) hilfreich sein.
[1] Das Buch “Java Secrets“ von Elliotte Rusty Harold geht den Klassen nach, ist aber schon älter.
Inselupdate: Erkennungsstring (Action-Command) einer Schalftfläche ändern
0 Kommentar(e). Veröffentlicht von Christian Ullenboom am Montag, Juli 23, 2007.Manche Ereignisbehandler sind für Schaltflächen so ähnlich, dass Entwickler nur einen Listener mit mehreren Schaltflächen verbinden möchten. Dann taucht nur das Problem auf, wie der Listener die Schaltflächen unterscheiden kann. Eine Idee wäre, die Beschriftung mit getText() auszulesen – das bringt allerdings das Problem mit sich, dass die Software stark landessprachlich ist, denn bei mehrsprachigen Anwendungen kann sich die Aufschrift ändern. Eine andere Lösung wäre mit getSource() zu arbeiten. Doch dann müsste im Listener die Komponenten für einen Vergleich verfügbar sein, was sie oft nicht ist.
Als Lösung bietet die AbstractButton-Klasse die Methode setActionCommand() an, mit der sich eine Kennung, der sogenannte Action-Command setzen lässt.
abstract class javax.swing.AbstractButton extends JComponent implements ItemSelectable, SwingConstants
- void setActionCommand( String command )
Setzt einen neuen Kommandostring, wenn das Ereignis ausgeführt wird.
Der Listener kann diesen Action-Command mit getActionCommand() aus dem ActionEvent auslesen.
class java.awt.event.ActionEvent extends AWTEvent
- String getActionCommand()
Liefert den String, der mit dieser Aktion verbunden ist.
Ohne explizites Setzen ist der Action-Command standardmäßig mit der Beschriftung der Schaltfläche initialisiert.
Inselupdate: Zugriff auf die gesamte Windows-Registry
2 Kommentar(e). Veröffentlicht von Christian Ullenboom am Freitag, Juli 20, 2007.Wird Java unter MS Windows ausgeführt, so ergibt sich hin und wieder die Aufgabe, Eigenschaften der Windows-Umgebung zu kontrollieren. Viele Eigenschaften des Windows-Betriebssystems sind in der Registry versteckt, und Java bietet als plattformunabhängige Sprache keine Möglichkeit, diese Eigenschaften in der Registry auszulesen oder zu verändern. (Die Schnittstelle java.rmi.registry.Registry ist eine Zentrale für entfernte Aufrufe und hat mit der Windows-Registry nichts zu tun. Auch das Paket java.util.prefs mit der Klasse Preferences erlaubt nur Modifikationen an einem ausgewählten Teil der Windows-Registry.)
Um von Java auf alle Teile der Windows-Registry zuzugreifen, gibt es mehrere Möglichkeiten, unter anderem:
- Windows Registry API Native Interface (http://tutego.com/go/jnireg), die frei zu benutzen ist und keiner besonderen Lizenz unterliegt.
- http://www.cogentlogic.com/jndi/ einen JNDI Service Provider for Windows Registries für teure 299 kanadische Dollar.
- Preferences unter Windows realisiert: java.util.prefs.WindowsPreferences. Damit ist keine zusätzlich native Implementierung – und damit eine Windows DLL im Klassenpfad – nötig. Die Bibliothek https://sourceforge.net/projects/jregistrykey/ realisiert eine solche Lösung.
- reg zum Setzen und Abfragen von von Schlüsselwerten.
Beispiel Zeigen den Dateinamen für den Desktop-Hintergrund an:
$ reg query "HKEY_CURRENT_USER\Control Panel\Desktop" /v Wallpaper
! REG.EXE VERSION 3.0
HKEY_CURRENT_USER\Control Panel\Desktop
Wallpaper REG_SZ C:\Dokumente und Einstellungen\tutego\Anwendungsdaten\Hintergrund.bmp
Unterschiedlicher Persistence Context und Speicherprobleme
0 Kommentar(e). Veröffentlicht von Christian Ullenboom am Donnerstag, Juli 19, 2007.Ein Persistence Context verwaltet Entities und kontrolliert ihren Lebenszyklus.
Man unterscheidet zwei Arten von Persistence Context:
–Transaction-scoped Persistence Context
–Extended Persistence Context
•Mit EntityManagerFactory.createEntityManager() bekommt man den Extended Persistence Context.
–createEntityManager() liefert den Application-Managed Entity Manager.
•Der Persistence Context beginnt, wenn der Application-Managed Entity Manager erzeugt wird und endet erst dann, wenn der Entity-Manager geschlossen wird.
•Werden Entities geladen, so bleiben sie so lange im Extended Persistence Context, bis der der Kontext geschlossen oder alle Entities ausdrücklich gelöscht werden.
–Entities bleiben also sehr lange „manged“ und nur dann „detached“, wenn der Entity-Manager geschlossen wird.
•Der Transaction Persistence Context ist der übliche Persistence Context eines „Container-Managed Entity Managers“, der also über den Container injiziert wird.
@PersistenceContext EntityManager em;
•Der EntityManager erzeugt pro Transaktionen einen neuen Persistence Context.
–Der Persistence Context endet bei einem Commit oder Rollback der Transaktion.
•Innerhalb der Transaktion werden die zum Beispiel über find() oder Query geladenen Entites zu managed Entities.
•Da nach der Transaktion der Persistence Context endet, werden die dort verwalteten Entities detached.
•Da der Transaction Persistence Context pro Transaktion aufgebaut wird, ist die Anzahl der verwalteten Objekte relativ klein.
•Der Extended Persistence Context ist oft deutlich länger und kann nach einer Zeit sehr viele Objekte aufnehmen.
–Damit kann das zu einem Speicherproblem werden.
•Um beim Extended Persistence Context kein Speicherproblem zu bekommen gibt es unterschiedliche Strategien:
–Von Zeit zu Zeit clear() vom EntityManager aufrufen. Das detached Objetkte.
–Auf das passende Lazy-Load achten.
–Weniger Objekte laden: Bei unachtsamem Design werden oft viel zu viele Objekte geladen.
•Besonders Gib-Mir-Alles-Ausdrücke wie „select o from Entity o“ sind gefährlich, da die Anzahl der Objekte groß sein kann, obwohl nur ein kleiner Teil der Objekte wirklich benötigt wird.
–Eine Paginierung kann hier sinnvoller sein um nur das zu laden, was zum Beispiel sichtbar ist.
•Einzelne Entities lassen sich nicht aus dem Entity-Manger entfernen (detachen).
–Bei Hibernate oder anderen Implementierungen funktioniert das, bei JPA standardmäßig nicht.
•Aber andersherum gibt es eine Lösung.
–Also alles freigeben, bis auf ausgewählte Objekte.
•Gibt es einen Verweis auf eine Entity-Objekt vom Persistence Context aus und von außen, und wird dann clear() den Persistence Context löschen, wird der Garbage-Collector das Objekt natürlich nicht freigeben.
–Das losgelöste Entity-Objekt kann später mit merge() wieder in den Persistence Context gesetzt werden.
Gui-Designer in NetBeans 6 (M10) mit Unterstützung für Beans Binding technology (JSR 295) + Swing Application Framework (JSR 296)
5 Kommentar(e). Veröffentlicht von Christian Ullenboom am Samstag, Juli 07, 2007.Ein kleines Demo zeigt, was heute mit BeanBeans möglich ist: http://www.netbeans.org/download/flash/netbeans_6_gui_builder/netbeans_6_gui_builder.html. Sehr hübsch. Ich lasse mich mal überraschen, wie verpfuscht dann die Gui-Anwendungen werden, wenn sie ohne Kenntnisse über den Entwurf mehrschichtiger Anwendungen gebaut werden.
