sun.misc.Unsafe zur Objekterzeugung ohne Standard-Konstruktor

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

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

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

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)

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.

Automatische Konvertierung von .NET Enterprise Anwendungen über Cross-Compiler in eine Java EE Anwendung

Das hat Mainsoft geschafft. Über die Portierung spricht sich der Hersteller des Cross-Compilers unter http://www.mainsoft.com/solutions/pdfs/PerformanceStudy.pdf aus. Interessant finde ich die Performace-Ergebnisse: Die Anwendung läuft unter dem WebSphere AppServer genauso schnell wie unter der MS .NET Plattform.

The software vendor successfully ported their .NET based application platform onto Java EE using Mainsoft’s technology and professional services saving $1M in R&D costs. The performance of this application was tested on the same hardware and under the same stress test conditions. The ported version of the application showed equivalent performance in average response time, and equivalent performance in server throughput. Thus, an SLA could be met using the ported version of the application without additional hardware investment. The Java EE version of the application also showed that in multi-CPU environments, the scalability characteristics of Java EE and WebSphere Application Server began to show marked improvements over the original .NET application.

Kostenschätzung von Open-Source Projekten mit ohloh

Die Seite ohloh schätzt die Projektkosten bekannter Open-Source Projekte. Unter der Annahme, ein Entwickler verdient $55,000 im Jahr, ergeben das für einige Projekte folgende Zahlen:

Open-Office: $186,086,458

Eclipse WTP: $46,954,139 (WOW!)   Nur das WTP soll teurer als das gesamte NetBeans sein?

NetBeans: $35,872,047

Firefox: $27,993,803

JBoss: $20,908,809

Gimp: $17,219,225

Hibernate: $11,779,390

ghostscript: $11,439,855

Samba: $8,359,750

PostgreSQL: $7,473,356

Derby: $7,210,467

Tomcat: $2,766,102

Lucene: $1,809,755

HSQLDB: $1,686,517

Notepad++: $1,224,341

XFire: $931,946

Some more information about eBays J2EE application?

The presentation The eBay Architecture – Striking a balance between site stability, feature velocity, performance and cost gave me a first impression of the internal architecture but I would like to know a little bit more about the realization. J2EE is (inglorious) “famous” for EJBs, JMS, JCA, … but these terms are not mentioned in the pdf. I got the impression that eBay is not really using the „hard“ stuff.

  • “eBay internally-developed pure Java OR mapping solution.” OK. No CMP. That implies that the container is not responsible for CMT.
  • “Keep Application Tier Completely Stateless”. Ok. No Stateful Session Beans.
  • “eBay scales on Servlets and a rewritten connection pool.” Hm. So no JDBC 2 connection pool from a vendor. So why is this a Java EE application? Because of Stateless Session Beans? (Then JNDI is in the boat.) The Spring folks will see a opportunity for POJOs on Tomcat/Jetty, … 🙂

Does anyone have some more information about this?

Erste Implementierung für JSR 308

Die JSR 308 (Annotations on Java Types) hat unter anderem das Ziel, Annotationen an weiteren Dingen festzumachen:

  • for generic type arguments to parameterized classes:
        Map<@NonNull String, @NonEmpty List<@Readonly Document>> files;

  • for generic type arguments in a generic method or constructor invocation:
        o.<@NonNull String>m("...");

  • for type parameter bounds and wildcards:
        class Folder<F extends @Existing File> { ... }
    Collection<? super @Existing File>

  • for class inheritance:
        class UnmodifiableList<T> implements @Readonly List<@Readonly T> { ... }

  • for throws clauses:
        void monitorTemperature() throws @Critical TemperatureException { ... }

  • for typecasts:
        myString = (@NonNull String) myObject;

  • for type tests:
        boolean isNonNull = myString instanceof @NonNull String;

  • for object creation:
        new @NonEmpty @Readonly List<String>(myNonEmptyStringSet)

    For generic constructors (JLS section 8.8.4), the annotation follows the explicit type arguments (JLS section 15.9):

        new <String> @Interned MyObject()

  • for method receivers:
        public int size() @Readonly { ... }

  • for class literals:
        Class<@NonNull String> c = @NonNull String.class;

  • for arrays:
        Document[@Readonly][] docs4 = new Document[@Readonly 2][12];
    Document[][@Readonly] docs5 = new Document[2][@Readonly 12];

    This syntax permits independent annotations for each distinct level of array, and for the elements; see Section 3.4 for alternative syntaxes.

Die Beispiele stammen aus dem working document von Michael D. Ernst. Auf seiner Homepage lässt sich die Compilererweiterung herunterladen und alles über die JSR 308 nachlesen.

NASA stellt seine World Wind Applikation in Java vor

Eigentlich ganz cool und flott in der Darstellung. Es gibt eine JNLP-Datei für Web-Start, mit der man das gleich ausprobieren kann. Interessant ist auch folgende Aussage:

With this SDK, developers can embed World Wind technology in their own applications. The API documentation will be made available later.

Mit „Place Name“ würde ich mir jetzt irgendwie Ortsnamen wünschen, die kommen aber nicht. Der Server könnte auch schneller sein und für feine Auflösungen sind nicht immer Kacheln dabei. Sehr merkwürdig, dass beim Zoom mal Kacheln kommen und dann wieder verschwinden.

Eine erste Programmieranleitung habe ich hier gefunden.

Contact to javax.beans.binding

This little example will show you how to bind a JTextField to a name property of a Person with Beans Binding (JSR-295). First the Person:

package com.tutego.binding;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class Person
{
private PropertyChangeSupport pcs = new PropertyChangeSupport( this );

private String name = "";

public void addPropertyChangeListener( PropertyChangeListener x )
{
pcs.addPropertyChangeListener( x );
}

public void removePropertyChangeListener( PropertyChangeListener x )
{
pcs.removePropertyChangeListener( x );
}

public String getName()
{
return name;
}

public void setName( String name )
{
String old = getName();
this.name = name;
pcs.firePropertyChange( "name", old, getName() );

System.out.println( "Changed name!" );
}
}

The code for the JavaBean Person is a litte bit cumbersome because of the PropertyChangeListener who will notify the Binding Framework if the model change.

package com.tutego.binding;

import javax.beans.binding.BindingContext;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class BindingDemo
{
public static void main( String[] args )
{
Person p = new Person();

JTextField tf = new JTextField();

BindingContext bindingContext = new BindingContext();
bindingContext.addBinding( p, "${name}", tf, "text" );
bindingContext.bind();


JFrame f = new JFrame();
f.add( tf );
f.pack();
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
f.setVisible( true );

p.setName( "Christian Ullenboom" );
}
}

Swing on the other side will although notify the model if the user type text in the text field and press Return. This will change the model.

Using format()/printf() for formatting and Scanner for parsing localized elements

format() from String or printf() from e.g. PrintWriter will use the default language except you give a Local object as the first argument:

String s1 = String.format( Locale.ENGLISH, "%,.2f", 1000234234.56772345 );
String s2 = String.format( Locale.FRANCE, "%,.2f", 1000234234.56772345 );
System.out.println( s1 ); // 1,000,234,234.57
System.out.println( s2 ); // 1 000 234 234,57

And the class Scanner offers nextDouble() that uses the default language too except you use useLocale().

double s1p = new Scanner( s1 ).useLocale( Locale.ENGLISH ).nextDouble();
double s2p = new Scanner( s2 ).useLocale( Locale.FRENCH ).nextDouble();

The methods format()/printf() and the class Scanner are very handy and easy to use.

Verhältnis von deprecated Elementen zur Gesamtheit

Die Standardbibliothek enthält 200 Pakete, die Java in der Version 6 deklariert. Sie beschreiben zusammen 3777 Typen, davon 2457 Klassen, 972 Schnittstellen, 49 Aufzählungen, 473 Ausnahmeklassen und 32 Errorklassen. Insgesamt gibt es 1482 Objektvariablen, 4408 statische Variablen/Konstanten, 21881 Objektmethoden in Klassen und 5226 aus Schnittstellen, 3039 Klassenmethoden sowie 4973 Konstruktoren. (In Java 1.0 verteilten sich 212 Klassen auf 8 Pakete.)

Veraltetes hat sich im Laufe der Zeit einiges angesammelt. In Java 6 sind über 334 Methoden, 20 Konstruktoren, 54 Variablen/Konstanten, 21 Klassen (zuzüglich 4 Exceptions), 17 Schnittstellen (viele aus CORBA), 3 Annotationstypen und ein Annotationselement veraltet. Dennoch ist das in Relation zur Gesamtheit klein:

Setzen wir beides in Relation (# Elemente/#deprecated davon)

Klassen: 2457/21 = 0,85%

Schnittstellen: 972/17=1,75%

Exceptions: 473/4=0,85%

Methoden: 21881/334=1,53%

Konstruktoren: 4973/20=0,40%

Variablen/Konstanten: 4408/54=1,22%

Einmal Finalizier, vielleicht mehrmals der GC

Objekte von Klassen, die eine finalize()-Methode besitzen, kann Suns JVM nicht so schnell erzeugen und entfernen, wie Klassen ohne finalize(). Das liegt auch daran, dass der GC vielleicht mehrmals laufen muss, um das Objekt zu löschen. Es gilt zwar, dass der GC aus dem Grund finalize() aufruft, weil das Objekt nicht mehr benötigt wird, es kann aber sein, dass aus der finalize()-Funktion die this-Referenz nach außen gegeben wurde, sodass das Objekt wegen einer bestehenden Referenz nicht gelöscht werden kann. Das Objekt wird zwar irgendwann entfernt, aber der Finalizer läuft nur einmal und nicht immer pro GC-Versuch. Einige Hintergründe erfährt der Leser unter http://www.iecc.com/gclist/GC-lang.html#Finalization.

Löst eine Anweisung in finalize() eine Ausnahme aus, so wird diese ignoriert. Das heißt aber, dass die Finalizierung des Objekts stehen bleibt. Den GC beeinflusst das in seiner Arbeit aber nicht.

Shell-Script-Editor (ShellEd) und Eclipse Target Management Project/Remote System Explorer

ShellEd (Bild) ist ein Shell-Script-Editor für Unix-Skripte (also ash, bsh, bash, csh, ksh, sh, zsh). Mit Manual und Vervollständigung. Interessant dazu ist das relativ unbekannte Target Management Project, wo man remote, etwa über SSH oder FTP auf einem Server arbeiten und zum Beispiel Dokumente editieren kann. Siehe dazu den Screenshot zum Remote System Explorer (RSE).

Mehr Eclipse-Plugins gibt’s unter http://www.tutego.com/java/eclipse/plugin/eclipse-plugins.html.