<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-951416721955590499</id><updated>2011-12-22T15:30:40.569+01:00</updated><category term='VisualVM'/><category term='Struts'/><category term='JPA'/><category term='JBoss'/><category term='JVM'/><category term='Lift'/><category term='Java EE'/><category term='CSS'/><category term='Dependency Injection'/><category term='GlassFish'/><category term='Hibernate'/><category term='Funktionale Programmierung'/><category term='Java ME'/><category term='XML'/><category term='NetBeans'/><category term='Apple'/><category term='Java'/><category term='WebObjects'/><category term='Open Source'/><category term='Parallele Programmierung'/><category term='JavaFX'/><category term='Swing'/><category term='EJB'/><category term='Scala'/><category term='Annotationen'/><category term='Eclipse'/><category term='HTML'/><category term='Mac OS X'/><category term='JMS'/><category term='Spring'/><category term='JavaScript'/><category term='Serialisierung'/><category term='Ant'/><category term='OpenJDK'/><title type='text'>Thomas Muchs Java Blog</title><subtitle type='html'>Gedanken und Schnipsel rund um die Java-Technologie im Allgemeinen, um Java EE im Speziellen - und manchmal auch zu Java auf Mac OS X.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>56</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-3737844281426029506</id><published>2011-12-22T11:44:00.002+01:00</published><updated>2011-12-22T15:30:40.579+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>JAXB und HashMaps</title><content type='html'>Die Technik ist zwar schon älter, aber vielleicht ist folgender Tipp trotzdem nützlich – zumal die entsprechende JAXB-Eigenschaft nicht sonderlich gut dokumentiert ist.&lt;br /&gt;&lt;br /&gt;Wenn man Schlüssel-Wert-Paare aus einer XML-Datei in eine HashMap einlesen soll, ist das recht einfach, sofern man Einfluss auf die Struktur des XML-Dokuments hat und dieses in etwa so aussehen kann:&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&amp;gt;&lt;br /&gt;&amp;lt;meineEntitaet&amp;gt;&lt;br /&gt;  &amp;lt;paarliste&amp;gt;&lt;br /&gt;    &amp;lt;entry&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;MeinSchlüssel&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;value&amp;gt;MeinWert&amp;lt;/value&amp;gt;&lt;br /&gt;    &amp;lt;/entry&amp;gt;&lt;br /&gt;    &amp;lt;entry&amp;gt;&lt;br /&gt;      &amp;lt;key&amp;gt;...&amp;lt;/key&amp;gt;&lt;br /&gt;      &amp;lt;value&amp;gt;...&amp;lt;/value&amp;gt;&lt;br /&gt;    &amp;lt;/entry&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;  &amp;lt;/paarliste&amp;gt;&lt;br /&gt;&amp;lt;/meineEntitaet&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Die zugehörige Klasse muss dann wie folgt aufgebaut und mit JAXB-Annotationen versehen sein:&lt;br /&gt;&lt;pre&gt;import java.util.*;&lt;br /&gt;import javax.xml.bind.annotation.*;&lt;br /&gt;&lt;br /&gt;@XmlRootElement&lt;br /&gt;@XmlAccessorType(XmlAccessType.FIELD)&lt;br /&gt;public class MeineEntitaet {&lt;br /&gt;&lt;br /&gt;  @XmlElementWrapper(name="paarliste")&lt;br /&gt;  private Map&amp;lt;String,String&amp;gt; map&lt;br /&gt;    = new HashMap&amp;lt;String,String&amp;gt;();&lt;br /&gt;&lt;br /&gt;  public Map&amp;lt;String,String&amp;gt; getMap() {&lt;br /&gt;    return map;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setMap(Map&amp;lt;String,String&amp;gt; map) {&lt;br /&gt;    this.map = map;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Die XML-Datei lässt sich dann mit folgender Anweisung in ein Objekt einlesen:&lt;br /&gt;&lt;pre&gt;MeineEntitaet obj =&lt;br /&gt;  JAXB.unmarshal(&lt;br /&gt;    new File("beispiel.xml"),&lt;br /&gt;    MeineEntitaet.class);&lt;br /&gt;System.out.println( obj.getMap() );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Genauso einfach lässt sich natürlich auch eine HashMap als XML schreiben:&lt;br /&gt;&lt;pre&gt;MeineEntitaet obj = new MeineEntitaet();&lt;br /&gt;obj.getMap().put("MeinSchlüssel", "MeinWert");&lt;br /&gt;// JAXB.marshal(obj, System.out);&lt;br /&gt;JAXB.marshal(obj, new File("beispiel.xml"));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Während man den XML-Element-Namen der Schlüssel-Wert-Paare-Liste mit der Annotation &lt;code&gt;@XmlElementWrapper&lt;/code&gt; konfigurieren kann, sind die Elemente &lt;code&gt;entry&lt;/code&gt;, &lt;code&gt;key&lt;/code&gt; und &lt;code&gt;value&lt;/code&gt; fest benannt. Um auch diese Namen zu verändern, muss man einen eigenen &lt;a href="http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html"&gt;XmlAdapter&lt;/a&gt; implementieren.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-3737844281426029506?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/3737844281426029506/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/12/jaxb-und-hashmaps.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3737844281426029506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3737844281426029506'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/12/jaxb-und-hashmaps.html' title='JAXB und HashMaps'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-3044759261470122067</id><published>2011-11-28T12:55:00.004+01:00</published><updated>2011-12-01T23:03:23.930+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Parallele Programmierung'/><category scheme='http://www.blogger.com/atom/ns#' term='Java EE'/><title type='text'>Message Driven Beans anhalten und starten</title><content type='html'>Message Driven Beans (MDBs) werden meistens schon aktiv (d.h. vom Container aufgerufen, wenn über JMS Nachrichten für die Bean vorhanden sind), während das Deployment der Anwendung noch läuft. Das ist normalerweise unkritisch, aber es gibt Situationen, in denen man sicherstellen möchte/muss, dass die MDBs erst nach vollständigem Deployment (oder irgend einem anderen definierten Zeitpunkt) aktiv werden.&lt;br /&gt;&lt;br /&gt;Nahezu jedes Messaging-System (JMS-Implementierung) bietet die Möglichkeit, über produktspezifische API oder externe Kommandos eine Queue anzuhalten und später wieder zu starten. Das betrifft aber die komplette Queue, d.h. es ist dann auch nicht mehr möglich, Nachrichten in die Queue zu schreiben.&lt;br /&gt;&lt;br /&gt;Bei einigen Messaging-Systeme kann man daher via JMX die MBean einer MDB ermitteln und damit tatsächlich nur die MDB anhalten – also die Zustellung aus der Queue unterbinden. Das Schreiben in die Queue wäre dann immer noch möglich. (Das Problem, wie damit die MDB gleich zu Beginn des Deployments gestoppt wird, lassen wir mal außen vor.)&lt;br /&gt;&lt;br /&gt;Leider sind beide Lösungen produktspezifisch. Eine portable Lösung ist bis inkl. Java EE 6 für Message Driven Beans nicht vorgesehen. Wie könnte eine selbst gebaute, portable Lösung aussehen?&lt;br /&gt;&lt;br /&gt;Java SE 5 hat im Paket &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html"&gt;java.util.concurrent&lt;/a&gt; viele neue Klassen rund um Thread-Synchronisation und Sperren in die Java-Welt gebracht. Für unsere Zwecke ist ein &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html"&gt;CountDownLatch&lt;/a&gt; geeignet:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;import java.util.concurrent.CountDownLatch;&lt;br /&gt;&lt;br /&gt;@Singleton&lt;br /&gt;public class AppStatus {&lt;br /&gt;&lt;br /&gt;  private static final CountDownLatch startSignal&lt;br /&gt;      = &lt;b&gt;new CountDownLatch(1)&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;  public void waitForAppInitialized() {&lt;br /&gt;    try {&lt;br /&gt;      startSignal.&lt;span style="font-weight: bold;"&gt;await()&lt;/span&gt;;&lt;br /&gt;    } catch (InterruptedException e) {&lt;br /&gt;      throw new RuntimeException(&lt;br /&gt;        "Fehler beim Warten auf Sperren-Freigabe", e);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setAppIsInitialized() {&lt;br /&gt;    startSignal.&lt;b&gt;countDown()&lt;/b&gt;;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public boolean isAppInitialized() {&lt;br /&gt;    return (startSignal.getCount() == 0L);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Der CountDownLatch ist zu Beginn gesperrt. Zur Freigabe muss die Anwendung zu einem geeigneten Zeitpunkt die Methode &lt;code&gt;setAppIsInitialized()&lt;/code&gt; aufrufen, beispielsweise in einem &lt;a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html"&gt;ServletContextListener&lt;/a&gt; oder in einem &lt;a href="http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html"&gt;EJB-Timer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Die zu blockierende MDB wartet dann bei jedem Aufruf zunächst darauf, ob die Sperre schon freigegeben wurde:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@MessageDriven&lt;br /&gt;public class StartbareMDB implements MessageListener {&lt;br /&gt;&lt;br /&gt;  @EJB&lt;br /&gt;  private AppStatus status;&lt;br /&gt;&lt;br /&gt;  public void onMessage(Message msg) {&lt;br /&gt;&lt;br /&gt;    &lt;span&gt;status&lt;/span&gt;.&lt;span style="font-weight: bold;"&gt;waitForAppInitialized()&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    // ... der eigentliche MDB-Code ...&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Eine einfache, funktionierende Lösung mit Java-Bordmitteln.&lt;br /&gt;&lt;br /&gt;Nachteil dieser Lösung ist, dass hier Threads des Containers blockiert werden. Man muss aufpassen, dass die Maximalzahl der blockierten MDB-Threads den Threadpool nicht überfordert (was ein Grund ist, warum man in Java EE-Containern nicht mit Threads herumspielen soll).&lt;br /&gt;&lt;br /&gt;Außerdem ist der Performanceverlust nicht riesig, aber messbar. Für Höchstlastsysteme ist das also evtl. nicht geeignet. Zumal dort oft Clustering zum Einsatz kommt – und obige Lösung ist nur clusterfähig, wenn man sicherstellen kann, dass die Freigabe-Methode auf jedem Cluster-Knoten aufgerufen wird.&lt;br /&gt;&lt;br /&gt;Als weitere (bewusste) Einschränkung ist zu beachten, dass der CountDownLatch nur einmalig nutzbar ist, er dient also wirklich nur als Start-Signal. Wenn man Message Driven Beans beliebig anhalten und starten möchte, muss man andere Sperren verwenden.&lt;br /&gt;&lt;br /&gt;Fazit: Die hier vorgestellte Lösung funktioniert in vielen praktischen Situationen gut. Aber gibt es andere Ideen / Lösungen, die ähnlich einfach zu realisieren sind, die gezeigten Einschränkungen aber nicht aufweisen? Oder müssen wir auf Java EE 7 (oder eher 8) warten?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-3044759261470122067?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/3044759261470122067/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/11/message-driven-beans-anhalten-und.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3044759261470122067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3044759261470122067'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/11/message-driven-beans-anhalten-und.html' title='Message Driven Beans anhalten und starten'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-2557211603997712107</id><published>2011-11-24T12:44:00.004+01:00</published><updated>2011-11-24T13:18:58.506+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenJDK'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Java für Mac OS X 10.7 "Lion"</title><content type='html'>Da Apple vor kurzem Java-Updates für Mac OS X veröffentlicht hat, gibt es an dieser Stelle eine kleine Erinnerung an die wichtige Änderung, die mit &lt;a href="http://www.apple.com/de/macosx/"&gt;Mac OS X 10.7 "Lion"&lt;/a&gt; eingeführt wurde: Im Gegensatz zu allen anderen Mac OS X-Versionen davor (*) ist &lt;span style="font-style:italic;"&gt;keine Java-Laufzeitumgebung mehr vorinstalliert&lt;/span&gt;.&lt;br /&gt;&lt;small&gt;(* Von der &lt;a href="http://de.wikipedia.org/wiki/Mac_OS_X#Mac_OS_X"&gt;10.0-Public Beta&lt;/a&gt;, die wir uns 2000 von der &lt;a href="http://www.snailshell.de/album/free/paris2.jpg"&gt;Apple Expo Paris&lt;/a&gt; mitgenommen haben, mal abgesehen.)&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-r8lyup77F3g/Ts4uRViP5tI/AAAAAAAAAFY/jVQdGgUX3Po/s1600/mosx17java-install.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 192px;" src="http://1.bp.blogspot.com/-r8lyup77F3g/Ts4uRViP5tI/AAAAAAAAAFY/jVQdGgUX3Po/s320/mosx17java-install.png" alt="" id="BLOGGER_PHOTO_ID_5678527055534221010" border="0" /&gt;&lt;/a&gt;Beim ersten Aufruf einer Java-Anwendung erhält man einen Hinweis, dass die Java-Runtime benötigt wird. Bestätigt man dies, wird Java SE 6 heruntergeladen und installiert. Danach wird die ursprünglich aufgerufene Java-Anwendung gestartet.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-irY3zRU09YI/Ts4vDYZlUQI/AAAAAAAAAFk/oebUkzGwZ-0/s1600/mosx17java-download.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 111px;" src="http://3.bp.blogspot.com/-irY3zRU09YI/Ts4vDYZlUQI/AAAAAAAAAFk/oebUkzGwZ-0/s320/mosx17java-download.png" alt="" id="BLOGGER_PHOTO_ID_5678527915296641282" border="0" /&gt;&lt;/a&gt;Das aktuelle Java-Update von Apple enthält Java 1.6.0_29 und ist damit zeitlich erfreulich nah an &lt;a href="http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html"&gt;Oracles Java 6-Update&lt;/a&gt; für andere Systeme. Java 7, für andere Systeme mittlerweile als erstes Update freigegeben, ist leider immer noch nicht final für Mac OS X verfügbar (immerhin gibt es eine &lt;a href="http://jdk7.java.net/macportpreview/"&gt;Developer Preview&lt;/a&gt; von Oracle). Java 8, was sich derzeit noch in der Entwicklung befindet, ist aber schon als Build des &lt;a href="http://www.muchsoft.com/java/macosxjavaversions.html"&gt;OpenJDK 8 für Mac OS X&lt;/a&gt; erhältlich.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-fO0qR9clKcM/Ts40E899wbI/AAAAAAAAAFw/qRyPWI_SNqE/s1600/mosx17java-update1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 309px; height: 320px;" src="http://1.bp.blogspot.com/-fO0qR9clKcM/Ts40E899wbI/AAAAAAAAAFw/qRyPWI_SNqE/s320/mosx17java-update1.png" alt="" id="BLOGGER_PHOTO_ID_5678533439850922418" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-2557211603997712107?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/2557211603997712107/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/11/java-fur-mac-os-x-107-lion.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2557211603997712107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2557211603997712107'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/11/java-fur-mac-os-x-107-lion.html' title='Java für Mac OS X 10.7 &quot;Lion&quot;'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-r8lyup77F3g/Ts4uRViP5tI/AAAAAAAAAFY/jVQdGgUX3Po/s72-c/mosx17java-install.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-6409069854116586142</id><published>2011-10-25T22:31:00.002+02:00</published><updated>2011-10-25T22:34:55.398+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Zeitdauern berechnen mit TimeUnit</title><content type='html'>Auf &lt;a href="http://home.java.net/"&gt;java.net&lt;/a&gt; ist gerade ein netter &lt;a href="http://weblogs.java.net/blog/hallorant/archive/2011/10/21/timeunit-rocks"&gt;Blog-Artikel&lt;/a&gt; verlinkt, der das &lt;code&gt;java.util.concurrent&lt;/code&gt;-Enum &lt;a href="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/TimeUnit.html"&gt;TimeUnit&lt;/a&gt; vorstellt. Aus diesem Anlass eine kleine Idee, wofür ich dieses Enum und seine Umwandlung-Methoden schon gut gebrauchen konnte. Wenn man Zeitdifferenzen berechnet, benötigt man häufiger Konstanten von folgender Art:&lt;br /&gt;&lt;pre&gt;public static final long MS_PRO_TAG&lt;br /&gt;             = 1L * 24L * 60L * 60L * 1000L;&lt;/pre&gt;Das funktioniert zwar, ist aber fehleranfällig, weil man sich bei Anzahl und Wert der Faktoren leicht vertun kann. Mit folgendem Ausdruck kann eine beliebige Anzahl Tage (hier: 1) in Millisekunden umgerechnet werden:&lt;br /&gt;&lt;pre&gt;public static final long MS_PRO_TAG&lt;br /&gt;             = &lt;b&gt;TimeUnit.DAYS.toMillis(1L)&lt;/b&gt;;&lt;/pre&gt;Ebenso lassen sich Sekunden in Stunden umrechnen etc.:&lt;br /&gt;&lt;pre&gt;assert &lt;b&gt;TimeUnit.SECONDS.toHours(7250L)&lt;/b&gt; == 2;&lt;/pre&gt;Wie der andere Blog-Autor schon schreibt: Eigentlich gehört dieses Enum ins Package &lt;code&gt;java.lang&lt;/code&gt; (oder vielleicht noch besser nach &lt;code&gt;java.util&lt;/code&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-6409069854116586142?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/6409069854116586142/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/10/zeitdauern-berechnen-mit-timeunit.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6409069854116586142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6409069854116586142'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/10/zeitdauern-berechnen-mit-timeunit.html' title='Zeitdauern berechnen mit TimeUnit'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-964184924787950691</id><published>2011-10-13T22:23:00.001+02:00</published><updated>2011-10-13T22:24:57.575+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GlassFish'/><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>"reschedule-failed-timer" in GlassFish 3.1</title><content type='html'>In Stateless Session Beans, Singleton Beans und Message Driven Beans kann der &lt;a href="http://download.oracle.com/javaee/6/tutorial/doc/bnboy.html"&gt;EJB-Timer-Service&lt;/a&gt; genutzt werden. Ab EJB 3.1 ist es dabei sehr einfach geworden, wiederkehrende Intervall-Timer mit der @Schedule-Annotation zu definieren (eine programmatische Definition ist natürlich weiterhin möglich).&lt;br /&gt;&lt;br /&gt;Wenn ein periodischer Timer eine Exception wirft, wird &lt;a href="http://glassfish.java.net/"&gt;GlassFish&lt;/a&gt; sofort noch zweimal versuchen, die Timer-Methode auszuführen. Werden auch diese Aufrufe mit Exceptions abgebrochen, &lt;span style="font-style: italic;"&gt;stoppt GlassFish den Timer komplett&lt;/span&gt;, d.h. auch nach Ablauf des nächsten Intervall-Zeitraums erfolgt kein Aufruf mehr! Ich bin mir nicht sicher, ob dieses Verhalten von der EJB-Spezifikation gedeckt ist – intuitiv dürfte man aber vermutlich erwarten, dass Intervall-Timer zuverlässig ausgeführt werden.&lt;br /&gt;&lt;br /&gt;Seit &lt;a href="http://java.net/jira/browse/GLASSFISH-4634"&gt;GlassFish 3.1&lt;/a&gt; gibt es eine Server-Property "reschedule-failed-timer", mit der dieses Verhalten konfiguriert werden kann. Über das Konfigurationsprogramm &lt;code&gt;asadmin&lt;/code&gt; kann man mit&lt;br /&gt;&lt;br /&gt;&lt;code&gt;asadmin set configs.config.server-config.ejb-container.ejb-timer-service.property.reschedule-failed-timer=true&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;einstellen, dass auch per Exception abgebrochene Timer nach Ablauf des nächsten Intervall-Zeitraums wieder aufgerufen werden. Durch den Aufruf wird in &lt;code&gt;domain.xml&lt;/code&gt; folgender Abschnitt eingetragen:&lt;br /&gt;&lt;pre&gt;&amp;lt;ejb-container session-store="${com.sun.aas.instanceRoot}/session-store"&amp;gt;&lt;br /&gt;  &amp;lt;ejb-timer-service&amp;gt;&lt;br /&gt;    &amp;lt;property name="reschedule-failed-timer" value="true"&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;  &amp;lt;/ejb-timer-service&amp;gt;&lt;br /&gt;&amp;lt;/ejb-container&amp;gt;&lt;/pre&gt;Ohne das Setzen der Property bleibt ansonsten nur, den gesamten Timer-Methoden-Rumpf in &lt;code&gt;try { ... } catch (Exception ...)&lt;/code&gt; einzufassen, damit garantiert keine Exception den Timer verlässt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-964184924787950691?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/964184924787950691/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/10/reschedule-failed-timer-in-glassfish-31.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/964184924787950691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/964184924787950691'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/10/reschedule-failed-timer-in-glassfish-31.html' title='&quot;reschedule-failed-timer&quot; in GlassFish 3.1'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-294990331925729017</id><published>2011-10-05T21:51:00.004+02:00</published><updated>2011-10-13T21:44:33.730+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenJDK'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Oracle JDK7 für Mac OS X (Developer Preview)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-2h0Oge3GIR4/Tpc8oK1UsBI/AAAAAAAAAE8/Y6XGn_604Tc/s1600/oracle-jdk7-mac-ea.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 122px;" src="http://2.bp.blogspot.com/-2h0Oge3GIR4/Tpc8oK1UsBI/AAAAAAAAAE8/Y6XGn_604Tc/s320/oracle-jdk7-mac-ea.png" alt="" id="BLOGGER_PHOTO_ID_5663061717242130450" border="0" /&gt;&lt;/a&gt;Nachdem &lt;a href="http://www.oracle.com/technetwork/java/javase/downloads/"&gt;Java SE 7&lt;/a&gt; schon seit einigen Monaten für Windows, Linux und Solaris verfügbar ist und eine &lt;a href="http://javabarista.blogspot.com/2011/01/openjdk-7-fur-mac-os-x.html"&gt;Portierung des OpenJDK 7&lt;/a&gt; für Mac OS X begonnen wurde, bietet Oracle nun eine &lt;a href="http://jdk7.java.net/macportpreview/"&gt;Vorabversion des JDK 7 für Mac OS X&lt;/a&gt; an.&lt;br /&gt;&lt;br /&gt;Die Installation ist denkbar einfach: Nach dem &lt;a href="http://jdk7.java.net/macportpreview/"&gt;Download&lt;/a&gt; der DMG-Datei zieht (kopiert) man die enthaltene Paket-Datei einfach ins Verzeichnis &lt;code&gt;/Library/Java/JavaVirtualMachines&lt;/code&gt;. Fertig! Das Verzeichnis sollte bereits existieren, wenn man das letzte &lt;a href="http://www.muchsoft.com/java/macosxjavaversions.html"&gt;Apple-Java-Update&lt;/a&gt; installiert hat, ansonsten muss man es von Hand anlegen.&lt;br /&gt;&lt;br /&gt;Die neue Version wird sofort von den Java-Einstellungen erkannt, ein Neustart des Systems ist nicht notwendig. Anwendungen müssen beendet und neu gestartet werden, um das neue Java nutzen zu können.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-7XbyRvBwd8c/Tpc-c0ZqgdI/AAAAAAAAAFI/DR8tsH4FH7w/s1600/oracle-jdk7-mac-prefs.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 234px;" src="http://3.bp.blogspot.com/-7XbyRvBwd8c/Tpc-c0ZqgdI/AAAAAAAAAFI/DR8tsH4FH7w/s320/oracle-jdk7-mac-prefs.png" alt="" id="BLOGGER_PHOTO_ID_5663063721265234386" border="0" /&gt;&lt;/a&gt;&lt;pre&gt;much$ /usr/libexec/java_home --version 1.7&lt;br /&gt;/Library/Java/JavaVirtualMachines/JDK 1.7.0 Developer Preview.jdk/Contents/Home&lt;br /&gt;&lt;br /&gt;much$ /usr/libexec/java_home -v 1.7 --exec java -version&lt;br /&gt;openjdk version "1.7.0-ea"&lt;br /&gt;OpenJDK Runtime Environment (build 1.7.0-ea-b211)&lt;br /&gt;OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode)&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-294990331925729017?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/294990331925729017/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/10/oracle-jdk7-fur-mac-os-x-developer.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/294990331925729017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/294990331925729017'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/10/oracle-jdk7-fur-mac-os-x-developer.html' title='Oracle JDK7 für Mac OS X (Developer Preview)'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-2h0Oge3GIR4/Tpc8oK1UsBI/AAAAAAAAAE8/Y6XGn_604Tc/s72-c/oracle-jdk7-mac-ea.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-6600537840842094787</id><published>2011-05-12T20:49:00.001+02:00</published><updated>2011-05-23T20:42:22.354+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Scala 2.9 und Akka 1.1</title><content type='html'>Ein halbes Jahr nach der letzten Version wurde heute &lt;a href="http://www.scala-lang.org/downloads"&gt;Scala 2.9&lt;/a&gt; veröffenticht.&lt;br /&gt;&lt;br /&gt;Wichtigste Neuerung sind sicherlich die parallelen Kollektionen, die z.B. beim Sortieren, Filtern und Durchlaufen automatisch mehrere Prozessorkerne nutzen. Sofern die dabei ausgeführten Funktionen hinreichend komplex sind, lassen sich durch die Parallelisierung deutliche Geschwindigkeitssteigerungen erreichen. "Normale" sequentielle Kollektionen lassen sich mit einem Methodenaufruf in eine parallele Kollektion umwandeln und umgekehrt.&lt;br /&gt;&lt;br /&gt;Hilfreich für die alltägliche Programmierung ist auch der neue &lt;code&gt;App&lt;/code&gt;-Trait, der den veralteten, nicht so mächtigen und teilweise problematischen &lt;code&gt;Application&lt;/code&gt;-Trait ablöst. Mit dem &lt;code&gt;App&lt;/code&gt;-Trait lässt sich auf einfache und elegante Weise der Programm-Einstiegspunkt schreiben – er ist also eine Vereinfachung der &lt;code&gt;main&lt;/code&gt;-Methode (die man aber immer noch von Hand programmieren kann).&lt;br /&gt;&lt;br /&gt;Diese und viele weitere kleine Verbesserungen sind genauer in der &lt;a href="http://www.scala-lang.org/node/9483"&gt;Ankündigung der neuen Version 2.9&lt;/a&gt; beschrieben.&lt;br /&gt;&lt;br /&gt;Zeitgleich wurde die Gründung der Firma &lt;a href="http://typesafe.com/"&gt;Typesafe&lt;/a&gt; bekannt gegeben, in der sich die Gründer und Entwickler von &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; und &lt;a href="http://akka.io/"&gt;Akka&lt;/a&gt; zusammentun, um Dienstleistungen rund um die Scala-Technologie anzubieten. Als Berater stehen dieser neuen Firma recht bekannte Java-Größen wie James Gosling und Doug Lea zur Seite. Neben Dienstleistungen bietet Typesafe den &lt;a href="http://typesafe.com/stack"&gt;Typesafe Stack&lt;/a&gt; an, ein vorkonfiguriertes Paket mit Scala 2.9 und Akka 1.1.&lt;br /&gt;&lt;br /&gt;Akka ist eine Ereignis-gesteuertes Rahmenwerk, mit dem sich verteilte Anwendungen entwickeln lassen. Die Geschäftslogik bleibt dabei frei von den technischen Aspekten der Parallelisierung, Kommunikation, Ausfallsicherheit etc. – ideal für typische Server-Anwendungen. Bekannt geworden ist Akka durch die eigenen, hochskalierbaren und robusten Aktoren (Actors).&lt;br /&gt;&lt;br /&gt;Im Typesafe Stack 1.0 sind sowohl die Aktoren von Scala als auch die von Akka mit ihrer bisherigen Funktionalität enthalten. Für zukünftige Scala-Versionen ist aber wohl geplant, diese Funktionalitäten zusammenzuführen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-6600537840842094787?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/6600537840842094787/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/05/scala-29-und-akka-11.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6600537840842094787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6600537840842094787'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/05/scala-29-und-akka-11.html' title='Scala 2.9 und Akka 1.1'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-1567544865952527153</id><published>2011-03-20T21:28:00.007+01:00</published><updated>2011-05-03T09:52:52.822+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Funktionale Programmierung'/><title type='text'>Monaden in Scala</title><content type='html'>Am vergangenen Wochenende habe ich beim &lt;a href="http://www.mathema.de/events/campus/"&gt;MATHEMA Campus 2011&lt;/a&gt; einen Vortrag über &lt;a href="http://www.mathema.de/events/campus/inhalte/#T7"&gt;Monaden in Scala&lt;/a&gt; gehalten (Folien &lt;a href="http://www.muchsoft.com/publikationen.html#talks"&gt;hier&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://de.wikipedia.org/wiki/Monade_%28Typkonstruktion%29"&gt;Monaden&lt;/a&gt; sind ein etwas sperriges Konzept, das in rein funktionalen Sprachen wie &lt;a href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt; u.a. für eine vernünftige Ein-/Ausgabeprogrammierung notwendig ist. Für &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; sind Monaden vielleicht nicht ganz so wichtig, aber auch mit Scala kann man sinnvoll monadisch programmieren – und das Schöne daran: Über die ganze komplizierte &lt;a href="http://de.wikipedia.org/wiki/Monade_%28Kategorientheorie%29"&gt;mathematische Theorie&lt;/a&gt; dahinter muss man sich keine Gedanken machen. Im Gegenteil, wer schonmal ein bisschen Scala programmiert hat, wird dabei vermutlich (unbewusst) auch Monaden genutzt haben.&lt;br /&gt;&lt;br /&gt;Was sind diese Monaden? Ein abstrakter Datentyp für verkettbare Berechnungen mit folgenden Eigenschaften:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ein Typkonstruktor wie &lt;code&gt;List[A]&lt;/code&gt; (mit z.B. &lt;code&gt;List[Int]&lt;/code&gt; als Ausprägung).&lt;/li&gt;&lt;li&gt;Eine Funktion, um einen Wert im Typ "einzuwickeln". Das kann der Konstruktor sein, z.B. &lt;code&gt;new List(1)&lt;/code&gt; bzw. &lt;code&gt;List(1)&lt;/code&gt;, aber häufig wird diese Funktion &lt;code&gt;return&lt;/code&gt;, &lt;code&gt;unit&lt;/code&gt;, &lt;code&gt;lift&lt;/code&gt; oder &lt;code&gt;pure&lt;/code&gt; genannt.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Eine Funktion, um die enthaltenen Werte zu verrechnen, aber nach der Berechnung im Typ verpackt zu lassen. Übliche Namen sind &lt;code&gt;bind&lt;/code&gt; oder (in Scala) &lt;code&gt;flatMap&lt;/code&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Die Monadengesetze müssen von den Funktionen eingehalten werden, aber das lassen wir mal außen vor. Klingt kompliziert? Schauen wir uns das in der Praxis an:&lt;br /&gt;&lt;pre&gt;case class MiniMonade[A](wert:A) {&lt;br /&gt;&lt;br /&gt;  def flatMap[B](f: A =&gt; MiniMonade[B]) = f(wert)&lt;br /&gt;&lt;br /&gt;  def map[B](f: A =&gt; B): MiniMonade[B]&lt;br /&gt;     = MiniMonade(f(wert))&lt;br /&gt;}&lt;/pre&gt;Die Mini-Monade soll also genau einen Wert des generischen Typs "A" speichern und verarbeiten können. Listen sind auch Monaden und können entsprechend beliebig viele Werte verarbeiten. In unserer Monade ist zusätzlich noch die Funktion &lt;code&gt;map&lt;/code&gt; implementiert, damit wir Objekte dieser Klasse in den &lt;a href="http://en.wikipedia.org/wiki/List_comprehension#Scala"&gt;for-Comprehensions&lt;/a&gt; von Scala einsetzen können. Und genau das ist auch der häufigste Anwendungsfall für Monaden in Scala:&lt;br /&gt;&lt;pre&gt;val m1 = MiniMonade(2)&lt;br /&gt;val m2 = MiniMonade(3)&lt;br /&gt;&lt;br /&gt;val erg = for { x &lt;- m1; y &lt;- m2 } yield x*y;&lt;br&gt;&lt;br&gt;println( erg )&lt;/pre&gt;In dieser for-Comprehension werden alle Werte aus den beiden Monaden-Objekten miteinander mit x*y verrechnet und landen anschließend (durch die Magie der Monaden-Funktionen) wieder in einem Monaden-Objekt. Da unsere Objekte jeweils nur einen Wert speichern, wird nur 2*3 berechnet:&lt;br /&gt;&lt;pre&gt;HeartOfGold:~ much$ scala MiniMonade.scala&lt;br /&gt;MiniMonade(6)&lt;/pre&gt;Das scheint unnötig viel Aufwand für eine simple Multiplikation zu sein... Aber folgendes Beispiel dürfte – so oder in ähnlicher Form – jeder schonmal programmiert haben, und das ergibt sicher mehr Sinn:&lt;br /&gt;&lt;pre&gt;val zeilen = List(10,20)&lt;br /&gt;val spalten = List(1,2)&lt;br /&gt;&lt;br /&gt;val summen = for {z &lt;- zeilen; s &lt;- spalten} yield z+s;&lt;br&gt;&lt;br&gt;println( summen )&lt;br /&gt;// List(11, 12, 21, 22)&lt;/pre&gt;Andere gebräuchliche monadische Typen sind (neben vielen weiteren) Map und Option, und alle diese Klassen können in einer for-Comprehension kombiniert werden.&lt;br /&gt;&lt;br /&gt;Die Verwendbarkeit in for-Comprehensions ist in Scala sicherlich der wichtigste Grund, warum man geeignete eigene Klassen monadisch machen sollte. Würden wir noch &lt;a href="http://www.scala-lang.org/api/current/scala/collection/generic/FilterMonadic.html"&gt;withFilter und foreach&lt;/a&gt; implementieren, könnten wir unsere Monade außerdem in weiteren for-Varianten einsetzen.&lt;br /&gt;&lt;br /&gt;Beim diesjährigen &lt;a href="http://www.herbstcampus.de/hc11/program/sessions.html#16"&gt;Herbstcampus&lt;/a&gt; werde ich einen Einsteiger-Vortrag (OO-Vorkenntnisse reichen) zu diesem Thema halten.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-1567544865952527153?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/1567544865952527153/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/03/monaden-in-scala.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1567544865952527153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1567544865952527153'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/03/monaden-in-scala.html' title='Monaden in Scala'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-3279617708166606189</id><published>2011-02-09T20:44:00.009+01:00</published><updated>2011-02-09T21:39:34.755+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>Freie Icons für Web-Oberflächen</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1bA4Fk08GL0/TVLxzq58ImI/AAAAAAAAAEw/bBd14aanjYc/s1600/fff-icons.png"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 202px; height: 323px;" src="http://3.bp.blogspot.com/_1bA4Fk08GL0/TVLxzq58ImI/AAAAAAAAAEw/bBd14aanjYc/s400/fff-icons.png" alt="" id="BLOGGER_PHOTO_ID_5571781559003652706" border="0" /&gt;&lt;/a&gt;Gute Web-Oberflächen zeichnen sich nicht nur durch durchdachte, einfach zu verstehende HTML-Formulare aus. Sie sollten auch ansprechend – "schön" – aussehen, weil die Benutzer dann garantiert lieber mit der Web-Anwendung arbeiten als mit lieblos gestalteten Seiten.&lt;br /&gt;&lt;br /&gt;Ein wichtiger Aspekt dabei sind klar gestaltete Symbolgrafiken (Icons) – sei es für Status-Anzeigen oder für Schaltflächen. Wenn man künstlerisch nur eingeschränkt begabt ist, greift man besser auf fertige Grafiken zurück, als langweilige und schlecht zu erkennende Symbole selber zusammenzupixeln.&lt;br /&gt;&lt;br /&gt;Seit langer Zeit nutze ich daher immer wieder gerne die &lt;a href="http://www.famfamfam.com/lab/icons/"&gt;famfamfam-Icons&lt;/a&gt; von Mark James. Die &lt;a href="http://www.famfamfam.com/lab/icons/mini/"&gt;Mini&lt;/a&gt;- und &lt;a href="http://www.famfamfam.com/lab/icons/flags/"&gt;Flaggen&lt;/a&gt;-Icons sind dabei komplett &lt;a href="http://de.wikipedia.org/wiki/Gemeinfreiheit#Public_Domain"&gt;Public Domain&lt;/a&gt;, können also beliebig verwendet werden. Und auch die 1000 &lt;a href="http://www.famfamfam.com/lab/icons/silk/"&gt;Silk&lt;/a&gt;-Icons stehen kostenfrei selbst für kommerzielle Anwendungen zur Verfügung. Der Autor bietet sie unter der &lt;a href="http://creativecommons.org/licenses/by/2.5/"&gt;Creative Commons Attribution 2.5&lt;/a&gt;-Lizenz an (wahlweise auch unter der Lizenz-Version 3.0) und verlangt lediglich einen Link auf seine Web-Seite.&lt;br /&gt;&lt;br /&gt;Vielen Dank für die Blumen – äh – Icons!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-3279617708166606189?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/3279617708166606189/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/02/freie-icons-fur-web-oberflachen.html#comment-form' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3279617708166606189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3279617708166606189'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/02/freie-icons-fur-web-oberflachen.html' title='Freie Icons für Web-Oberflächen'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_1bA4Fk08GL0/TVLxzq58ImI/AAAAAAAAAEw/bBd14aanjYc/s72-c/fff-icons.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-7072459933422534981</id><published>2011-01-14T20:07:00.003+01:00</published><updated>2011-01-14T20:17:51.151+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenJDK'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>OpenJDK 7 für Mac OS X</title><content type='html'>Nachdem Apple &lt;a href="http://javabarista.blogspot.com/2010/11/oracle-bringt-java-se-7-fur-mac-os-x.html"&gt;vor knapp zwei Monaten&lt;/a&gt; Unterstützung für das &lt;a href="http://openjdk.java.net/"&gt;OpenJDK&lt;/a&gt;-Projekt angekündigt hatte, wurde die &lt;a href="http://openjdk.java.net/projects/macosx-port/"&gt;Mac OS X-Portierung&lt;/a&gt;  am Montag dieser Woche als offizielles OpenJDK-Projekt angenommen – und nur &lt;a href="http://lists.apple.com/archives/java-dev/2011/Jan/msg00065.html"&gt;einen Tag später&lt;/a&gt; hat Apple den ersten offenen Code in das Projekt eingebracht. Im Wesentlichen entspricht diese erste Veröffentlichung der &lt;a href="http://openjdk.java.net/projects/bsd-port/"&gt;BSD-Portierung&lt;/a&gt;. Apple hat derzeit nur den Build-Prozess verändert, um ein Universal Binary mit einem .jdk-Bundle zu erzeugen, das zur neuen Java-Verzeichnisstruktur von Mac OS X passt (und entsprechend nach der Installation automatisch erkannt wird).&lt;br /&gt;&lt;br /&gt;Jeder kann nun zum Mac OS X-Port beitragen und sich das aktuellste OpenJDK aus den Quelltexten bauen. Voraussetzung dafür sind u.a. Mac OS X ab Version 10.6.5 sowie Xcode ab Version 3.2.5. Genaueres ist im &lt;a href="http://wikis.sun.com/display/OpenJDK/Mac+OS+X+Port"&gt;Wiki&lt;/a&gt; beschrieben; dort kann man auch den aktuellen &lt;a href="http://wikis.sun.com/display/OpenJDK/Mac+OS+X+Port+Project+Status"&gt;Projekt-Status&lt;/a&gt; einsehen.&lt;br /&gt;&lt;br /&gt;Wer das JDK 7 einfach ausprobieren möchte, ohne es selber bauen zu müssen, kann sich ein fertiges DMG von &lt;a href="http://code.google.com/p/openjdk-osx-build/"&gt;Google Code&lt;/a&gt; herunterladen. Der &lt;a href="http://openjdk-osx-build.googlecode.com/files/OpenJDK-OSX-1.7-x86_64-2011011.dmg"&gt;Installer&lt;/a&gt; für den Mac OS X-Branch enthält sowohl eine 32- als auch eine 64-Bit-JVM. Nach der schnellen und vollkommen unproblematischen Installation kann man das JDK 7 mit den üblichen Kommandos im Terminal testen:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;much$ /usr/libexec/java_home --version 1.7&lt;br /&gt;/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home&lt;br /&gt;&lt;br /&gt;much$ export JAVA_HOME=`/usr/libexec/java_home -v 1.7`&lt;br /&gt;much$ $JAVA_HOME/bin/java -version&lt;br /&gt;openjdk version "1.7.0-internal"&lt;br /&gt;OpenJDK Runtime Environment (build 1.7.0-internal-b00)&lt;br /&gt;OpenJDK 64-Bit Server VM (build 20.0-b03, mixed mode)&lt;br /&gt;&lt;br /&gt;much$ /usr/libexec/java_home -v 1.7 --exec java -version&lt;br /&gt;openjdk version "1.7.0-internal"&lt;br /&gt;OpenJDK Runtime Environment (build 1.7.0-internal-b00)&lt;br /&gt;OpenJDK 64-Bit Server VM (build 20.0-b03, mixed mode)&lt;/pre&gt;&lt;br /&gt;Für grafische Frontends wird noch kein Cocoa, sondern nur X11 unterstützt. Zum Ausprobieren der neuen Sprachfeaturen (Strings im &lt;code&gt;switch&lt;/code&gt; etc.) reicht das aber vollkommen aus.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_1bA4Fk08GL0/TTCfwZCkBgI/AAAAAAAAAEc/Wc69HCPNw1Q/s1600/javaprefs-openjdk7.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 230px;" src="http://4.bp.blogspot.com/_1bA4Fk08GL0/TTCfwZCkBgI/AAAAAAAAAEc/Wc69HCPNw1Q/s320/javaprefs-openjdk7.png" alt="" id="BLOGGER_PHOTO_ID_5562121193506735618" border="0" /&gt;&lt;/a&gt;Wie bereits erwähnt wird das OpenJDK 7 automatisch von den Java-Einstellungen in Mac OS X erkannt. Wegen der noch unvollständigen Cocoa- bzw. Mac OS X-Integration sollte man die neue Version aber noch nicht als Default setzen, d.h. besser am Ende der Liste belassen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-7072459933422534981?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/7072459933422534981/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2011/01/openjdk-7-fur-mac-os-x.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7072459933422534981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7072459933422534981'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2011/01/openjdk-7-fur-mac-os-x.html' title='OpenJDK 7 für Mac OS X'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_1bA4Fk08GL0/TTCfwZCkBgI/AAAAAAAAAEc/Wc69HCPNw1Q/s72-c/javaprefs-openjdk7.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-5492842485283596267</id><published>2010-11-30T21:39:00.005+01:00</published><updated>2010-11-30T21:48:00.357+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='VisualVM'/><title type='text'>VisualVM 1.3.x statt Eclipse TPTP?</title><content type='html'>Vor zwei Wochen wurde &lt;a href="http://www.eclipse.org/tptp/home/project_info/devplans/EclipseTPTPProjectPlan2010.htm"&gt;bekannt gegeben&lt;/a&gt;, dass das Eclipse-Projekt für Test- und Performance-Werkzeuge – &lt;a href="http://www.eclipse.org/tptp/"&gt;TPTP&lt;/a&gt; – nach dem kommenden Update auf Version 4.7.2 (geplant für Februar 2011) nicht mehr weiterentwickelt wird.&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Einer der Aspekte, die mir an TPTP gefallen haben, war das &lt;a href="http://www.eclipse.org/tptp/platform/documents/probekit/probekit.html"&gt;Probekit&lt;/a&gt;, mit dem man kleine Java-Schnipsel an bestimmte Stellen einer Java-Klasse (Methoden-Ein- und -Ausgang etc.) einweben lassen konnte, um die Klassen zur Laufzeit genauer zu untersuchen.&lt;br /&gt;&lt;br /&gt;Ein möglicher Ersatz steht schon in den Startlöchern. Mitte des Jahres wurde &lt;a href="https://visualvm.dev.java.net/"&gt;VisualVM 1.3&lt;/a&gt; veröffentlicht, das mittlerweile in der Version 1.3.1 verfügbar ist. Darin enthalten ist das Tracer-Plugin, mit dem sich diverse "Probes" für eine laufende Anwendung aktivieren lassen, die dann synchron untereinander auf einer Zeitleiste dargestellt werden:&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_1bA4Fk08GL0/TO-4LnQoMRI/AAAAAAAAAEQ/DJAakRAG-A8/s1600/vvm13-tracer.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 197px;" src="http://4.bp.blogspot.com/_1bA4Fk08GL0/TO-4LnQoMRI/AAAAAAAAAEQ/DJAakRAG-A8/s320/vvm13-tracer.png" alt="" id="BLOGGER_PHOTO_ID_5543852175973167378" border="0" /&gt;&lt;/a&gt;Derzeit gibt es nur vordefinierte Probes für Swing, JavaFX sowie für diverse weitere Pakete der Standard-Klassenbibliothek (Collections, I/O etc.). Das Tracer-Framework soll sich aber einfach mit eigenen Probes erweitern lassen (auch wenn ich noch keinen Link zu einer aktuellen &lt;a href="https://visualvm.dev.java.net/plugins.html#write_plugin"&gt;Entwickler-Dokumentation&lt;/a&gt; gefunden habe) – und vielleicht gibt es ja in absehbarer Zeit eine Probe zum AOP-mäßigen Einweben von kleinen Code-Stücken? Dieser Wunsch muss erlaubt sein, schließlich ist ja bald Weihnachten :-)&lt;br /&gt;&lt;br /&gt;Ob man VisualVM separat herunterladen muss oder ob es im installierten JDK bereits enthalten ist, kann man auf der &lt;a href="https://visualvm.dev.java.net/releases.html"&gt;Release-Übersicht&lt;/a&gt; herausfinden. Das aktuelle Java 6 Update 22 bringt leider immer noch die ältere VisualVM-Version 1.2.2 mit.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-5492842485283596267?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/5492842485283596267/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/11/visualvm-13x-statt-eclipse-tptp.html#comment-form' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/5492842485283596267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/5492842485283596267'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/11/visualvm-13x-statt-eclipse-tptp.html' title='VisualVM 1.3.x statt Eclipse TPTP?'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_1bA4Fk08GL0/TO-4LnQoMRI/AAAAAAAAAEQ/DJAakRAG-A8/s72-c/vvm13-tracer.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-5555771947313215463</id><published>2010-11-15T18:07:00.003+01:00</published><updated>2010-11-15T18:18:34.586+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenJDK'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Oracle bringt Java SE 7 für Mac OS X</title><content type='html'>... und Apple wird auch in Mac OS X 10.7 "Lion" noch die eigene Java SE 6-Implementation bereitstellen. Das sind kurz zusammengefasst die Ergebnisse der letzten Tage.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://openjdk.java.net/"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 220px; height: 60px;" src="http://openjdk.java.net/images/openjdk.png" alt="" border="0" /&gt;&lt;/a&gt;Nachdem es vor drei Wochen &lt;a href="http://javabarista.blogspot.com/2010/10/deprecated-java-fur-mac-os-x.html"&gt;recht düster&lt;/a&gt; für die Zukunft von Java auf Mac OS X ausgesehen hatte, weil Apple die eigene Java-Implementierung abgekündigt, aber keinen Ersatz als Perspektive geboten hatte, sieht es nun so aus, als ob wir genau die Lösung bekommen, die von vielen favorisiert wurde: Apple bringt die meisten Teile seiner Java-Implementation als Open Source in das &lt;a href="http://openjdk.java.net/"&gt;OpenJDK&lt;/a&gt;-Projekt ein, und Oracle wird daraus – beginnend mit Java SE 7 – offizielle Java-Releases für Mac OS X bauen.&lt;br /&gt;&lt;br /&gt;Es ist noch nicht ganz klar, &lt;a href="http://blogs.oracle.com/henrik/2010/11/oracle_and_apple_announce_openjdk_project_for_osx.html"&gt;wann&lt;/a&gt; Java SE 7 für Mac OS X verfügbar sein wird und &lt;a href="http://lists.apple.com/archives/Java-dev/2010/Nov/msg00104.html"&gt;wie&lt;/a&gt; die Quelltexte im Detail zur Verfügung gestellt werden. Aber die Zukunft für Java auf Mac OS X dürfte damit sichergestellt sein.&lt;br /&gt;&lt;br /&gt;Nebenbei hat Apple in der &lt;a href="http://www.apple.com/pr/library/2010/11/12openjdk.html"&gt;Pressemitteilung&lt;/a&gt; bekannt gegeben, dass auch das im nächsten Jahr erscheinende Mac OS X 10.7 "Lion" noch die eigene Java SE 6-Implementation enthalten wird, so dass für die Übergangszeit auf Oracles Mac-Java-Implementation eine klare Perspektive besteht.&lt;br /&gt;&lt;br /&gt;Na also. Warum denn nicht gleich so?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-5555771947313215463?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/5555771947313215463/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/11/oracle-bringt-java-se-7-fur-mac-os-x.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/5555771947313215463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/5555771947313215463'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/11/oracle-bringt-java-se-7-fur-mac-os-x.html' title='Oracle bringt Java SE 7 für Mac OS X'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-7677513674071177465</id><published>2010-11-11T21:35:00.003+01:00</published><updated>2010-11-11T22:01:09.787+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Scala 2.8.1</title><content type='html'>Vorgestern wurde mit nur wenigen Tagen Verspätung &lt;a href="http://www.scala-lang.org/node/8102"&gt;Scala 2.8.1&lt;/a&gt; freigegeben.&lt;br /&gt;&lt;br /&gt;Neben zahlreichen Bugfixes enthält das Update vor allem eine verbesserte Version von &lt;a href="http://lampsvn.epfl.ch/trac/scala/wiki/Scaladoc"&gt;Scaladoc&lt;/a&gt;. Ein Ergebnis dieses &lt;a href="http://www.scala-lang.org/docu/files/tools/scaladoc.html"&gt;Werkzeugs&lt;/a&gt; ist beispielsweise die API-Dokumentation der &lt;a href="http://www.scala-lang.org/api/current/"&gt;Scala-Standard-Bibliothek&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Scala 2.8.1 ist vollständig binärkompatibel mit der vorangegangenen Version 2.8.0 (was davor durchaus nicht selbstverständlich war, nun aber erklärtes Ziel zur Stabilisierung der Softwareentwicklung mit Scala ist).&lt;br /&gt;&lt;br /&gt;Seit heute liegt außerdem die &lt;a href="http://www.scala-ide.org/"&gt;Scala IDE für Eclipse&lt;/a&gt; in einer aktualisierten Version vor. Durch die Binärkompatibilität der Scala 2.8.x-Versionen kann man erstmalig die neueste Scala IDE einsetzen und damit bestehende Projekte wahlweise weiterhin mit Scala 2.8.0 übersetzen, bis eine Umstellung auf 2.8.1 geeignet erscheint.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-7677513674071177465?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/7677513674071177465/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/11/scala-281.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7677513674071177465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7677513674071177465'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/11/scala-281.html' title='Scala 2.8.1'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-6100885700862544132</id><published>2010-10-21T22:11:00.001+02:00</published><updated>2010-10-21T22:46:54.896+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>@Deprecated Java für Mac OS X</title><content type='html'>Es musste ja irgendwann passieren: Nachdem schon Flash in Ungnade gefallen war, hat Apple nun keine Lust mehr auf Java...&lt;br /&gt;&lt;br /&gt;In den &lt;a href="http://developer.apple.com/library/mac/#releasenotes/Java/JavaSnowLeopardUpdate3LeopardUpdate8RN/NewandNoteworthy/NewandNoteworthy.html"&gt;Release Notes&lt;/a&gt; zum gestern erschienenen "&lt;a href="http://support.apple.com/downloads/Java_for_Mac_OS_X_10_6_Update_3"&gt;Java for Mac OS X 10.6 Update 3&lt;/a&gt;", das Java SE 6 auf Version 1.6.0_22 aktualisiert, findet sich an prominenter Stelle der Hinweis, dass Apples eigene Java-Implementation ab sofort als veraltete Technologie gilt und in &lt;a href="http://www.apple.com/de/macosx/lion/"&gt;künftigen Mac OS X-Versionen&lt;/a&gt; fehlen könnte.&lt;br /&gt;&lt;br /&gt;Auch wenn direkt unter dieser Ankündigung beschrieben ist, dass und wie mit diesem Update Java Virtual Machines (JVMs) anderer Hersteller leichter ins System eingebunden werden können (was ich in einem folgenden Blog-Eintrag beschreibe) und auch die exakte Wortwahl der Apple-Java-Abkündigung fast impliziert, dass ein anderer Hersteller in die Bresche springen wird – gesichert ist dies nicht.&lt;br /&gt;&lt;br /&gt;Bis also Oracle oder IBM oder irgendwer sonst (Google?) offiziell bekannt gibt, dass sie eine Java-Implementierung für Mac OS X anbieten werden, müssen wir leider davon ausgehen, dass Java auf dem Mac tot ist.&lt;br /&gt;&lt;br /&gt;Dies dürfte extrem negative Auswirkungen auf den Einsatz von Macs in Unternehmen haben, da dort Java-Anwendungen häufig in der einen oder anderen Form benötigt werden. Ebenso wird der Mac damit für Bildungseinrichtungen und insbesondere Hochschulen uninteressant, da dort oft Java als Lehrsprache eingesetzt wird. Und die Java-Entwickler-Gemeinde, in der sich (zumindest gefühlt) überdurchschnittlich viele Mac-Anwender befinden, wird sich neue Hardware-Investitionen und Upgrades auf kommende Mac OS X-Versionen gut überlegen.&lt;br /&gt;&lt;br /&gt;Zu hoffen bleibt, dass die Ankündigung nur eine Kommunikations-Katastrophe mit schlechtem Timing war. Andererseite werden, sofern man diversen &lt;a href="http://www.appleinsider.com/articles/10/10/20/apple_issues_review_guidelines_for_mac_app_store.html"&gt;Internet-Quellen&lt;/a&gt; glauben darf, Java-Anwendungen für den kommende "Mac App Store" nicht akzeptiert werden, da es sich um veraltete Technologie handelt. Und das sieht dann schon eher nach Absicht aus...&lt;br /&gt;&lt;br /&gt;Abwarten und Kaffee trinken.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-6100885700862544132?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/6100885700862544132/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/10/deprecated-java-fur-mac-os-x.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6100885700862544132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6100885700862544132'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/10/deprecated-java-fur-mac-os-x.html' title='@Deprecated Java für Mac OS X'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-83443725031107341</id><published>2010-10-14T12:50:00.004+02:00</published><updated>2010-10-14T13:01:37.558+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Hibernate 3.6 mit performanterem Envers und ohne Java 1.4</title><content type='html'>Gestern gab es das zweite, große Hibernate-Release in diesem Jahr: &lt;a href="http://in.relation.to/Bloggers/HibernateCore360FinalRelease"&gt;Hibernate 3.6&lt;/a&gt;. So kurz nach Hibernate 3.5, das vor allem die JPA 2.0-Kompatibilität brachte, bringt die neue Version nicht sehr viele neue Features mit, sondern hat vor allem dringend notwendige interne Änderungen und Re-Implementierungen erfahren:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Java 1.4 wird nicht mehr unterstützt, Voraussetzung ist nun also Java 5.0 und neuer.&lt;/li&gt;&lt;li&gt;Das interne Typsystem wurde überarbeitet. Vor allem Implementierungen &lt;a href="http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/usertype/UserType.html"&gt;benutzerdefinierter Mapping-Typen&lt;/a&gt; müssen nun vermutlich angepasst werden.&lt;/li&gt;&lt;li&gt;Wer XML-Mappings verwendet, sollte die DTDs von &lt;span style="font-style: italic;"&gt;http://hibernate.sourceforge.net/&lt;/span&gt; auf &lt;span style="font-style: italic;"&gt;http://www.hibernate.org/dtd&lt;/span&gt; umstellen.&lt;/li&gt;&lt;li&gt;Und schließlich enthält das mitgelieferte &lt;a href="http://www.jboss.org/envers/"&gt;Envers&lt;/a&gt; eine neue Audit-Strategie, &lt;a href="http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/envers/strategy/ValidityAuditStrategy.html"&gt;ValidityAuditStrategy&lt;/a&gt;. Damit kann nun nicht nur der Anfangszeitpunkt einer Revision gespeichert werden, sondern auch der Endzeitpunkt. Während das Speichern dadurch etwas mehr Zeit und eine zusätzliche Spalte in der Datenbank-Tabelle benötigt, wird das Lesen historischer Daten deutlich performanter.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-83443725031107341?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/83443725031107341/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/10/hibernate-36-mit-performanterem-envers.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/83443725031107341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/83443725031107341'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/10/hibernate-36-mit-performanterem-envers.html' title='Hibernate 3.6 mit performanterem Envers und ohne Java 1.4'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-8347551919870215161</id><published>2010-10-07T21:27:00.001+02:00</published><updated>2010-10-07T21:29:03.283+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Scala-Roadmap, -Literatur u.a.</title><content type='html'>Es tut sich was im &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;-Universum. Laut &lt;a href="http://www.scala-lang.org/node/7285"&gt;Roadmap&lt;/a&gt; soll noch in diesem Monat Version 2.8.1 veröffentlicht werden. Zeitlich sieht es gut aus, denn die Version liegt bereits als zweiter &lt;a href="http://www.scala-lang.org/downloads#RC"&gt;Release Candidate&lt;/a&gt; vor. Mit diesem kleinen Update werden hauptsächlich Fehler beseitigt, die sich durch die starken internen Änderungen beim Sprung auf Version 2.8 eingeschlichten hatten.&lt;br /&gt;&lt;br /&gt;Das nächste größere Update wird Scala 2.9 sein, das für Anfang kommenden Jahres geplant ist. Darin sollen vor allem parallele Kollektionen enthalten sein.&lt;br /&gt;&lt;br /&gt;Um Firmen bei der Einführung von Scala und bei der Migration von älteren Scala-Versionen zu unterstützen, hat &lt;a href="http://en.wikipedia.org/wiki/Martin_Odersky"&gt;Martin Odersky&lt;/a&gt;, der Erfinder der Sprache, vor kurzem &lt;a href="http://www.scalasolutions.com/"&gt;Scala Solutions&lt;/a&gt; gegründet. Ein guter und notwendiger Schritt, damit Scala im kommerziellen Umfeld die Akzeptanz findet, die diese Sprache verdient! (Scala-Workshops kann man natürlich auch &lt;a href="http://www.muchsoft.com/coaching.html#training"&gt;anderswo&lt;/a&gt; buchen ;-)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_1bA4Fk08GL0/TK4YX8fgvLI/AAAAAAAAAEI/Kt0KdHm91BQ/s1600/9783836216692.gif"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 184px; height: 167px;" src="http://4.bp.blogspot.com/_1bA4Fk08GL0/TK4YX8fgvLI/AAAAAAAAAEI/Kt0KdHm91BQ/s320/9783836216692.gif" alt="" id="BLOGGER_PHOTO_ID_5525380592484531378" border="0" /&gt;&lt;/a&gt;Und noch ein bisschen Werbung in eigener Sache: Der Galileo-Verlag hat heute mein Buch "&lt;a href="http://www.galileocomputing.de/2464?GPP=much"&gt;Scala. Der Schnelleinstieg für Entwickler.&lt;/a&gt;" angekündigt, das im kommenden Jahr erscheinen wird. Bis zur Veröffentlichung bleibt noch genug zu tun, aber es macht Spaß, nach über fünf Jahren mal wieder ein Buch entstehen zu sehen :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-8347551919870215161?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/8347551919870215161/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/10/scala-roadmap-literatur-ua.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/8347551919870215161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/8347551919870215161'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/10/scala-roadmap-literatur-ua.html' title='Scala-Roadmap, -Literatur u.a.'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_1bA4Fk08GL0/TK4YX8fgvLI/AAAAAAAAAEI/Kt0KdHm91BQ/s72-c/9783836216692.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-4085992596310519382</id><published>2010-09-28T17:09:00.001+02:00</published><updated>2010-09-30T16:29:39.270+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Annotationen'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>Eclipse 3.6 und @SuppressWarnings("unchecked")</title><content type='html'>&lt;a href="http://www.eclipse.org/downloads/packages/release/helios/sr1"&gt;Eclipse 3.6&lt;/a&gt; ist schon seit einiger Zeit auf dem Markt, aber die ganzen neuen kleinen Features entdeckt man oft erst nach und nach.&lt;br /&gt;&lt;br /&gt;Ergänzend zu einem &lt;a href="http://javabarista.blogspot.com/2009/04/suppresswarningsunchecked.html"&gt;früheren Posting&lt;/a&gt; habe ich gerade gesehen, dass die "Quick Fix"-Funktion bei einer "Type safety"-Warnung nun nach Möglichkeit anbietet, die passende Annotation direkt an die Variablendeklaration zu schreiben (und nicht nur über die gesamte Methode):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_1bA4Fk08GL0/TKSdnShoOpI/AAAAAAAAAEA/RzjGOiNVUJc/s1600/suppresswarningslocal.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 82px;" src="http://4.bp.blogspot.com/_1bA4Fk08GL0/TKSdnShoOpI/AAAAAAAAAEA/RzjGOiNVUJc/s320/suppresswarningslocal.png" alt="" id="BLOGGER_PHOTO_ID_5522712341376416402" border="0" /&gt;&lt;/a&gt;Nett!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-4085992596310519382?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/4085992596310519382/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/09/eclipse-36-und-suppresswarningsunchecke.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4085992596310519382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4085992596310519382'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/09/eclipse-36-und-suppresswarningsunchecke.html' title='Eclipse 3.6 und @SuppressWarnings(&quot;unchecked&quot;)'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_1bA4Fk08GL0/TKSdnShoOpI/AAAAAAAAAEA/RzjGOiNVUJc/s72-c/suppresswarningslocal.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-2504540422782280046</id><published>2010-07-31T12:22:00.008+02:00</published><updated>2010-08-01T18:54:51.026+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ant'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Ant Filter-Copy-Task und Zeichenkodierung</title><content type='html'>Ein Eintrag aus der Rubrik "kleiner Fehler, große Wirkung": Resource-&lt;a href="http://de.wikipedia.org/wiki/Java-Properties-Datei"&gt;Properties&lt;/a&gt;-Dateien wurden für eine Web-Anwendung mit einem &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt;-Skript aus den Projektordnern in die passenden Ordner der &lt;a href="http://de.wikipedia.org/wiki/Web_Archive"&gt;Web-Applikation&lt;/a&gt; umkopiert. Bei manchen Properties-Dateien wurden die darin enthaltenen Umlaute im Browser manchmal (je nach Applikations-Server und je nach Rechner, auf dem die Web-Anwendung gebaut wurde) falsch dargestellt.&lt;br /&gt;&lt;br /&gt;Ursache des Problems war ein &lt;code&gt;copy&lt;/code&gt;-Task, der die Datei nicht 1:1 umkopiert, sondern mit einem &lt;code&gt;filterset&lt;/code&gt; bestimmte Token ersetzt hat. Je nach Systemeinstellung kamen dann in der Web-Anwendung Umlaute (bzw. allgemein Sonderzeichen) an, die im Browser korrekt angezeigt werden konnten &amp;ndash; oder eben nicht.&lt;br /&gt;&lt;br /&gt;Die Lösung des Problems ist, bei Filter-Copy-Tasks die Kodierung explizit anzugeben, damit nicht die System-Default-Kodierung verwendet wird (die &lt;a href="http://ant.apache.org/manual/Tasks/copy.html#encoding"&gt;Doku&lt;/a&gt; erwähnt dies am Ende des Dokuments). Bei Properties-Dateien ist &lt;a href="http://de.wikipedia.org/wiki/ISO_8859-1"&gt;ISO-Latin-1 (ISO-8859-1)&lt;/a&gt; meist eine erste, gute Wahl (sofern die gesamte Web-Anwendung nicht auf UTF ausgelegt ist):&lt;br /&gt;&lt;pre&gt;&amp;lt;copy&lt;br /&gt;   todir="${webapp}/WEB-INF/classes"&lt;br /&gt;   file="${src}/MyResources.properties"&lt;br /&gt;   &lt;b&gt;encoding="ISO-8859-1"&lt;/b&gt;&lt;br /&gt;   overwrite="true"&amp;gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;filterset&amp;gt;&lt;br /&gt;      &amp;lt;filter token="COMPILETIME" value="${DSTAMP}-${TSTAMP}"/&amp;gt;&lt;br /&gt;   &amp;lt;/filterset&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/copy&amp;gt;&lt;/pre&gt;Entstanden ist der Bug wohl durch Copy&amp;amp;Paste, wobei aus einem &lt;code&gt;fileset&lt;/code&gt; &amp;ndash; ohne Filterung und damit ohne die Notwendigkeit, eine Zeichenkodierung anzugeben &amp;ndash; ein &lt;code&gt;filterset&lt;/code&gt; wurde.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-2504540422782280046?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/2504540422782280046/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/07/ant-filter-copy-task-und.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2504540422782280046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2504540422782280046'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/07/ant-filter-copy-task-und.html' title='Ant Filter-Copy-Task und Zeichenkodierung'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-2405478671085894347</id><published>2010-07-14T18:49:00.005+02:00</published><updated>2010-07-15T15:16:24.860+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Lift'/><title type='text'>Scala 2.8 und Lift 2.0</title><content type='html'>Knapp ein dreiviertel Jahr nach der letzten offiziellen Version &lt;a href="http://www.scala-lang.org/node/3906"&gt;2.7.7&lt;/a&gt; ist es heute endlich soweit: &lt;a href="http://www.scala-lang.org/node/7009"&gt;Scala 2.8&lt;/a&gt; wurde veröffentlicht! Neben zahlreichen Bugfixes gibt es viele Neuerungen:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;leichtgewichtigere, performantere &lt;a href="http://www.scala-lang.org/node/242"&gt;Aktoren&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Unterstützung für &lt;a href="http://www.scala-lang.org/node/2096#comment-7682"&gt;Continuations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;verbesserte XML-Bibliothek&lt;/li&gt;&lt;li&gt;Überarbeitete &lt;a href="http://www.scala-lang.org/node/2060"&gt;Kollektions&lt;/a&gt;-Bibliothek und Array-Implementation&lt;/li&gt;&lt;li&gt;Benannte  und Default-&lt;a href="http://www.scala-lang.org/node/2075"&gt;Argumente&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Package-Objekte&lt;/li&gt;&lt;li&gt;bessere Unterstützung für (verschachtelte) Java-Annotationen&lt;br /&gt;&lt;/li&gt;&lt;li&gt;deutlich  verbesserte Scala-Interpreter-Shell (&lt;a href="http://www.scala-lang.org/node/2097"&gt;REPL&lt;/a&gt;), u.a. mit  Tab-Eingabevervollständigung&lt;br /&gt;&lt;/li&gt;&lt;li&gt;u.a.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Die Werkzeuge &lt;a href="http://www.scala-lang.org/node/93"&gt;Sbaz&lt;/a&gt; und &lt;a href="https://lampsvn.epfl.ch/trac/scala/wiki/Scaladoc"&gt;Scaladoc&lt;/a&gt; liegen in Version 2 vor, der Decompiler Scalap wurde an aktuelle Sprachkonstrukte angepasst. Die &lt;a href="http://www.scala-ide.org/"&gt;Scala IDE für Eclipse&lt;/a&gt; wurde intensiv überarbeitet, wodurch sie nun u.a. besser in die Java-Werkzeuge von Eclipse eingebunden ist.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_1bA4Fk08GL0/TD4CAnFH7lI/AAAAAAAAADw/F7-A_ByoK7k/s1600/scala-2.8.0.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 158px;" src="http://2.bp.blogspot.com/_1bA4Fk08GL0/TD4CAnFH7lI/AAAAAAAAADw/F7-A_ByoK7k/s320/scala-2.8.0.png" alt="" id="BLOGGER_PHOTO_ID_5493830804952313426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Bereits vor zwei Wochen wurde das Scala-Web-Framework &lt;a href="http://liftweb.net/20_release.html"&gt;Lift 2.0&lt;/a&gt; veröffentlicht. Neben der bisher schon sehr guten &lt;a href="http://de.wikipedia.org/wiki/Ajax_%28Programmierung%29"&gt;Ajax&lt;/a&gt;- und &lt;a href="http://en.wikipedia.org/wiki/Comet_%28programming%29"&gt;Comet&lt;/a&gt;-Unterstützung gibt es u.a. folgende Neuerungen:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://de.wikipedia.org/wiki/NoSQL"&gt;NoSQL&lt;/a&gt;-Unterstützung (für &lt;a href="http://www.mongodb.org/"&gt;MongoDB&lt;/a&gt; und &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Performante &lt;a href="http://de.wikipedia.org/wiki/JavaScript_Object_Notation"&gt;JSON&lt;/a&gt;-Unterstützung mit einer eigenen &lt;a href="http://de.wikipedia.org/wiki/Dom%C3%A4nenspezifische_Sprache"&gt;DSL&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://de.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt;-Unterstützung&lt;/li&gt;&lt;li&gt;Einbindung von JTA, LDAP u.a.&lt;/li&gt;&lt;li&gt;das &lt;a href="http://code.google.com/p/simple-build-tool/"&gt;Simple Build Tool &lt;code&gt;sbt&lt;/code&gt;&lt;/a&gt; wird unterstützt und&lt;/li&gt;&lt;li&gt;die Lift-Programmierung wurde insgesamt vereinfacht.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Zum Schluss ein bisschen Werbung in eigener Sache: Wer mehr über Scala erfahren möchte, darf gerne an meinem nächsten &lt;a href="http://www.muchsoft.com/coaching.html"&gt;Scala-Workshop&lt;/a&gt; teilnehmen, der Ende November in Köln stattfindet!&lt;br /&gt;&lt;br /&gt;One more thing...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-2405478671085894347?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/2405478671085894347/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/07/scala-28-und-lift-20.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2405478671085894347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2405478671085894347'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/07/scala-28-und-lift-20.html' title='Scala 2.8 und Lift 2.0'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_1bA4Fk08GL0/TD4CAnFH7lI/AAAAAAAAADw/F7-A_ByoK7k/s72-c/scala-2.8.0.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-5942423081177360330</id><published>2010-06-15T22:34:00.010+02:00</published><updated>2010-06-16T23:09:01.443+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GlassFish'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Dependency Injection'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaFX'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>NetBeans 6.9 inkl. JavaFX Composer</title><content type='html'>Heute hat Oracle/Sun &lt;a href="http://netbeans.org/downloads/"&gt;NetBeans 6.9&lt;/a&gt; fertig gestellt und &lt;a href="http://netbeans.org/community/releases/roadmap.html"&gt;veröffentlicht&lt;/a&gt;. Eines der wichtigsten &lt;a href="http://netbeans.org/community/releases/69/"&gt;neuen Merkmale&lt;/a&gt; dürfte der nun standardmäßig integrierte &lt;a href="http://wiki.netbeans.org/JavaFXComposerGettingStarted"&gt;JavaFX Composer&lt;/a&gt; sein, mit dem sich Formulare und Grafiken für &lt;a href="http://javafx.com/"&gt;JavaFX 1.3&lt;/a&gt; visuell erstellen lassen:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_1bA4Fk08GL0/TBk6sKrRRTI/AAAAAAAAADo/cdHUFdhkey0/s1600/javafxcomposer.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 235px;" src="http://1.bp.blogspot.com/_1bA4Fk08GL0/TBk6sKrRRTI/AAAAAAAAADo/cdHUFdhkey0/s320/javafxcomposer.png" alt="" id="BLOGGER_PHOTO_ID_5483478551754786098" border="0" /&gt;&lt;/a&gt;Mal abwarten, wie sich der GUI-Editor in der Praxis bewährt. Aber die ersten Versuche sehen recht vielversprechend aus.&lt;br /&gt;&lt;br /&gt;Im Bereich "Java EE" ist die Unterstützung für den &lt;a href="http://jcp.org/en/jsr/detail?id=299"&gt;JSR-299 (CDI)&lt;/a&gt; sowie für &lt;a href="http://www.springsource.org/about"&gt;Spring 3.0&lt;/a&gt; erwähnenswert. Außerdem ist der Application Server &lt;a href="http://glassfish.org/"&gt;GlassFish&lt;/a&gt; in der Version 3.0.1 integriert.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-5942423081177360330?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/5942423081177360330/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/06/netbeans-69-inkl-javafx-composer.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/5942423081177360330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/5942423081177360330'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/06/netbeans-69-inkl-javafx-composer.html' title='NetBeans 6.9 inkl. JavaFX Composer'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_1bA4Fk08GL0/TBk6sKrRRTI/AAAAAAAAADo/cdHUFdhkey0/s72-c/javafxcomposer.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-3636312653283925031</id><published>2010-05-31T11:37:00.008+02:00</published><updated>2010-06-15T23:21:44.362+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaFX'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>JavaFX 1.3</title><content type='html'>Nur der Vollständigkeit halber... Bereits Ende letzten Monats hat Oracle/Sun &lt;a href="http://www.javafx.com/"&gt;JavaFX&lt;/a&gt; &lt;a href="http://blogs.sun.com/javafx/entry/javafx_1_3_released_delivers"&gt;1.3 &lt;/a&gt;veröffentlicht. Die wichtigsten Neuerungen sind&lt;br /&gt;&lt;ul&gt;&lt;li&gt;neue Controls (u.a. endlich eine ChoiceBox)&lt;/li&gt;&lt;li&gt;neue, brauchbare &lt;a href="http://amyfowlersblog.wordpress.com/2010/05/26/javafx-1-3-growing-shrinking-and-filling/"&gt;Layouts&lt;/a&gt;&lt;/li&gt;&lt;li&gt;bessere CSS-Unterstützung&lt;br /&gt;&lt;/li&gt;&lt;li&gt;bessere Performance und weniger Speicherverbrauch.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Beschreibungen und Zusammenfassungen der Änderungen und Neuerungen finden sich u.a. &lt;a href="http://javafx.com/docs/articles/javafx1-3.jsp"&gt;hier&lt;/a&gt;, &lt;a href="http://steveonjava.com/javafx-1-3-top-10/"&gt;hier&lt;/a&gt; und &lt;a href="http://fxexperience.com/2010/04/top-10-changes-in-javafx-1-3/"&gt;hier&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Wichtiger für die Akzeptanz von JavaFX ist m.E. aber, dass mit der Beta-Version von &lt;a href="http://netbeans.org/community/releases/69/"&gt;NetBeans 6.9&lt;/a&gt; der &lt;a href="http://wiki.netbeans.org/JavaFXComposer"&gt;JavaFX Composer&lt;/a&gt; mitgeliefert wird, mit dem Benutzeroberflächen (GUIs) – sowohl Masken als auch Grafiken – visuell zusammengestellt werden können.&lt;br /&gt;&lt;br /&gt;Die Migration bestehender Java FX 1.2-Anwendungen auf die neue Version ist &lt;a href="http://javafx.com/docs/articles/porting-guide-javafx1-3.jsp"&gt;hier&lt;/a&gt; beschrieben.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-3636312653283925031?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/3636312653283925031/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/05/javafx-13.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3636312653283925031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3636312653283925031'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/05/javafx-13.html' title='JavaFX 1.3'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-7119393079099346375</id><published>2010-04-20T22:10:00.013+02:00</published><updated>2010-04-20T22:40:25.877+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Hibernate 3.5 mit JPA 2.0 und Envers</title><content type='html'>Einige Wochen war es ruhig in diesem Blog, aber mit der Veröffentlichung unseres aktuellen Projekts Klaas 1.0 hatten wir alle Hände voll zu tun :-)&lt;br /&gt;&lt;br /&gt;In der Zwischenzeit wurde nach vielen Monaten der Entwicklung Ende März endlich &lt;a href="http://in.relation.to/Bloggers/Hibernate350FinalRelease"&gt;Hibernate 3.5&lt;/a&gt; fertiggestellt. Mittlerweile steht sogar schon das erste Bugfix-Release &lt;a href="http://in.relation.to/Bloggers/Hibernate351Final"&gt;Hibernate 3.5.1&lt;/a&gt; zur Verfügung.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jcp.org/aboutJava/communityprocess/final/jsr317/"&gt;JPA 2.0&lt;/a&gt; wird nun vollständig unterstützt, und mit &lt;a href="http://www.jboss.org/envers/"&gt;Envers&lt;/a&gt; ist eine Bibliothek zur automatischen &lt;a href="http://de.wikipedia.org/wiki/Temporale_Datenhaltung"&gt;temporalen Datenhaltung&lt;/a&gt; (Historisierung bzw. Versionierung) enthalten. Außerdem wurde die Abhängigkeitsverwaltung der Hibernate-Teilprojekte vereinfacht, denn aufeinander abgestimmte Versionen der Hibernate-Annotationen, des Hibernate-EntityManagers und von Envers sind nun im Hibernate-Core-JAR enthalten.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-7119393079099346375?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/7119393079099346375/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/04/hibernate-35-mit-jpa-20-und-envers.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7119393079099346375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7119393079099346375'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/04/hibernate-35-mit-jpa-20-und-envers.html' title='Hibernate 3.5 mit JPA 2.0 und Envers'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-8262680382636914963</id><published>2010-02-26T10:51:00.005+01:00</published><updated>2010-02-26T12:28:04.882+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Funktionale Programmierung'/><title type='text'>Closures in JavaScript</title><content type='html'>Nachdem ich schon Beispiele für Closures (Funktionsabschlüsse) in &lt;a href="http://javabarista.blogspot.com/2009/08/closures-in-javafx-script.html"&gt;JavaFX&lt;/a&gt; und &lt;a href="http://javabarista.blogspot.com/2010/01/closures-in-scala.html"&gt;Scala&lt;/a&gt; vorgestellt hatte, schauen wir uns dasselbe Beispiel in &lt;a href="http://de.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt; (&lt;a href="http://en.wikipedia.org/wiki/ECMAScript"&gt;ECMAScript&lt;/a&gt;) an:&lt;br /&gt;&lt;pre&gt;// closures.js&lt;br /&gt;&lt;br /&gt;function zaehlerMitStartwert(startwert) {&lt;br /&gt;  return function() {&lt;br /&gt;    return startwert++&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;next1 = zaehlerMitStartwert(10)&lt;br /&gt;next2 = zaehlerMitStartwert(20)&lt;br /&gt;&lt;br /&gt;document.writeln( next1() )   // 10&lt;br /&gt;document.writeln( next2() )   // 20&lt;br /&gt;document.writeln( next2() )   // 21&lt;br /&gt;document.writeln( next1() )   // 11&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Sehr viel mehr gibt es dazu eigentlich nicht zu sagen, außer dass es&lt;ol type="a"&gt;&lt;li&gt; wirklich so einfach ist (was auch zu &lt;a href="http://molily.de/weblog/closures-performance"&gt;Problemen&lt;/a&gt; führen kann)&lt;br /&gt;&lt;li&gt; schon seit den ersten JavaScript-Versionen (und damit seit über 10 Jahren) zur Verfügung steht und&lt;br /&gt;&lt;li&gt; im Gegensatz zu JavaFX Script und Scala dynamisch typisiert ist; zudem ist keine zusätzliche lokale Variable nötig, weil der Übergabeparameter &lt;code&gt;startwert&lt;/code&gt; bereits eine veränderbare Variable ist. Beides ist im Hinblick auf stabile, wartbare Software nicht unbedingt als positiv zu bewerten.&lt;br /&gt;&lt;/ol&gt;Viele moderne JavaScript-Bibliotheken machen starken Gebrauch von solchen Funktionsliteralen und Closures, beispielsweise &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-8262680382636914963?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/8262680382636914963/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/02/closures-in-javascript.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/8262680382636914963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/8262680382636914963'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/02/closures-in-javascript.html' title='Closures in JavaScript'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-1066015682078129174</id><published>2010-02-16T18:40:00.006+01:00</published><updated>2010-02-16T20:03:33.976+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Hibernate/JPA, hashCode() und Eclipse</title><content type='html'>Entitäten in Hibernate/JPA haben oft einen synthetischen (technischen) Primärschlüssel, der im folgenden Beispiel als &lt;code&gt;Long id&lt;/code&gt; implementiert wird. Sofern es keine zusätzlichen fachlichen Schlüsselkandidaten gibt, muss man die &lt;code&gt;hashCode()&lt;/code&gt;-Methode für Hibernate/JPA so implementieren, dass sie ausschließlich mit dieser Id arbeitet. (Es gibt auf &lt;a href="https://www.hibernate.org/109.html"&gt;hibernate.org&lt;/a&gt; eine lange Diskussion zu diesem Thema, denn die "offiziell" vorgeschlagene Variante, "halb-eindeutige" Felder zu verwenden, macht in der Praxis meistens mehr Probleme als die Id-Variante.)&lt;br /&gt;&lt;br /&gt;Damit man &lt;code&gt;hashCode()&lt;/code&gt; (und das zwingend dazu gehörende &lt;code&gt;equals()&lt;/code&gt;) nicht immer wieder von Hand neu schreiben muss, bietet Eclipse über &lt;i&gt;Source &amp;gt; Generate hashCode() and equals()&lt;/i&gt; die Möglichkeit, die beiden Methoden mit wählbaren Attributen zu generieren. Eine Beispiel-Entität könnte dann wie folgt aussehen:&lt;br /&gt;&lt;pre&gt;@Entity&lt;br /&gt;public class Datensatz {&lt;br /&gt;&lt;br /&gt;  @Id @GeneratedValue&lt;br /&gt;  private Long id;&lt;br /&gt;&lt;br /&gt;  // weitere Felder, Getter, Setter, equals() etc. ...&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Von Eclipse 3.5 generiert.&lt;br /&gt;   */&lt;br /&gt;  @Override&lt;br /&gt;  public int hashCode() {&lt;br /&gt;    final int prime = 31;&lt;br /&gt;    int result = 1;&lt;br /&gt;    result = prime * result&lt;br /&gt;              + ((id == null) ? &lt;b&gt;&lt;u&gt;0&lt;/u&gt;&lt;/b&gt; : id.hashCode());&lt;br /&gt;    return result;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;An sich liefert die Hashwert-Berechnung mittels Primzahlen eine gute Streuung, und der automatisch generierte Code beachtet auch, dass die Id &lt;code&gt;null&lt;/code&gt; sein kann &amp;ndash; nämlich bei noch nicht in der Datenbank gespeicherten (persistierten) Objekten.&lt;br /&gt;&lt;br /&gt;Nun testen wir diese Entity-Klasse:&lt;br /&gt;&lt;pre&gt;@Test&lt;br /&gt;public void testAddToHashSet() {&lt;br /&gt;&lt;br /&gt;  Set&amp;lt;Datensatz&amp;gt; menge = new HashSet&amp;lt;Datensatz&amp;gt;();&lt;br /&gt;&lt;br /&gt;  Datensatz ds1 = new Datensatz();&lt;br /&gt;  Datensatz ds2 = new Datensatz();&lt;br /&gt;&lt;br /&gt;  assertTrue("Menge sollte leer sein", menge.isEmpty());&lt;br /&gt;&lt;br /&gt;  menge.add(ds1);&lt;br /&gt;&lt;br /&gt;  assertTrue("Menge sollte ein Element besitzen",&lt;br /&gt;             menge.size() == 1);&lt;br /&gt;  // ok&lt;br /&gt;&lt;br /&gt;  menge.add(ds2);&lt;br /&gt;&lt;br /&gt;  assertTrue("Menge sollte zwei Elemente besitzen",&lt;br /&gt;             menge.size() == 2);&lt;br /&gt;  // immer noch 1... Ups!?!&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Immer, wenn man Assoziationen im Objekt-Modell aufbaut, bevor die Datensätze gespeichert sind (also z.B. bei Unit-Tests wie im obigen Beispiel), tritt das gezeigte Szenario auf. Wir haben hier zwei Objekte, die beide keine Id (=&lt;code&gt;null&lt;/code&gt;) besitzen. Es sind aber trotzdem zwei nicht identische Objekte in separaten Speicherbereichen, die beim Persistieren entsprechend zwei Datensätze mit unterschiedlichen Primärschlüsseln (Ids) erzeugen würden. Leider kann sich das HashSet nur eines der beiden Objekte merken &amp;ndash; und auch beim Persistieren einer Assoziation ginge so eines der Objekte verloren!&lt;br /&gt;&lt;br /&gt;Eine Anpassung der generierten &lt;code&gt;hashCode()&lt;/code&gt;-Methode ist denkbar einfach. Statt bei einer nicht vorhandenen Id die Zahl &lt;code&gt;0&lt;/code&gt; für die Hashwert-Berechnung zu verwenden, nehmen wir den Hashwert des Objekts, der bei nicht identischen Objekten in den allermeisten Fällen unterschiedlich ist:&lt;br /&gt;&lt;pre&gt;@Override&lt;br /&gt;public int hashCode() {&lt;br /&gt;  final int prime = 31;&lt;br /&gt;  int result = 1;&lt;br /&gt;  result = prime * result&lt;br /&gt;     + ((id == null) ? &lt;b&gt;&lt;u&gt;super.hashCode()&lt;/u&gt;&lt;/b&gt; : id.hashCode());&lt;br /&gt;  return result;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Eine vergleichbare Implementierung nutze ich seit Jahren ohne Probleme, weshalb ich diese Variante pauschal für die praktikabelste halte. In Einzelfällen mögen natürlich speziellere Implementierungen sinnvoller sein.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-1066015682078129174?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/1066015682078129174/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/02/hibernatejpa-hashcode-und-eclipse.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1066015682078129174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1066015682078129174'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/02/hibernatejpa-hashcode-und-eclipse.html' title='Hibernate/JPA, hashCode() und Eclipse'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-2115670326814987842</id><published>2010-02-03T21:43:00.003+01:00</published><updated>2010-02-03T23:05:42.220+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>HTML-Accesskey mit CSS darstellen</title><content type='html'>Mit dem Standard-HTML-Attribut &lt;a href="http://www.w3.org/TR/html401/interact/forms.html#access-keys"&gt;&lt;code&gt;accesskey&lt;/code&gt;&lt;/a&gt; lassen sich Tastaturkürzel (Shortcuts) definieren, mit denen man den Eingabefokus auf die zugehörigen Eingabeelemente setzen kann:&lt;br /&gt;&lt;pre&gt;&amp;lt;label for="nachname" &lt;b&gt;accesskey="n"&lt;/b&gt;&amp;gt;Nachname:&amp;lt;/label&amp;gt;&lt;br /&gt;&amp;lt;input id="nachname" type="text"&amp;gt;&lt;br /&gt;&lt;/pre&gt;Mit welcher Tastenkombination der Fokus gesetzt wird, ist browser- und systemabhängig. Obiges Kürzel aktiviert man im IE/Win mit Alt+N, im Firefox/Win mit Shift+Alt+N, im Firefox/Mac mit Ctrl+N, in Safari/Mac mit Ctrl+Alt+N...&lt;br /&gt;&lt;br /&gt;Natürlich sollte man dem Anwender auch anzeigen, dass Tastaturkürzel vorhanden sind. Man kann diese Information zwar noch einmal statisch in den HTML-Quelltext schreiben (zusätzlich zum &lt;code&gt;accesskey&lt;/code&gt;-Attribut). Mit einer einfachen CSS2-Regel kann man aber auf solche redundanten Angaben verzichten und die Kürzel an allen &lt;code&gt;label&lt;/code&gt;-Elementen darstellen lassen, bei denen &lt;code&gt;accesskey&lt;/code&gt; gesetzt ist:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;label[accesskey]:after {&lt;br /&gt;  content: " [" attr(accesskey) "]";&lt;br /&gt;  text-transform: uppercase;&lt;br /&gt;  color: #999999;&lt;br /&gt;  font-size: x-small;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Die CSS-Regel basiert vor allem auf einem &lt;a href="http://www.w3.org/TR/CSS2/selector.html#attribute-selectors"&gt;Attribut-Selektor&lt;/a&gt; und einem &lt;a href="http://www.w3.org/TR/CSS2/selector.html#before-and-after"&gt;Pseudo-Element&lt;/a&gt;. Dadurch wird nach (&lt;code&gt;:after&lt;/code&gt;) jedem &lt;code&gt;label&lt;/code&gt;-Element, bei dem das &lt;code&gt;accesskey&lt;/code&gt;-Attribut vorhanden ist, der Wert des Attributs in Großschreibung (&lt;code&gt;uppercase&lt;/code&gt;) in den Dokument-Inhalt (&lt;code&gt;content&lt;/code&gt;) eingefügt:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1bA4Fk08GL0/S2njxwZYRDI/AAAAAAAAACQ/oVzznqrfjv0/s1600-h/accesskey.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 271px; height: 41px;" src="http://3.bp.blogspot.com/_1bA4Fk08GL0/S2njxwZYRDI/AAAAAAAAACQ/oVzznqrfjv0/s320/accesskey.png" alt="" id="BLOGGER_PHOTO_ID_5434124869343659058" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;An sich sind diese Techniken recht alt, die entsprechenden Standards wurden schon vor Jahren offiziell verabschiedet (die HTML 4.01-Spezifikation ist über 10 Jahre alt, CSS 2 ebenso). Was macht dieses Thema wieder aktuell?&lt;br /&gt;&lt;br /&gt;Google hat vor kurzem &lt;a href="http://googleenterprise.blogspot.com/2010/01/modern-browsers-for-modern-applications.html"&gt;angekündigt&lt;/a&gt;, ab dem 1. März dieses Jahres ältere Browser-Versionen und insbesondere den &lt;a href="http://iedeathmarch.org/"&gt;Internet Explorer 6 (IE6)&lt;/a&gt; nicht mehr in seinen Web-Anwendungen zu unterstützen.&lt;br /&gt;Dieser &amp;ndash; eigentlich längst überfällige &amp;ndash; Schritt dürfte auch andere Anbieter dazu bewegen, neuere IE-Versionen (oder Alternativen wie &lt;a href="http://getfirefox.com/"&gt;Firefox&lt;/a&gt;) vorauszusetzen. Und dann könnten auch endlich IE-Nutzer von Web-Standards wie den Attribut-Selektoren profitieren, die der IE6 leider seit Jahren ignoriert.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-2115670326814987842?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/2115670326814987842/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/02/html-accesskey-mit-css-darstellen.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2115670326814987842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2115670326814987842'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/02/html-accesskey-mit-css-darstellen.html' title='HTML-Accesskey mit CSS darstellen'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_1bA4Fk08GL0/S2njxwZYRDI/AAAAAAAAACQ/oVzznqrfjv0/s72-c/accesskey.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-4145710881077155810</id><published>2010-01-31T13:24:00.010+01:00</published><updated>2010-01-31T15:43:32.386+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Funktionale Programmierung'/><title type='text'>Closures in Scala</title><content type='html'>Als funktionale Sprache unterstützt &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; Funktionen höherer Ordnung (first-class functions) und Funktionsabschlüsse (&lt;a href="http://de.wikipedia.org/wiki/Closure"&gt;Closures&lt;/a&gt;). In dem Beitrag über &lt;a href="http://javabarista.blogspot.com/2009/08/closures-in-javafx-script.html"&gt;Closures in JavaFXScript&lt;/a&gt; hatte ich bereits gezeigt, wie dort Closures definiert und genutzt werden. Wie programmiert man nun Closures in Scala?&lt;br /&gt;&lt;pre&gt;// closures1.scala&lt;br /&gt;&lt;br /&gt;def zaehlerMitStartwert(startwert: Int): (() =&gt; Int)  = {&lt;br /&gt;  var n = startwert&lt;br /&gt;  def nplus1(): Int = { n=n+1; n }&lt;br /&gt;  nplus1&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;val next1 = zaehlerMitStartwert(10)&lt;br /&gt;val next2 = zaehlerMitStartwert(20)&lt;br /&gt;&lt;br /&gt;println( next1() )&lt;br /&gt;println( next2() )&lt;br /&gt;println( next2() )&lt;br /&gt;println( next1() )&lt;br /&gt;&lt;/pre&gt;Wir definieren eine Funktion &lt;code&gt;zaehlerMitStartwert()&lt;/code&gt;, die den Startwert als Int-Parameter übergeben bekommt. Rückgabe dieser Funktion ist eine Funktion, die keine Parameter hat, aber einen Int-Wert zurückgibt.&lt;br /&gt;&lt;br /&gt;Innerhalb der äußeren Funktion legen wir eine Zählvariable &lt;code&gt;n&lt;/code&gt; an, da der Übergabeparameter &lt;code&gt;startwert&lt;/code&gt; unveränderlich ist. Dann definieren wir eine verschachtelte Funktion &lt;code&gt;nplus1()&lt;/code&gt;, die auf die Zählvariable &lt;code&gt;n&lt;/code&gt; eins draufzählt und als letzten Ausdruck der Funktion das hochgezählte &lt;code&gt;n&lt;/code&gt; zurückgibt. Hier findet der Funktionsabschluss statt - das Binden der Variablen &lt;code&gt;n&lt;/code&gt;, die als lokale Variable in der umgebenden Funktion definiert ist. Als letzten Ausdruck in der äußeren Funktion geben wir die Funktion &lt;code&gt;nplus1&lt;/code&gt; als Ergebnis zurück.&lt;br /&gt;&lt;br /&gt;Das ganze geht auch etwas kürzer und "funktionaler", wenn man die innere Funktion nicht explizit definiert, sondern als letzten Ausdruck der äußeren Funktion gleich ein entsprechendes Funktionsliteral hinschreibt:&lt;br /&gt;&lt;pre&gt;// closures2.scala&lt;br /&gt;&lt;br /&gt;def zaehlerMitStartwert(startwert: Int) = {&lt;br /&gt;  var n = startwert&lt;br /&gt;  &lt;b&gt;() =&gt; { n=n+1; n }&lt;/b&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;val next1 = zaehlerMitStartwert(10)&lt;br /&gt;val next2 = zaehlerMitStartwert(20)&lt;br /&gt;&lt;br /&gt;println( next1() )&lt;br /&gt;println( next2() )&lt;br /&gt;println( next2() )&lt;br /&gt;println( next1() )&lt;br /&gt;&lt;/pre&gt;Beide Skripte liefern dieselbe Ausgabe:&lt;br /&gt;&lt;pre&gt;HeartOfGold:~ much$ scala closures2.scala&lt;br /&gt;11&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;12&lt;/pre&gt;Wenn man den Scala-Interpreter mit &lt;code&gt;scala -savecompiled closures2.scala&lt;/code&gt; aufruft, erhält man ein JAR-Archiv, in dem man sich die generierten Java-Bytecode-Dateien anschauen kann. In diesem Fall werden vier &lt;code&gt;class&lt;/code&gt;-Dateien erzeugt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-4145710881077155810?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/4145710881077155810/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2010/01/closures-in-scala.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4145710881077155810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4145710881077155810'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2010/01/closures-in-scala.html' title='Closures in Scala'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-9008414375714626709</id><published>2009-12-27T11:57:00.005+01:00</published><updated>2009-12-27T12:27:11.790+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Scala-Servlets</title><content type='html'>Ein schönes Beispiel dafür, wie sich gewohnte Java-Programmierung in &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; "anfühlt", sind &lt;a href="http://de.wikipedia.org/wiki/Servlet"&gt;Servlets&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;package com.muchsoft.scala.servlets&lt;br /&gt;&lt;br /&gt;import javax.servlet.http.HttpServlet&lt;br /&gt;import javax.servlet.http.{HttpServletRequest =&amp;gt; Request,&lt;br /&gt;                           HttpServletResponse =&amp;gt; Response}&lt;br /&gt;&lt;br /&gt;class MeinErstesScalaServlet extends HttpServlet {&lt;br /&gt;&lt;br /&gt;  override def doGet(request: Request, response: Response) {&lt;br /&gt;&lt;br /&gt;    val ausgabe =&lt;br /&gt;      &amp;lt;html&amp;gt;&lt;br /&gt;        &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Hallo Scala&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;        &amp;lt;body&amp;gt;&lt;br /&gt;          &amp;lt;h1&amp;gt;Hallo Scala-Welt!&amp;lt;/h1&amp;gt;&lt;br /&gt;        &amp;lt;/body&amp;gt;&lt;br /&gt;      &amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;    response.getWriter().print(ausgabe)&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;Das sieht doch fast wie Java aus, oder? Nicht ganz: Beim Import können wir Umdefinitionen vornehmen, das &lt;code&gt;override&lt;/code&gt; vor der Methodendefinition ist zwingend notwendig, zudem ein Schlüsselwort und keine Annotation. Der Rückgabetyp der Methode &lt;code&gt;doGet()&lt;/code&gt; ist nicht angegeben und entspricht dadurch dem Java-&lt;code&gt;void&lt;/code&gt;. Für Scala hätten wir vor die öffnende geschweifte Methodenklammer &lt;code&gt;:Unit=&lt;/code&gt; schreiben können.&lt;br /&gt;&lt;br /&gt;Innerhalb von &lt;code&gt;doGet()&lt;/code&gt; legen wir das XML-Literal &lt;code&gt;ausgabe&lt;/code&gt; an (als nicht änderbaren Wert mit &lt;code&gt;val&lt;/code&gt;; mit &lt;code&gt;var&lt;/code&gt; angelegte Variablen versucht man in funktionalen Sprachen zu vermeiden). Dieses XML-Literal schreiben wir ganz normal in den Ausgabestrom des Response-Objekts. Der Typ von &lt;code&gt;ausgabe&lt;/code&gt; ist &lt;code&gt;scala.xml.Elem&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Die Struktur der Web-Applikation entspricht dem JavaEE-Standard:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1bA4Fk08GL0/Szc9S5XKxrI/AAAAAAAAACI/xYxeMB5Z4Yk/s1600-h/scala-servlets.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 185px;" src="http://3.bp.blogspot.com/_1bA4Fk08GL0/Szc9S5XKxrI/AAAAAAAAACI/xYxeMB5Z4Yk/s320/scala-servlets.png" alt="" id="BLOGGER_PHOTO_ID_5419868071408617138" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Der vom Scala-Compiler erzeugte Java-Bytecode landet in &lt;code&gt;WEB-INF/classes&lt;/code&gt;. Die Scala-Standardbibliothek &lt;code&gt;scala-library.jar&lt;/code&gt; (aus dem Scala-Installationsverzeichnis) muss in &lt;code&gt;WEB-INF/lib&lt;/code&gt; mit ausgeliefert werden. In &lt;a href="http://en.wikipedia.org/wiki/WAR_%28Sun_file_format%29"&gt;&lt;code&gt;WEB-INF/web.xml&lt;/code&gt;&lt;/a&gt; mappen wir die Klasse &lt;code&gt;com.muchsoft.scala.servlets.MeinErstesScalaServlet&lt;/code&gt; auf die URL "hallo.scala". Nach dem Bereitstellen (Deployment) z.B. in &lt;a href="http://tomcat.apache.org/"&gt;Tomcat&lt;/a&gt; oder &lt;a href="https://glassfish.dev.java.net/"&gt;GlassFish&lt;/a&gt; kann das Servlet im Web-Browser dann mit der URL &lt;i&gt;http://localhost:8080/halloscala/hallo.scala&lt;/i&gt; aufgerufen werden.&lt;br /&gt;&lt;br /&gt;Zum Übersetzen der Servlet-Klasse muss sich noch die Servlet-API auf dem Build-Path (Classpath) befinden. Dazu kann man z.B. aus dem Tomcat-Installationsverzeichnis &lt;code&gt;servlet-api.jar&lt;/code&gt; oder aus dem GlassFish-Verzeichnis &lt;code&gt;javaee.jar&lt;/code&gt; als externe Bibliothek einbinden.&lt;br /&gt;&lt;br /&gt;Nun verbessern wir das erste Scala-Servlet und trennen Darstellung und Steuerung etwas besser voneinander:&lt;br /&gt;&lt;pre&gt;class MeinZweitesScalaServlet extends HttpServlet {&lt;br /&gt;&lt;br /&gt;  def ausgabe =&lt;br /&gt;    &amp;lt;html&amp;gt;&lt;br /&gt;      &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Hallo Scala&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;      &amp;lt;body&amp;gt;&lt;br /&gt;        &amp;lt;h1&amp;gt;Hallo Scala-Welt!&amp;lt;/h1&amp;gt;&lt;br /&gt;        &amp;lt;p&amp;gt;Zeit auf dem Server: {jetzt} &amp;lt;/p&amp;gt;&lt;br /&gt;      &amp;lt;/body&amp;gt;&lt;br /&gt;    &amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;  def jetzt = new java.util.Date&lt;br /&gt;&lt;br /&gt;  override def doGet(request: Request, response: Response) {&lt;br /&gt;    response.getWriter().print(ausgabe)&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;code&gt;ausgabe&lt;/code&gt; ist nun eine Funktion außerhalb von &lt;code&gt;doGet()&lt;/code&gt;, die auf die Funktion &lt;code&gt;jetzt&lt;/code&gt; zurückgreift, um einen aktuellen Zeitstempel auszugeben. Beide Funktionen sind ohne Parameterklammern definiert und müssen daher ohne Klammern aufgerufen werden. Hätten wir die Funktionen mit leeren Parameterklammern definiert, hätten wir es uns beim Aufruf aussuchen können, ob wir die Klammern hinschreiben oder nicht. Es hat sich die Konvention herausgebildet, die Klammern bei der Definition wegzulassen, wenn eine Funktion keine Nebenwirkungen (Seiteneffekte) hat.&lt;br /&gt;&lt;br /&gt;Für eine "vollständige" Web-Applikation fehlt noch ein Formular. Bitteschön:&lt;br /&gt;&lt;pre&gt;class MeinDrittesScalaServlet extends HttpServlet {&lt;br /&gt; &lt;br /&gt;  def ausgabe(benutzername: String) =&lt;br /&gt;    &amp;lt;html&amp;gt;&lt;br /&gt;      &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Hallo Scala-Welt&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;      &amp;lt;body&amp;gt;&lt;br /&gt;        &amp;lt;h1&amp;gt;Hallo {benutzername}&amp;lt;/h1&amp;gt;&lt;br /&gt;        &amp;lt;p&amp;gt;Zeit auf dem Server: {jetzt}&amp;lt;/p&amp;gt;&lt;br /&gt;        &amp;lt;form method="GET" action="hallo3.scala"&amp;gt;&lt;br /&gt;          &amp;lt;p&amp;gt;Wie heißt Du?&lt;br /&gt;          &amp;lt;input name="benutzer" /&amp;gt;&lt;br /&gt;          &amp;lt;input type="submit" value="Abschicken" /&amp;gt;&lt;br /&gt;          &amp;lt;/p&amp;gt;&lt;br /&gt;        &amp;lt;/form&amp;gt;&lt;br /&gt;      &amp;lt;/body&amp;gt;&lt;br /&gt;    &amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;  def jetzt = new java.util.Date&lt;br /&gt;&lt;br /&gt;  override def doGet(request: Request, response: Response) {&lt;br /&gt; &lt;br /&gt;    val param = request getParameter "benutzer"&lt;br /&gt;&lt;br /&gt;    val benutzername =&lt;br /&gt;      if ((param == null) || (param.isEmpty))&lt;br /&gt;        "Scala"&lt;br /&gt;      else&lt;br /&gt;        param capitalize&lt;br /&gt;&lt;br /&gt;    val antwort = ausgabe(benutzername)&lt;br /&gt;&lt;br /&gt;    response.getWriter().print(antwort)&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;code&gt;ausgabe()&lt;/code&gt; bekommt nun einen String-Parameter übergeben, der in &lt;code&gt;doGet()&lt;/code&gt; anhand des Request-Parameters "benutzer" ermittelt wird. Statt des &lt;code&gt;?:&lt;/code&gt;-Operators von Java, den es in Scala nicht gibt, verwenden wir ein besser lesbares &lt;code&gt;if-else&lt;/code&gt;, das in Scala ein Ausdruck ist und entsprechend ein Ergebnis liefert.&lt;br /&gt;&lt;br /&gt;Wenn diese dritte Servlet-Klasse in &lt;code&gt;web.xml&lt;/code&gt; auf die URL "hallo3.scala" gemappt wird, kann der Aufruf im lokalen Applikations-Server mit &lt;i&gt;http://localhost:8080/halloscala/hallo3.scala?benutzer=Thomas&lt;/i&gt; erfolgen.&lt;br /&gt;&lt;br /&gt;In der Praxis wird man Servlets wohl eher nicht direkt programmieren, sondern ein Framework wie &lt;a href="http://struts.apache.org/"&gt;Struts&lt;/a&gt;, &lt;a href="http://java.sun.com/javaee/javaserverfaces/"&gt;JSF&lt;/a&gt;, &lt;a href="http://wicket.apache.org/"&gt;Wicket&lt;/a&gt; o.ä. einsetzen. Man sieht hier aber gut, wie problemlos man Scala in bestehende Java-(Web-)Anwendungen integrieren kann. Und wenn man Web-Applikationen so richtig funktional entwickeln möchte, kann man das Scala-&lt;a href="http://liftweb.net/"&gt;Lift&lt;/a&gt;-Framework nutzen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-9008414375714626709?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/9008414375714626709/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/12/scala-servlets.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/9008414375714626709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/9008414375714626709'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/12/scala-servlets.html' title='Scala-Servlets'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_1bA4Fk08GL0/Szc9S5XKxrI/AAAAAAAAACI/xYxeMB5Z4Yk/s72-c/scala-servlets.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-8280818102804147463</id><published>2009-12-12T19:26:00.007+01:00</published><updated>2009-12-14T22:20:36.240+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>ECMAScript 5</title><content type='html'>Bis vor ein paar Jahren musste man regelmäßig darauf hinweisen, dass &lt;a href="http://de.wikipedia.org/wiki/Java_%28Programmiersprache%29"&gt;Java&lt;/a&gt; nicht &lt;a href="http://de.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt; ist, und JavaScript wurde als Programmiersprache – trotz Objektbasierung und funktionaler Aspekte – nicht ernst genommen. Mit &lt;a href="http://de.wikipedia.org/wiki/Web_2.0"&gt;Web 2.0&lt;/a&gt; und &lt;a href="http://de.wikipedia.org/wiki/Ajax_%28Programmierung%29"&gt;Ajax&lt;/a&gt; ist dies seit einiger Zeit definitiv anders. JavaScript ist im Frontend akzeptiert, und es gibt keine ernsthaften Diskussionen mehr, ob man es im Browser deaktivieren soll. &lt;a href="http://de.wikipedia.org/wiki/Rich_Internet_Application"&gt;RIA&lt;/a&gt; kommt ohne JavaScript nicht aus.&lt;br /&gt;&lt;br /&gt;Vor einer Woche wurde nun die Spezifikation von &lt;a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm"&gt;ECMAScript 5&lt;/a&gt;, dem offiziellen Standard für JavaScript, freigegeben. Die neue &lt;a href="http://www.ecmascript.org/"&gt;ECMAScript&lt;/a&gt;-Version wurde ziemlich genau zehn Jahre nach der letzten Version, ECMAScript 3, veröffentlicht (Version 4 wurde ausgelassen). Neben vielen kleinen Verbesserungen und einem "strict"-Modus ist nun auch &lt;a href="http://de.wikipedia.org/wiki/JavaScript_Object_Notation"&gt;JSON&lt;/a&gt; im Standard enthalten. Mit diesem Datenformat können JavaScript-Objekte kompakt durch das Netz übertragen werden.&lt;br /&gt;&lt;br /&gt;Für mich ist ECMAScript insofern interessant, als es nun über zehn Jahre her ist, dass ich für den Web-Browser &lt;a href="http://www.icab.de/"&gt;iCab&lt;/a&gt; eine JavaScript-Engine (Interpreter) zunächst auf Basis von ECMAScript 2, nach 1999 dann aufbauend auf ECMAScript 3 entwickelt hatte. iCab hat seine Rendering Engine (und damit auch die JavaScript-Laufzeitumgebung) zwar mittlerweile auf Apples &lt;a href="http://de.wikipedia.org/wiki/WebKit"&gt;WebKit&lt;/a&gt; umgestellt, aber die Implementierung einer so zentralen Browser-Komponente gab einen tollen Einblick hinter die technischen Kulissen auf das, wie das Web bis (und gerade) heute funktioniert.&lt;br /&gt;&lt;br /&gt;Wie die Zeit vergeht...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-8280818102804147463?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/8280818102804147463/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/12/ecmascript-5.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/8280818102804147463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/8280818102804147463'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/12/ecmascript-5.html' title='ECMAScript 5'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-731302916788658602</id><published>2009-12-10T18:49:00.004+01:00</published><updated>2009-12-10T21:16:39.846+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GlassFish'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>Hallo Java EE 6!</title><content type='html'>Dreieinhalb Jahre nach Java EE 5 hat Sun heute die endgültige Spezifikation von &lt;a href="http://java.sun.com/javaee/"&gt;Java EE 6&lt;/a&gt; freigegeben. Bestandteil davon sind u.a. die Spezifikationen von EJB 3.1, JPA 2.0 und JSF 2.0.&lt;br /&gt;&lt;br /&gt;Der Download des &lt;a href="http://java.sun.com/javaee/downloads/"&gt;Java EE 6 SDK&lt;/a&gt; enthält den Application Server &lt;a href="http://www.sun.com/software/products/glassfishv3/"&gt;GlassFish v3&lt;/a&gt; als Referenzimplementation (neben Beispielen samt Dokumentation).&lt;br /&gt;&lt;br /&gt;Ebenfalls verfügbar ist die an JEE 6 und GlassFish v3 angepasste Entwicklungsumgebung &lt;a href="http://netbeans.org/downloads/"&gt;NetBeans 6.8&lt;/a&gt;. Eclipse-Anwender finden &lt;a href="http://download.java.net/glassfish/eclipse/"&gt;hier&lt;/a&gt; das entsprechende Plugin.&lt;br /&gt;&lt;br /&gt;Wer bereits jetzt Java-Enterprise-Projekte auf Basis von JEE 5 entwickelt, dem dürfte die Umstellung auf die neue Version nicht allzu schwer fallen – sofern der eingesetzte &lt;a href="http://java.sun.com/javaee/overview/compatibility.jsp"&gt;Application Server&lt;/a&gt; kompatibel zur neuen Spezifikation ist.&lt;br /&gt;&lt;br /&gt;Eine dreiteilige Einführung in Java EE 6 hat Sun &lt;a href="http://java.sun.com/developer/technicalArticles/JavaEE/JavaEE6Overview.html"&gt;hier&lt;/a&gt; veröffentlicht.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-731302916788658602?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/731302916788658602/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/12/hallo-java-ee-6.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/731302916788658602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/731302916788658602'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/12/hallo-java-ee-6.html' title='Hallo Java EE 6!'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-7996511157194317752</id><published>2009-12-08T20:47:00.007+01:00</published><updated>2009-12-08T22:00:43.111+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>Eclipse 3.5 Galileo, Software-Updates und Proxy-Verbindungen</title><content type='html'>Je nach Netzwerkumgebung gibt es mit Eclipse immer wieder Probleme beim Installieren von Plugins (über das Menü &lt;span style="font-style: italic;"&gt;Help &amp;gt; Install New Software...&lt;/span&gt;) bzw. beim automatischen Aktualisieren bereits installierter Erweiterungen (über &lt;span style="font-style: italic;"&gt;Help &amp;gt; Check for Updates&lt;/span&gt;). Grund sind meistens Proxies, die von Eclipse nicht unterstützte Protokolle verwenden, sowie Firewalls, die eigene Zertifikate für https-Verbindungen ausgeben.&lt;br /&gt;&lt;br /&gt;Sofern man das Zertifikat der Firewall besitzt (eine Datei üblicherweise mit der Endung &lt;code&gt;*.cer&lt;/code&gt;), kann man dieses in den Keystore der Java-Installation importieren. Welche Java-Installation von Eclipse verwendet wird, kann man unter &lt;span style="font-style: italic;"&gt;About Eclipse &amp;gt; Installation Details &amp;gt; Configuration&lt;/span&gt; herausfinden. Unter Windows lautet der Aufruf des &lt;code&gt;keytool&lt;/code&gt;-Kommandozeilenbefehls beispielsweise&lt;br /&gt;&lt;pre&gt;C:\Programme\Java\jre6\bin\keytool -import -v&lt;br /&gt;   -file &lt;i&gt;PfadZumZertifikat&lt;/i&gt;&lt;br /&gt;   -keystore C:\Programme\Java\jre6\lib\security\cacerts&lt;br /&gt;Geben Sie das Keystore-Passwort ein: &lt;i&gt;changeit&lt;/i&gt;&lt;/pre&gt;"changeit" ist das Standard-Passwort des KeyStores, sofern Sie es nicht geändert haben.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ein anderes Problem stellen &lt;a href="http://de.wikipedia.org/wiki/NTLM"&gt;NTLMv2&lt;/a&gt;-Proxy-Server dar, die seit Eclipse 3.5 nicht mehr direkt unterstützt werden. Neben der korrekten Einrichtung der Proxy-Adresse und der Authentifizierungsdaten unter &lt;span style="font-style: italic;"&gt;Preferences &amp;gt; General &amp;gt; Network Connections&lt;/span&gt; muss in der Datei &lt;code&gt;eclipse.ini&lt;/code&gt; (im Eclipse-Programmverzeichnis) am Ende &lt;a href="http://wiki.eclipse.org/ECF_Filetransfer_Support_for_NTLMv2_Proxies"&gt;folgende Zeile&lt;/a&gt; hinzugefügt werden:&lt;br /&gt;&lt;pre&gt;-Dorg.eclipse.ecf.provider.filetransfer.excludeContributors=org.eclipse.ecf.provider.filetransfer.httpclient&lt;/pre&gt;In Eclipse 3.5 war es in der o.g. Preferences-Seite zudem notwendig, den "Active Provider" auf "Native" zu stellen. In Eclipse 3.5.1 funktioniert auch die Einstellung "Manual".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-7996511157194317752?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/7996511157194317752/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/12/eclipse-35-galileo-software-updates-und.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7996511157194317752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7996511157194317752'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/12/eclipse-35-galileo-software-updates-und.html' title='Eclipse 3.5 Galileo, Software-Updates und Proxy-Verbindungen'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-3044268182039246216</id><published>2009-11-16T08:51:00.006+01:00</published><updated>2009-11-16T11:11:41.928+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Scala-Code als und in einer Java-Anwendung ausführen</title><content type='html'>Compilierter Scala-Bytecode lässt sich problemlos in bestehende Java-Anwendungen integrieren. Möglich ist dies, weil der Scala-Compiler ganz normalen &lt;a href="http://en.wikipedia.org/wiki/Java_bytecode"&gt;Java-Bytecode&lt;/a&gt; erzeugt. Als &lt;a href="http://de.wikipedia.org/wiki/Java_Virtual_Machine"&gt;Laufzeitumgebung&lt;/a&gt; sollte dabei Java 5.0 oder neuer zum Einsatz kommen.&lt;br /&gt;&lt;br /&gt;Dazu wird eine Scala-Installation benötigt. Am besten nimmt man den &lt;a href="http://www.scala-lang.org/downloads"&gt;IzPack-Installer&lt;/a&gt;. Das Installationsverzeichnis heißt im folgenden Beispiel "scala-2.7.7".&lt;br /&gt;&lt;pre&gt;object HalloScalaWelt extends Application {&lt;br /&gt;  println("Hallo Scala!")&lt;br /&gt;}&lt;/pre&gt;Dieses ausführbare Singleton-Objekt speichert man als Datei "HalloScalaWelt.scala", die nun übersetzt und ausgeführt wird:&lt;br /&gt;&lt;pre&gt;HeartOfGold:~ much$ &lt;b&gt;scalac HalloScalaWelt.scala&lt;/b&gt;&lt;br /&gt;HeartOfGold:~ much$ ls Hallo*.class&lt;br /&gt;HalloScalaWelt$.class    HalloScalaWelt.class&lt;br /&gt;HeartOfGold:~ much$ &lt;b&gt;scala HalloScalaWelt&lt;/b&gt;&lt;br /&gt;Hallo Scala!&lt;/pre&gt;Bereits jedem Java-Einsteiger sollten diese Kommandos irgendwie bekannt vorkommen. Entsprechend führen wir die erzeugten class-Dateien ganz einfach als Java-Anwendung aus:&lt;br /&gt;&lt;pre&gt;HeartOfGold:~ much$&lt;br /&gt;  &lt;b&gt;java -cp scala-2.7.7/lib/scala-library.jar:. HalloScalaWelt&lt;/b&gt;&lt;br /&gt;Hallo Scala!&lt;/pre&gt;Unter Windows gibt man beim Klassenpfad (Option &lt;code&gt;-cp&lt;/code&gt; oder &lt;code&gt;-classpath&lt;/code&gt;) vor dem Punkt am Ende (= aktuelles Verzeichnis) ein Semikolon anstelle des Doppelpunkts an.&lt;br /&gt;&lt;br /&gt;Ebenso einfach kann man Scala-Code in bestehende Java-Anwendungen integrieren. Man übernimmt einfach die compilierten class-Dateien und setzt &lt;code&gt;scala-library.jar&lt;/code&gt; auf den Klassenpfad – fertig!&lt;br /&gt;&lt;br /&gt;Die Benutzung von Klassen zwischen Java und Scala besteht meistens ganz einfach darin, wie gewohnt den (vollqualifizierten oder importierten) Klassennamen zu verwenden.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-3044268182039246216?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/3044268182039246216/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/11/scala-code-als-und-in-einer-java.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3044268182039246216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3044268182039246216'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/11/scala-code-als-und-in-einer-java.html' title='Scala-Code als und in einer Java-Anwendung ausführen'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-4380944167266625797</id><published>2009-11-13T08:19:00.002+01:00</published><updated>2009-11-13T12:01:47.525+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaFX'/><category scheme='http://www.blogger.com/atom/ns#' term='Java ME'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>Java ME SDK 3.0 für Mac OS X</title><content type='html'>Die Entwicklung von Applikationen für &lt;a href="http://java.sun.com/javame/"&gt;Java ME&lt;/a&gt;, der Java-Plattform für mobile Geräte, war unter Mac OS X ein eher schwieriges Thema. Wichtige Bestandteile des SDKs fehlten oder wurden nicht offiziell unterstützt (Anleitungen für "inoffizielle" Lösungen gibt es z.B. &lt;a href="http://javablog.co.uk/2008/01/17/j2me-development-on-os-x-revisited/"&gt;hier&lt;/a&gt;, &lt;a href="http://www.just2me.com/2008/06/developing-java-me-on-mac-os-x.html"&gt;hier&lt;/a&gt; oder &lt;a href="http://wiki.netbeans.org/FaqMobilityMpowerMacOs"&gt;hier&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Vor drei Wochen hat Sun nun endlich das &lt;a href="http://java.sun.com/javame/downloads/sdk30_mac.jsp"&gt;Java ME SDK 3.0&lt;/a&gt; als &lt;a href="http://blogs.sun.com/javamesdk/entry/early_access_release_for_mac"&gt;Early Access&lt;/a&gt; (EA) für Mac OS X 10.5.8 und neuer veröffentlicht. Das &lt;a href="http://de.wikipedia.org/wiki/Disk_Image_%28Apple%29"&gt;DMG&lt;/a&gt; enthält das komplette SDK als eine Applikation, die einfach per Drag&amp;amp;Drop in den Programme-Ordner installiert wird.&lt;br /&gt;&lt;br /&gt;Die SDK-Entwicklungsumgebung basiert auf der NetBeans-Plattform und ermöglicht erstmalig &lt;a href="http://de.wikipedia.org/wiki/CLDC"&gt;CLDC&lt;/a&gt;-Entwicklung auf Mac OS X. Enthalten ist außerdem der JavaFX 1.2.1 Mobile Emulator.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_1bA4Fk08GL0/Sv07ym8I7zI/AAAAAAAAACA/W6XHd3rMf7g/s1600-h/javamesdk30.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 182px;" src="http://2.bp.blogspot.com/_1bA4Fk08GL0/Sv07ym8I7zI/AAAAAAAAACA/W6XHd3rMf7g/s320/javamesdk30.png" alt="" id="BLOGGER_PHOTO_ID_5403540868546752306" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-4380944167266625797?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/4380944167266625797/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/11/java-me-sdk-30-fur-mac-os-x.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4380944167266625797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4380944167266625797'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/11/java-me-sdk-30-fur-mac-os-x.html' title='Java ME SDK 3.0 für Mac OS X'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_1bA4Fk08GL0/Sv07ym8I7zI/AAAAAAAAACA/W6XHd3rMf7g/s72-c/javamesdk30.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-1664838522434524364</id><published>2009-11-13T08:05:00.006+01:00</published><updated>2009-11-13T11:18:53.180+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='VisualVM'/><title type='text'>VisualVM 1.2</title><content type='html'>Nachdem im Oktober Version 1.2 des Monitoring- und Profiling-Werkzeugs &lt;a href="https://visualvm.dev.java.net/"&gt;VisualVM&lt;/a&gt; veröffentlicht wurde, folgte Anfang dieser Woche das Bugfix-Release 1.2.1. Beide Versionen basieren auf dem Profiler von NetBeans 6.7.1.&lt;br /&gt;&lt;br /&gt;Neu ist u.a. die stabile Version des "Sampler"-Plugins, mit dem schnell ein einfaches (aber oft schon vollkommen ausreichendes) CPU- und Speicher-Profiling durchgeführt werden kann. Wie die übrigens Plugins muss auch dieses im Menü Tools &amp;gt; Plugins installiert werden:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_1bA4Fk08GL0/Sv0xX0N_wZI/AAAAAAAAAB4/oRCvuHblbOo/s1600-h/vvm121-plugins.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 222px;" src="http://2.bp.blogspot.com/_1bA4Fk08GL0/Sv0xX0N_wZI/AAAAAAAAAB4/oRCvuHblbOo/s320/vvm121-plugins.png" alt="" id="BLOGGER_PHOTO_ID_5403529413138563474" border="0" /&gt;&lt;/a&gt;Außerdem kann man nun endlich eventuell notwendige Proxy-Einstellungen innerhalb von VisualVM vornehmen. Weitere Änderungen und Ergänzungen sind &lt;a href="https://visualvm.dev.java.net/relnotes.html"&gt;hier&lt;/a&gt; aufgelistet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-1664838522434524364?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/1664838522434524364/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/11/visualvm-12.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1664838522434524364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1664838522434524364'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/11/visualvm-12.html' title='VisualVM 1.2'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_1bA4Fk08GL0/Sv0xX0N_wZI/AAAAAAAAAB4/oRCvuHblbOo/s72-c/vvm121-plugins.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-3825133011107268201</id><published>2009-11-03T07:58:00.001+01:00</published><updated>2009-11-03T10:51:54.797+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GlassFish'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Java EE SDK unter Snow Leopard installieren</title><content type='html'>Mac OS X 10.6 "Snow Leopard" enthält Java SE 6 als einzige Java-Laufzeitumgebung (und nicht mehr Java 1.4, 5.0 und 6 wie Mac OS X 10.5). Das bringt ein Problem mit sich, wenn man Suns aktuelles &lt;a href="http://java.sun.com/javaee/downloads/"&gt;Java EE 5 SDK Update 7&lt;/a&gt; installieren möchte, denn das Installationsskript ist fest verdrahtet auf ein installiertes Java 5 angewiesen. Im System sind zwar die Ordner für Java 5.0 vorhanden, die verweisen aber auf die Java 6-Installation – und das reicht dem Skript leider nicht aus.&lt;br /&gt;&lt;br /&gt;Im konkreten Fall haben wir das Archiv &lt;code&gt;java_ee_sdk-5_07-mac-nojdk.zip&lt;/code&gt; (&lt;a href="http://java.sun.com/javaee/downloads/"&gt;Download&lt;/a&gt; "GlassFish Java EE") ausgepackt und zu installieren versucht:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;HeartOfGold:java_ee_sdk-5_07-mac-nojdk much$ chmod a+rx setup&lt;br /&gt;HeartOfGold:java_ee_sdk-5_07-mac-nojdk much$ ./setup&lt;br /&gt;Installer cannot find a suitable 1.5.x version of JDK under the&lt;br /&gt;following directories.&lt;br /&gt;&lt;br /&gt;1. /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home&lt;br /&gt;2. /Library/Java/Home&lt;br /&gt;&lt;br /&gt;Please rerun with -javahome argument pointing to a valid 1.5 version of JDK.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Zum Glück ist die Lösung recht einfach (man muss dafür kein altes Java 5.0 aus Mac OS X 10.5 installieren). In der Skript-Datei &lt;code&gt;setup&lt;/code&gt; ersetzt man mit einem &lt;a href="http://smultron.sourceforge.net/"&gt;Texteditor&lt;/a&gt; in Zeile 54 einfach am Ende der Zeile "1.5" durch "1.6":&lt;br /&gt;&lt;pre&gt;54: javaVersion=`${TIGER_JAVAHOME} ... ${GREP} &lt;b&gt;1.6&lt;/b&gt;`&lt;br /&gt;&lt;/pre&gt;Das war es dann auch schon! Der Installer lässt sich nun auch mit Java 6 problemlos ausführen, und GlassFish läuft auch (bzw. gerade) mit dem aktuellen JRE hervorragend.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-3825133011107268201?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/3825133011107268201/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/11/java-ee-sdk-unter-snow-leopard.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3825133011107268201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3825133011107268201'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/11/java-ee-sdk-unter-snow-leopard.html' title='Java EE SDK unter Snow Leopard installieren'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-4598335232612938680</id><published>2009-10-15T19:57:00.001+02:00</published><updated>2009-10-15T22:04:13.856+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><title type='text'>IntelliJ IDEA 9: Community Edition und Open Source</title><content type='html'>Die Entwicklungsumgebung &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt; ist seit längerem &lt;span style="font-style: italic;"&gt;der&lt;/span&gt; Geheimtipp für Java-Entwickler. Doch während Eclipse und NetBeans kostenlos erhältlich und weit verbreitet sind, schreckten viele vor dem dreistelligen Kaufpreis für eine IDE(A) zurück.&lt;br /&gt;&lt;br /&gt;Mit der kommenden Version 9.0 wird IntelliJ IDEA nun &lt;a href="http://www.jetbrains.org/"&gt;Open Source&lt;/a&gt; und steht seit heute auch in einer kostenlosen &lt;a href="http://www.jetbrains.com/idea/nextversion/free_java_ide.html"&gt;Community Edition&lt;/a&gt; zur Verfügung. Mit dieser Edition kann Java SE, Groovy und Scala programmiert werden (inkl. Debugging, Refactoring, Testen, Versionsverwaltung etc.).&lt;br /&gt;&lt;br /&gt;Für die Entwicklung von Web- und Enterprise-Applikationen wird die weiterhin kostenpflichtige Ultimate Edition benötigt, die neben aktuellen und künftigen Standards (Java EE 6 etc.) zahlreiche Programmiersprachen, Frameworks und Versionsverwaltungssysteme zusätzlich unterstützt.&lt;br /&gt;&lt;br /&gt;Fazit: Für professionelle JEE-Entwicklung ist zwar nach wie vor die kostenpflichtige Ultimate Edition notwendig, aber zumindest kann sich nun jeder einen ausführlichen Eindruck von IntelliJ verschaffen. Und das hat diese Entwicklungsumgebung durchaus verdient.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-4598335232612938680?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/4598335232612938680/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/10/intellij-idea-9-community-edition-und.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4598335232612938680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4598335232612938680'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/10/intellij-idea-9-community-edition-und.html' title='IntelliJ IDEA 9: Community Edition und Open Source'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-1088901860404659462</id><published>2009-10-13T21:52:00.002+02:00</published><updated>2009-10-13T22:33:40.209+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Snow Leopard und Rosetta</title><content type='html'>Schon seit den ersten Mac OS X-Versionen können Java-Applikationen in einer speziellen Verzeichnisstruktur als "normale" Mac OS X-Anwendung verpackt werden, so dass sie u.a. mit einem eigenen Programmsymbol dargestellt werden. Damit solche &lt;a href="http://en.wikipedia.org/wiki/Application_Bundle"&gt;Application Bundles&lt;/a&gt; Java-Bytecode ausführen können, enthalten sie als nativen &lt;a href="http://en.wikipedia.org/wiki/Mach-O"&gt;Mach-O&lt;/a&gt;-Startcode im Verzeichnis &lt;code&gt;/Contents/MacOS/&lt;/code&gt; die Datei &lt;code&gt;JavaApplicationStub&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1bA4Fk08GL0/StTYvT4DWOI/AAAAAAAAABw/_nqeEEk-7z0/s1600-h/JavaApplicationStub.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 122px;" src="http://3.bp.blogspot.com/_1bA4Fk08GL0/StTYvT4DWOI/AAAAAAAAABw/_nqeEEk-7z0/s320/JavaApplicationStub.png" alt="" id="BLOGGER_PHOTO_ID_5392172961170151650" border="0" /&gt;&lt;/a&gt;Führt man ältere, noch unter &lt;a href="http://de.wikipedia.org/wiki/PowerPC"&gt;PowerPC&lt;/a&gt; (PPC) Mac OS X zusammengebaute Java-Application-Bundles unter Mac OS X 10.6 "Snow Leopard" aus, erhält man eventuell den Hinweis, dass man  den auf der Snow-Leopard-Installations-DVD enthaltenen PPC-Emulator "&lt;a href="http://de.wikipedia.org/wiki/Rosetta_%28Apple%29"&gt;Rosetta&lt;/a&gt;" installieren muss, um die Anwendung starten zu können. Obwohl Apple seit Mac OS X 10.4 alte PPC-JavaApplicationStubs erkennt und als 32-Bit-Intel-Prozess neu startet, muss dafür Rosetta installiert sein – und genau das ist seit Snow Leopard nicht mehr standardmäßig der Fall.&lt;br /&gt;&lt;br /&gt;Die einfachste Lösung, die zudem Rosetta nicht benötigt, ist, den alten Stub im Application Bundle durch eine Kopie der aktuelle Version &lt;code&gt;/System/Library/Frameworks/JavaVM.framework/Resources/MacOS/JavaApplicationStub&lt;/code&gt; zu ersetzen. Dieser neue Stub enthält Code für die drei derzeit unterstützten Prozessorarchitekturen:&lt;br /&gt;&lt;pre&gt;Straylight:~ much$ file JavaApplicationStub&lt;br /&gt;JavaApplicationStub: Mach-O universal binary with 3 architectures&lt;br /&gt;JavaApplicationStub (for architecture x86_64):  Mach-O 64-bit executable x86_64&lt;br /&gt;JavaApplicationStub (for architecture i386):    Mach-O executable i386&lt;br /&gt;JavaApplicationStub (for architecture ppc7400): Mach-O executable ppc&lt;br /&gt;&lt;/pre&gt;Wenn eine Java-Anwendung eine bestimmte Architektur nicht benötigt (z.B. weil nachgeladene JNI-Bibliotheken dafür nicht compiliert wurden), kann und sollte der entsprechende Code mit &lt;code&gt;/usr/bin/lipo&lt;/code&gt; entfernt werden.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-1088901860404659462?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/1088901860404659462/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/10/snow-leopard-und-rosetta.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1088901860404659462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1088901860404659462'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/10/snow-leopard-und-rosetta.html' title='Snow Leopard und Rosetta'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_1bA4Fk08GL0/StTYvT4DWOI/AAAAAAAAABw/_nqeEEk-7z0/s72-c/JavaApplicationStub.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-7171170464663846666</id><published>2009-09-01T22:03:00.003+02:00</published><updated>2009-09-01T22:08:21.016+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Java in Mac OS X 10.6 "Snow Leopard"</title><content type='html'>Der &lt;a href="http://www.apple.com/de/macosx/"&gt;Schneeleopard&lt;/a&gt; ist also aus dem Käfig... Und während das nun "alte" Mac OS X 10.5 noch drei Implementierungen für Java 1.4, 5.0 und 6 mitbrachte, enthält Mac OS X 10.6 ausschließlich Java SE 6 (1.6.0_15) in einer 32-Bit- und einer 64-Bit-Version. Detaillierte Informationen zu beseitigten und bekannten Fehlern enthalten die &lt;a href="http://developer.apple.com/mac/library/releasenotes/Java/JavaSnowLeopardRN/Introduction/Introduction.html"&gt;Release Notes&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Damit auch Java 5-Anwendungen weitestgehend problemlos laufen, sind im Ordner &lt;tt&gt;/System/Library/Frameworks/JavaVM.framework/Versions&lt;/tt&gt; noch die Unterordner &lt;tt&gt;1.5&lt;/tt&gt; und &lt;tt&gt;1.5.0&lt;/tt&gt; enthalten, aber beide sind Aliase (Symlinks) auf die Java 6-Implementierung.&lt;br /&gt;&lt;br /&gt;Und obwohl &lt;a href="http://developer.apple.com/quicktime/qtjava/"&gt;QuickTime for Java&lt;/a&gt; schon seit längerem nicht mehr offiziell unterstützt wird, sind die QTJava-Bibliotheken immer noch vorhanden und funktionieren auch mit Java 6.&lt;br /&gt;&lt;br /&gt;Mal abwarten, was die praktischen Erfahrungen in den kommenden Tagen zeigen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-7171170464663846666?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/7171170464663846666/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/09/java-in-mac-os-x-106-snow-leopard.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7171170464663846666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7171170464663846666'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/09/java-in-mac-os-x-106-snow-leopard.html' title='Java in Mac OS X 10.6 &quot;Snow Leopard&quot;'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-6437927235208183903</id><published>2009-08-26T19:44:00.004+02:00</published><updated>2009-08-26T20:45:27.721+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaFX'/><category scheme='http://www.blogger.com/atom/ns#' term='Funktionale Programmierung'/><category scheme='http://www.blogger.com/atom/ns#' term='JVM'/><title type='text'>Closures in JavaFX Script</title><content type='html'>&lt;a href="http://java.sun.com/javafx/reference/docs.jsp#learn_javafx"&gt;JavaFX Script&lt;/a&gt; (die Programmiersprache für Suns neue &lt;a href="http://de.wikipedia.org/wiki/Rich_Internet_Application"&gt;RIA&lt;/a&gt;-Technologie &lt;a href="http://javafx.com/"&gt;JavaFX&lt;/a&gt;) ist eine objektorientierte, deklarative und funktionale Programmiersprache.&lt;br /&gt;&lt;br /&gt;Als funktionale Sprache unterstützt sie Funktionen höherer Ordnung (first-class functions) und Funktionsabschlüsse (Closures). Ersteres bedeutet, dass Funktionen selber Werte sind – sie können also als Parameter übergeben und zurückgegeben werden. Letzteres erlaubt den Funktionswerten, dass sie sich den Zustand ihrer Umgebung (die lokalen Variablen) bei ihrer Erzeugung merken können.&lt;br /&gt;&lt;br /&gt;Für viele sind Closures seltsame Konstrukte und ihre Einsatzmöglichkeiten nicht offensichtlich. Daher im Folgenden ein kleines, relativ leicht verständliches Beispiel, in dem mehrere Zähler mit individuellen Startwerten erzeugt und benutzt werden:&lt;br /&gt;&lt;pre&gt;// closure.fx&lt;br /&gt;&lt;br /&gt;function zaehlerMitStartwert(startwert: Integer) {&lt;br /&gt;  var n = startwert;&lt;br /&gt;  &lt;span style="color:lightgrey;"&gt;return&lt;/span&gt; function()&lt;span style="color:lightgrey;"&gt;: Integer&lt;/span&gt; { &lt;span style="color:lightgrey;"&gt;return&lt;/span&gt; n++ }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var next1 = zaehlerMitStartwert(10);&lt;br /&gt;var next2 = zaehlerMitStartwert(20);&lt;br /&gt;&lt;br /&gt;println( next1() ); // 10&lt;br /&gt;println( next2() ); // 20&lt;br /&gt;println( next2() ); // 21&lt;br /&gt;println( next1() ); // 11&lt;br /&gt;&lt;/pre&gt;Wer das Beispiel ausprobieren möchte, installiert sich das &lt;a href="http://java.sun.com/javafx/downloads/"&gt;JavaFX 1.2 SDK&lt;/a&gt; und nutzt die Kommandozeile (oder &lt;a href="http://www.netbeans.org/servlets/NewsItemView?newsItemID=1407"&gt;NetBeans&lt;/a&gt; oder &lt;a href="http://javafx.com/docs/gettingstarted/eclipse-plugin/"&gt;Eclipse mit dem JavaFX-Plugin&lt;/a&gt;):&lt;br /&gt;&lt;pre&gt;Straylight:~ much$ javafxc closure.fx&lt;br /&gt;Straylight:~ much$ javafx closure&lt;br /&gt;10&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;11&lt;br /&gt;&lt;/pre&gt;Die ausgegrauten Elemente sind nicht wirklich notwendig und sollen nur das Skript für Java-Programmierer leichter verständlich machen. "return" ist an beiden Stellen optional, da der letzte Ausdruck in einer Funktion gleichzeitig deren Ergebnis definiert. Der Rückgabetyp ":Integer" der inneren, anonymen Funktion ist optional, da aus dem Datentyp des Ergebnisses der Rückgabetyp durch &lt;a href="http://de.wikipedia.org/wiki/Typinferenz"&gt;Typinferenz&lt;/a&gt; ermittelt werden kann.&lt;br /&gt;&lt;br /&gt;Trotz (bzw. gerade wegen) dieser impliziten Typisierung ist JavaFX Script im Gegensatz zu &lt;a href="http://de.wikipedia.org/wiki/Skriptsprache"&gt;Skriptsprachen&lt;/a&gt; wie JavaScript statisch und streng typisiert. Bereits der Compiler ermittelt also die Datentypen und Signaturen von Variablen und Funktionen, sofern sie nicht explizit angegeben sind. Im Beispiel hat die Variable &lt;code&gt;n&lt;/code&gt; also den Datentyp &lt;code&gt;Integer&lt;/code&gt;, die Variablen &lt;code&gt;next1&lt;/code&gt; und &lt;code&gt;next2&lt;/code&gt; haben den Typ &lt;code&gt;function():Integer&lt;/code&gt; und &lt;code&gt;zaehlerMitStartwert&lt;/code&gt; hat den Typ &lt;code&gt;function(:Integer):function():Integer&lt;/code&gt; :-)&lt;br /&gt;&lt;br /&gt;Wie funktioniert das Skript? Beim Aufruf der Funktion &lt;code&gt;zaehlerMitStartwert&lt;/code&gt; wird eine Funktion zurückgegeben, die bei jedem Aufruf die Variable &lt;code&gt;n&lt;/code&gt; um eins erhöht zurückgibt. Obwohl die Variable &lt;code&gt;n&lt;/code&gt; zur äußeren Funktion gehört und damit beim Aufruf der zurückgegebenen Funktion mit &lt;code&gt;next1()&lt;/code&gt; bzw. &lt;code&gt;next2()&lt;/code&gt; eigentlich gar nicht mehr vorhanden ist, merkt sich die innere Funktion die lokale Variable separat für jede zurückgegebene innere Funktion &amp;ndash; und genau das macht sie zur Closure.&lt;br /&gt;&lt;br /&gt;Man kann sich Closures als Objekte vorstellen, die aus einer einzigen Methode/Funktion bestehen und wie Objekte zusätzlich einen Zustand haben. Schön sehen kann man dies an den generierten Java-Bytecode-Klassendateien: &lt;code&gt;closure.class&lt;/code&gt; und &lt;code&gt;closure$1.class&lt;/code&gt;. Die innere, anonyme Funktion wird für die JVM also einfach als innere, anonyme Java-Klasse &lt;code&gt;closure$1.class&lt;/code&gt; abgebildet.&lt;br /&gt;&lt;br /&gt;Closures sind prima geeignet, um damit z.B. Event-Handler zu definieren, denen man zusätzliche Informationen mitgeben kann (bei Farb-Setz-Buttons in einem Grafikprogramm beispielsweise die zu setzende Farbe). Dadurch kann man häufig auf das Schreiben von Event-Handler-Klassen verzichten, auch wenn dies in JavaFX Script ebenfalls möglich ist.&lt;br /&gt;&lt;br /&gt;Vielleicht hat man es gemerkt: Ich halte JavaFX Script trotz des Namens ganz und gar nicht für eine Skriptsprache. Meines Erachtens wurde die Sprache vor allem deshalb so genannt, um zu zeigen, dass man damit in Wettbewerb zu Skriptsprachen wie Ruby tritt, die als agil und produktiv empfunden werden. JavaFX Script zeigt dabei sehr schön, dass sich Produktivität und statische, strenge Typisierung überhaupt nicht ausschließen müssen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-6437927235208183903?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/6437927235208183903/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/08/closures-in-javafx-script.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6437927235208183903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6437927235208183903'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/08/closures-in-javafx-script.html' title='Closures in JavaFX Script'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-4621124409894167371</id><published>2009-08-25T20:35:00.005+02:00</published><updated>2009-08-25T20:55:12.999+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Hibernate 3.5 und JPA 2.0</title><content type='html'>Vor wenigen Tagen wurde die erste &lt;a href="http://in.relation.to/12153.lace"&gt;Betaversion von Hibernate 3.5&lt;/a&gt; veröffentlicht. Sofern der &lt;a href="https://www.hibernate.org/6.html"&gt;Download&lt;/a&gt; von SourceForge klappt, kann man damit viele der Neuerungen von &lt;a href="http://jcp.org/en/jsr/detail?id=317"&gt;JPA 2.0 &lt;/a&gt;ausprobieren.&lt;br /&gt;&lt;br /&gt;Hibernate 3.5 bietet keine wesentlichen neuen Hibernate-Features, und auch für die Unterstützung der neuen JPA-Version wurden vor allem standardkonforme Schnittstellen für bereits vorhandene Hibernate-Eigenschaften bereitgestellt. Dies ist wohl auch der Grund, warum die Hibernate-Version nicht gleich auf 4.0 heraufgesetzt wurde.&lt;br /&gt;&lt;br /&gt;Schön ist meines Erachtens, dass ab Version 3.5 die JARs für die Hibernate-Annotationen und den JPA-EntityManager Bestandteil vom Hibernate-Kern (Core) geworden sind. Und die Einbindung von &lt;a href="http://jboss.org/envers/"&gt;Envers&lt;/a&gt; dürfte diese Versionierungs-Bibliothek zum heißen Kandidaten für den De-Facto-Standard bezüglich Versionierung/Historisierung/Auditierung mit JPA machen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-4621124409894167371?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/4621124409894167371/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/08/hibernate-35-und-jpa-20.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4621124409894167371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4621124409894167371'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/08/hibernate-35-und-jpa-20.html' title='Hibernate 3.5 und JPA 2.0'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-6714094748596122656</id><published>2009-07-22T23:09:00.007+02:00</published><updated>2009-07-23T14:06:41.213+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GlassFish'/><category scheme='http://www.blogger.com/atom/ns#' term='Annotationen'/><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Serialisierung'/><title type='text'>Lokaler Aufruf von @Remote in GlassFish</title><content type='html'>GlassFish muss als Java EE 5-konformer Application-Server beim Aufruf von EJB-@Remote-Interfaces die Übergabeparameter und Rückgabewerte kopieren (serialisieren). Der Aufruf erfolgt also mit Wert-Semantik ("pass-by-value"), selbst wenn der Aufrufer und die aufgerufene Session-Bean innerhalb derselben JVM laufen ("co-located") und der Aufruf damit prinzipiell lokal erfolgen könnte (durch Über-/Rückgabe von Referenzen, entsprechend "pass-by-reference" genannt).&lt;br /&gt;&lt;br /&gt;Obwohl GlassFish den eigentlichen Remote-&lt;span style="font-style: italic;"&gt;Aufruf&lt;/span&gt; bereits gut optimiert, wenn sich Aufrufer und aufgerufene Bean auf demselben Server befinden, kostet das Kopieren der Parameter Zeit und Speicher. Wenn die Parameter große Datenmengen beinhalten, kann es sich daher als &lt;a href="http://docs.sun.com/app/docs/doc/820-4343/abecg"&gt;Performanz-Optimierung&lt;/a&gt; lohnen, die Parameter des lokalen Remote-Aufrufs entgegen der Spezifikation als Referenz übergeben zu lassen.  Man muss dann aber bedenken, dass Änderungen an den Parameterdaten – wie bei @Local-Aufrufen – an allen Stellen sichtbar sind, die eine Referenz darauf halten.&lt;br /&gt;&lt;br /&gt;Aktivieren lässt sich der lokale Aufruf von @Remote-Methoden in GlassFish für eine komplette Enterprise-Applikation (EAR) im &lt;a href="http://docs.sun.com/app/docs/doc/820-4337/6nfqe0sdp"&gt;sun-application.xml&lt;/a&gt;-Deskriptor wie folgt:&lt;br /&gt;&lt;pre&gt;&amp;lt;sun-application&amp;gt;&lt;br /&gt;  &amp;lt;pass-by-reference&gt;true&amp;lt;/pass-by-reference&amp;gt;&lt;br /&gt;&amp;lt;/sun-application&amp;gt;&lt;br /&gt;&lt;/pre&gt;Oder für einzelne EJBs in &lt;a href="http://docs.sun.com/app/docs/doc/820-4337/beaya"&gt;sun-ejb-jar.xml&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&amp;lt;sun-ejb-jar&amp;gt;&lt;br /&gt;  &amp;lt;enterprise-beans&amp;gt;&lt;br /&gt;    &amp;lt;ejb&amp;gt;&lt;br /&gt;      &amp;lt;pass-by-reference&gt;true&amp;lt;/pass-by-reference&amp;gt;&lt;br /&gt;    &amp;lt;/ejb&amp;gt;&lt;br /&gt;  &amp;lt;/enterprise-beans&amp;gt;&lt;br /&gt;&amp;lt;/sun-ejb-jar&amp;gt;&lt;br /&gt;&lt;/pre&gt;Achtung: Zumindest GlassFish 2.1 scheint einen &lt;a href="https://glassfish.dev.java.net/issues/show_bug.cgi?id=7207"&gt;Bug&lt;/a&gt; zu haben, dass die Einstellung in &lt;code&gt;sun-application.xml&lt;/code&gt; ignoriert wird, wenn sich in einem EJB-Modul (EJB-JAR) kein &lt;code&gt;sun-ejb-jar.xml&lt;/code&gt; befindet. Abhilfe: Einfach einen (abgesehen vom Wurzel-Element) leeren Deskriptor ergänzen.&lt;br /&gt;&lt;br /&gt;Und nochmal Achtung: Offenbar klappt die Optimierung nur innerhalb einer Anwendung (EAR), nicht aber zwischen mehreren separaten Anwendungen bzw. EJB-Modulen auf demselben Server.&lt;br /&gt;&lt;br /&gt;Warum will man überhaupt eine nicht standardkonforme Referenz-Übergabe aktivieren? Kann man nicht besser @Local-Interfaces verwenden, die die erwähnten Performanz-Vorteile sowieso mit sich bringen? Ja, man sollte &lt;a href="http://docs.sun.com/app/docs/doc/820-4343/abecg"&gt;@Local-Interfaces nach Möglichkeit bevorzugen&lt;/a&gt;.&lt;br /&gt;Es gibt aber Fälle, bei denen man nicht schon bei der Programmierung entscheiden kann bzw. möchte, wie die Bean-Aufrufe durchgeführt werden, beispielsweise weil man sich die Option offen halten möchte, ob Frontend (WAR) und Backend (EJB-JAR) gemeinsam in einem EAR oder aber separat bereitgestellt ("deployed") werden. Im Quelltext wird man dann die @Remote-Variante programmieren, hat aber mit dem &lt;code&gt;pass-by-reference&lt;/code&gt;-Schalter später per Konfiguration die Möglichkeit, die Aufrufart einfach und schnell umzustellen.&lt;br /&gt;&lt;br /&gt;Sinnvoll erscheint dies vor allem dann, wenn man viele EJBs entfernt aufruft und alle Aufrufe auf einen Schlag optimieren will. Wenn man dagegen nur wenige EJBs entfernt nutzt oder nur einzelne Aufrufe optimieren möchte, kann man die Aufrufart – wenn auch mit etwas mehr Aufwand – über die Standard-XML-Deskriptoren ändern. Eine mögliche Realisierung ist &lt;a href="http://thomas-schuett.de/2009/01/31/local-remoteinterfaces-per-konfiguration-nutzen/"&gt;hier&lt;/a&gt; beschrieben.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-6714094748596122656?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/6714094748596122656/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/07/lokaler-aufruf-von-remote-in-glassfish.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6714094748596122656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6714094748596122656'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/07/lokaler-aufruf-von-remote-in-glassfish.html' title='Lokaler Aufruf von @Remote in GlassFish'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-6402762995876439319</id><published>2009-07-16T20:04:00.009+02:00</published><updated>2009-07-16T21:09:39.915+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Sein oder !sein, das ist hier die Frage</title><content type='html'>Echte C-Freaks werden mich dafür verachten, aber ich finde ausgeschriebene boolesche Operatoren wie &lt;code&gt;not&lt;/code&gt;, &lt;code&gt;and&lt;/code&gt; und &lt;code&gt;or&lt;/code&gt; einfach lesbarer als &lt;code&gt;!&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; und &lt;code&gt;||&lt;/code&gt; (und ja, ich habe jahrelang C und C++ programmiert und weiß, wovon ich rede). Ein Beispiel:&lt;br /&gt;&lt;pre&gt;  if (!liste.isEmpty()) { ... }&lt;br /&gt;&lt;br /&gt;  if (not(liste.isEmpty())) { ... }&lt;br /&gt;&lt;/pre&gt;M.E. ist das Ausrufungszeichen beim Durchsehen des Quelltextes viel zu leicht zu übersehen (und Code wird normalerweise viel häufiger gelesen als geschrieben).&lt;br /&gt;&lt;br /&gt;Während beispielsweise die &lt;a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnahq.html#bnaik"&gt;EL&lt;/a&gt; beide Schreibweisen erlaubt, kennt Java leider nur die Symbol-Operatoren. Was tun? Zumindest für den Präfix-Operator &lt;code&gt;not&lt;/code&gt; kann man statische Methoden definieren, die sich dann mittels &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/static-import.html"&gt;statischer Imports&lt;/a&gt; wie in obigem Beispiel nutzen lassen:&lt;br /&gt;&lt;pre&gt;  public static boolean not(boolean bval) {&lt;br /&gt;    return !bval;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static Boolean not(Boolean bval) {&lt;br /&gt;    if (bval == null) {&lt;br /&gt;      return null;&lt;br /&gt;    }&lt;br /&gt;    else {&lt;br /&gt;      return !bval;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;(Den kompletten Quelltext gibt es &lt;a href="http://www.muchsoft.com/java/source/Bool.java"&gt;hier&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;Nur: Muss man sich diese Methoden selber schreiben, oder gibt es dafür bereits fertige Bibliotheken? Im Netz habe ich leider nichts passendes gefunden.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-6402762995876439319?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/6402762995876439319/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/07/sein-oder-sein-das-ist-hier-die-frage.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6402762995876439319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6402762995876439319'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/07/sein-oder-sein-das-ist-hier-die-frage.html' title='Sein oder !sein, das ist hier die Frage'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-8823711355117503928</id><published>2009-07-09T19:52:00.003+02:00</published><updated>2009-07-09T20:10:13.348+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>java_home oder /Library/Java/Home?</title><content type='html'>Es ist immer wieder eine spannende Frage, wie man in Mac OS X die Standard-Java-Version einstellt bzw. wie man die für eine bestimmte Anwendung "richtige" Java-Version herausbekommt. Mac OS X 10.5 unterstützt derzeit bis zu drei verschiedene Hauptversionen (1.4.2, 1.5.0, 1.6.0), teils als 32-Bit-, teils als 64-Bit-Variante.&lt;br /&gt;&lt;br /&gt;Bisher konnten Anwender die bevorzugte Java-Version getrennt für Applets und für andere Anwendungen (Web Start, Kommandozeile) mit &lt;code&gt;/Programme/Dienstprogramme/Java/Java-Einstellungen&lt;/code&gt; konfigurieren. Alternativ konnte man natürlich auch die Umgebungsvariable &lt;code&gt;JAVA_HOME&lt;/code&gt; setzen oder sich auf den festen Pfad &lt;code&gt;/Library/Java/Home&lt;/code&gt; verlassen. Und weil diese Möglichkeiten immer noch nicht bei allen Anwendungen funktionierten, verbogen die ganz Wagemutigen diverse Symlinks im JavaVM-Framework (was aber auch nicht immer klappte und zu diversen Fehlern führte).&lt;br /&gt;&lt;br /&gt;Bevor wir uns um die empfohlene Lösung kümmern, hier zunächst eine Warnung: &lt;span style="font-style: italic;"&gt;Basteln Sie &lt;span style="font-weight: bold;"&gt;niemals&lt;/span&gt; an den Symlinks in &lt;code&gt;/System/Library/Frameworks/JavaVM.framework&lt;/code&gt; (und in Unterordnern davon) herum! Auch dann nicht, wenn Sie viele gutgemeinte Tipps finden, wie man &lt;code&gt;Current&lt;/code&gt; und &lt;code&gt;CurrentJDK&lt;/code&gt; verbiegen kann... Apple weist seit langem darauf hin, dass diese Symlinks interne Implementationsdetails sind, die sich jederzeit ändern können.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mit dem &lt;a href="http://support.apple.com/downloads/Java_for_Mac_OS_X_10_5_Update_4"&gt;aktuellen Java-Update für Mac OS X 10.5&lt;/a&gt; liefert Apple nun ein Kommandozeilenprogramm aus, mit dem sich die Benutzereinstellungen aus &lt;code&gt;/Programme/Dienstprogramme/Java-Einstellungen&lt;/code&gt; auslesen lassen (beachten Sie, dass der &lt;code&gt;Java&lt;/code&gt;-Unterordner in dem Pfad mit diesem Update verschwunden ist):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;HeartOfGold:~ much$ &lt;b&gt;/usr/libexec/java_home&lt;/b&gt;&lt;br /&gt;/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Ein Aufruf mit der Option &lt;code&gt;-h&lt;/code&gt; zeigt alle erlaubten Optionen an. Eine Liste aller verfügbaren JVMs – in der in den Java-Einstellungen festgelegten Reihenfolge – erhalten wir mit &lt;code&gt;--verbose&lt;/code&gt;:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;HeartOfGold:~ much$ &lt;b&gt;/usr/libexec/java_home --verbose&lt;/b&gt;&lt;br /&gt;Matching Java Virtual Machines (4):&lt;br /&gt;1.5.0_19 (i386):   /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home&lt;br /&gt;1.6.0_13 (x86_64): /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home&lt;br /&gt;1.5.0_19 (x86_64): /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home&lt;br /&gt;1.4.2_21 (i386):   /System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/Home&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Man kann auch ganz gezielt nach einer bestimmten Java-Version und/oder Prozessorarchitektur fragen:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;HeartOfGold:~ much$ &lt;b&gt;/usr/libexec/java_home --version 1.6 --arch x86_64&lt;/b&gt;&lt;br /&gt;/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Sofern die gewünschte JVM nicht vorhanden ist, erhält man eine Fehlermeldung und eine hoffentliche passende alternative JVM:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;HeartOfGold:~ much$ &lt;b&gt;/usr/libexec/java_home --version 1.6 --arch i386&lt;/b&gt;&lt;br /&gt;Unable to find any JVMs matching architecture "i386".&lt;br /&gt;/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Zurück zur Ausgangsfrage. Wie finden wir damit z.B. in einem Shell-Skript die passende Java-Version für eine Anwendung? Apple empfiehlt folgendes Vorgehen:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Prüfen Sie, ob &lt;code&gt;/usr/libexec/java_home&lt;/code&gt; vorhanden ist, übergeben Sie optional die gewünschte Java-Version und werten Sie die Rückgabe aus.&lt;/li&gt;&lt;li&gt;Wenn das nicht erfolgreich war, verwenden Sie als Java-Home-Verzeichnis fest kodiert (!) das Verzeichnis &lt;code&gt;/System/Library/Frameworks/JavaVM.framework/Versions/&lt;span style="font-style: italic;"&gt;1.X&lt;/span&gt;/Home&lt;/code&gt;, wobei Sie "1.X" durch die gewünschte Versionsnummer (1.4, 1.5, 1.6) ersetzen.&lt;/li&gt;&lt;li&gt;Sollte das Verzeichnis nicht existieren, verwenden Sie &lt;code&gt;/Library/Java/Home&lt;/code&gt; (und beten, das alles klappt).&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;100% perfekt ist das m.E. zwar nicht, denn Punkt 2 geht schief, wenn das Verzeichnis für Java 6 existiert, Java 6 aber nicht ausgeführt werden kann (das betrifft vor allem 32-Bit CoreDuo-Macs). Aber immerhin hat Apple nun dokumentiert, wie man künftig – und in den meisten Fällen auch bisher – zum korrekten Ergebnis gelangt.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Und was ist mit der Umgebungsvariable &lt;code&gt;JAVA_HOME&lt;/code&gt;? Offenbar werten diverse Systemprogramme (wie &lt;code&gt;/usr/bin/java&lt;/code&gt;) nicht nur die Rückgabe von &lt;code&gt;/usr/libexec/java_home&lt;/code&gt; aus, sondern auch den Wert von &lt;code&gt;JAVA_HOME&lt;/code&gt;. Wenn sich die Werte unterscheiden, kann das zu unerwartetem Verhalten führen... Insofern sollte mittelfristig auf das Setzen von &lt;code&gt;JAVA_HOME&lt;/code&gt; besser verzichtet werden.&lt;br /&gt;&lt;br /&gt;Da sich aber kurzfristig viele Anwendungen noch auf die Umgebungsvariable &lt;code&gt;JAVA_HOME&lt;/code&gt; verlassen, ist es derzeit m.E. am besten, die Variable auf die Java-Version zu setzen, die auch in den Java-Einstellungen an oberster Stelle steht (auch wenn das erst einmal doppelten Konfigurationsaufwand bedeutet). Das Setzen der Variablen geschieht am einfachsten mit &lt;a href="http://www.rubicode.com/Software/RCEnvironment/"&gt;RCEnvironment&lt;/a&gt;, wodurch die Variable sowohl Shell-Skripten als auch GUI-Anwendungen bekannt ist:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1bA4Fk08GL0/SlWq7C1TCII/AAAAAAAAABo/P5JBYXHpkIE/s1600-h/rcenvironment.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 219px;" src="http://3.bp.blogspot.com/_1bA4Fk08GL0/SlWq7C1TCII/AAAAAAAAABo/P5JBYXHpkIE/s320/rcenvironment.png" alt="" id="BLOGGER_PHOTO_ID_5356375263176493186" border="0" /&gt;&lt;/a&gt;Eine ausführliche Diskussion rund um &lt;code&gt;java_home&lt;/code&gt; findet sich auf &lt;a href="http://lists.apple.com/archives/java-dev/2009/May/msg00212.html"&gt;Apples Java-Mailingliste&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-8823711355117503928?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/8823711355117503928/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/07/javahome-oder-libraryjavahome.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/8823711355117503928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/8823711355117503928'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/07/javahome-oder-libraryjavahome.html' title='java_home oder /Library/Java/Home?'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_1bA4Fk08GL0/SlWq7C1TCII/AAAAAAAAABo/P5JBYXHpkIE/s72-c/rcenvironment.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-2742540089083007013</id><published>2009-06-04T17:15:00.001+02:00</published><updated>2009-06-04T17:19:39.138+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='VisualVM'/><title type='text'>VisualVM 1.1.1 im JDK</title><content type='html'>&lt;span class="news_date"&gt;Letzte Woche hat Sun das &lt;a href="http://java.sun.com/javase/6/"&gt;JDK 6 Update 14&lt;/a&gt; veröffentlicht. Darin enthalten ist &lt;a href="http://java.sun.com/javase/6/webnotes/6u14.html"&gt;unter anderem&lt;/a&gt; die aktuelle Version 1.1.1 von &lt;a href="https://visualvm.dev.java.net/"&gt;VisualVM&lt;/a&gt;, dem Werkzeug für Monitoring und einfaches Profiling. Derzeit ist damit also kein separater Download mehr erforderlich, um die vielen kleinen Verbesserungen und Bugfixes gegenüber der Version 1.0.1 zu erhalten, die seit dem &lt;/span&gt;JDK 6 Update 11 mitgeliefert wurde.&lt;br /&gt;&lt;br /&gt;Sun hat übrigens vor einigen Wochen einen &lt;a href="http://java.sun.com/community/javavisualvm/"&gt;Blog-Wettbewerb zu VisualVM&lt;/a&gt; gestartet, der noch bis zum 24. Juni läuft. Dieses Blog läuft allerdings außer Konkurrenz, da es nicht auf Englisch geschrieben ist...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-2742540089083007013?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/2742540089083007013/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/06/visualvm-111-im-jdk.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2742540089083007013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/2742540089083007013'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/06/visualvm-111-im-jdk.html' title='VisualVM 1.1.1 im JDK'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-3205703983845823726</id><published>2009-05-31T20:41:00.004+02:00</published><updated>2009-05-31T21:07:14.062+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>NetBeans 6.7 im nächsten Monat</title><content type='html'>Die &lt;a href="http://java.sun.com/javaone/"&gt;JavaOne&lt;/a&gt; startet in nicht einmal zwei Tagen – ein prima Termin, um &lt;a href="http://www.netbeans.org/"&gt;NetBeans&lt;/a&gt; 6.7 zu veröffentlichen, das sich derzeit noch im Beta-Stadium befindet.&lt;br /&gt;&lt;br /&gt;Die neue Version von Suns Entwicklungsumgebung bietet viele &lt;a href="http://www.netbeans.org/community/releases/67/"&gt;Neuerungen und Verbesserungen&lt;/a&gt;, u.a. einen erweiterten Profiler, die Unterstützung von GlassFish v3 sowie die Integration von Suns Entwickler-Portal &lt;a href="http://kenai.com/"&gt;Kenai&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Für Entwickler, die NetBeans unter Mac OS X nutzen, wird dies ein besonders schönes Release. Das Projektfenster wurde an das native Aussehen des Systems angepasst und erinnert nun deutlich an &lt;a href="http://developer.apple.com/tools/xcode/"&gt;Xcode&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1bA4Fk08GL0/SiLTKvygS1I/AAAAAAAAABg/DMtaL8u8x_Y/s1600-h/netbeans67macosx.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 200px;" src="http://3.bp.blogspot.com/_1bA4Fk08GL0/SiLTKvygS1I/AAAAAAAAABg/DMtaL8u8x_Y/s320/netbeans67macosx.jpg" alt="" id="BLOGGER_PHOTO_ID_5342064289595280210" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-3205703983845823726?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/3205703983845823726/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/05/netbeans-67-im-nachsten-monat.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3205703983845823726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/3205703983845823726'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/05/netbeans-67-im-nachsten-monat.html' title='NetBeans 6.7 im nächsten Monat'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_1bA4Fk08GL0/SiLTKvygS1I/AAAAAAAAABg/DMtaL8u8x_Y/s72-c/netbeans67macosx.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-593449565630861139</id><published>2009-04-29T23:06:00.002+02:00</published><updated>2009-04-29T23:09:45.033+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Annotationen'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>@SuppressWarnings("unchecked")</title><content type='html'>Seit Version 5.0 kennt Java das Konzept der &lt;a href="http://de.wikipedia.org/wiki/Generische_Programmierung_in_Java"&gt;Generics&lt;/a&gt;, mit denen u.a. Kollektionen mit Typen parametrisiert und typsicherer gemacht werden können.&lt;br /&gt;&lt;br /&gt;Leider lassen sich damit nicht alle Stellen perfekt absichern – insbesondere bei Hibernate bzw. JPA wird man beim Ausführen von Abfragen (Queries) immer wieder auf "Type safety"-Compiler-Warnungen stoßen:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_1bA4Fk08GL0/Sfi8Wq3AMhI/AAAAAAAAABY/LaDQSj6wn-U/s1600-h/typesafety.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 67px;" src="http://1.bp.blogspot.com/_1bA4Fk08GL0/Sfi8Wq3AMhI/AAAAAAAAABY/LaDQSj6wn-U/s320/typesafety.png" alt="" id="BLOGGER_PHOTO_ID_5330217256641114642" border="0" /&gt;&lt;/a&gt;An sich ist das kein Problem, denn mit der bestehenden API gibt es für den Compiler keine sinnvolle Möglichkeit, vom Query-String auf den Ergebnis-Typ zu schließen. Und Entwicklungsumgebungen wie Eclipse bieten die einfache Lösung an, diese unumgängliche Warnung mit der @SuppressWarnings-Annotation zu unterdrücken.&lt;br /&gt;&lt;br /&gt;Nur leider schreibt Eclipse die Annotation immer vor die umgebende Methode, was alle weiteren – vielleicht wichtigen – Typ-Warnungen in der Methode ebenfalls unterdrückt:&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;@SuppressWarnings("unchecked")&lt;/span&gt;&lt;br /&gt;public List&amp;lt;Benutzer&amp;gt; findAllBenutzer() {&lt;br /&gt;   Query q = session.createQuery("from Benutzer");&lt;br /&gt;   return q.list();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Das muss nicht sein! Sehen wir uns dazu den Quelltext der @SuppressWarnings-Annotation an:&lt;br /&gt;&lt;pre&gt;@Target({TYPE, FIELD, METHOD, PARAMETER,&lt;br /&gt;          CONSTRUCTOR, &lt;b&gt;LOCAL_VARIABLE&lt;/b&gt;})&lt;br /&gt;@Retention(RetentionPolicy.SOURCE)&lt;br /&gt;public @interface SuppressWarnings {&lt;br /&gt;&lt;/pre&gt;LOCAL_VARIABLE bedeutet, dass wir die Annotation auch an eine lokale Variablendeklaration schreiben dürfen. Wenn wir also in der Methode eine temporäre Variable einführen, können wir das Unterdrücken der Warnung auf die eine relevante Zeile beschränken:&lt;br /&gt;&lt;pre&gt;public List&amp;lt;Benutzer&amp;gt; findAllBenutzer() {&lt;br /&gt;   Query q = session.createQuery("from Benutzer");&lt;br /&gt;&lt;br /&gt;   &lt;b&gt;@SuppressWarnings("unchecked")&lt;/b&gt;&lt;br /&gt;   List&amp;lt;Benutzer&amp;gt; alle = q.list();&lt;br /&gt;&lt;br /&gt;   return alle;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Für die JPA-Query-Methoden getResultList() und getSingleResult() gilt dies entsprechend.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-593449565630861139?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/593449565630861139/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/04/suppresswarningsunchecked.html#comment-form' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/593449565630861139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/593449565630861139'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/04/suppresswarningsunchecked.html' title='@SuppressWarnings(&quot;unchecked&quot;)'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_1bA4Fk08GL0/Sfi8Wq3AMhI/AAAAAAAAABY/LaDQSj6wn-U/s72-c/typesafety.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-6534395142722516426</id><published>2009-04-21T20:49:00.005+02:00</published><updated>2009-04-21T21:39:44.018+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GlassFish'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Oracle kauft Sun</title><content type='html'>Nun ist es also geschehen: Sun wird &lt;a href="http://www.sun.com/third-party/global/oracle/"&gt;verkauft&lt;/a&gt;, und nicht etwa an IBM (die Übernahmeverhandlungen waren erst kürzlich gescheitert), sondern an &lt;a href="http://www.oracle.com/sun/"&gt;Oracle&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Was dies für die Java-Technologie und die diversen Sun-Java-Produkte konkret bedeutet, bleibt abzuwarten. Immerhin ist Java seit langem gut in bestehende Oracle-Produkte &lt;a href="http://www.oracle.com/technologies/java/"&gt;integriert&lt;/a&gt; und dürfte für Oracle auch weiterhin von strategischer Bedeutung sein.&lt;br /&gt;&lt;br /&gt;Spannend wird es für Suns Application Server &lt;a href="http://java.sun.com/javaee/community/glassfish/"&gt;GlassFish&lt;/a&gt;, der sich seit über einem Jahr deutlich steigender Beliebtheit erfreut. Hier ist zu hoffen, dass Oracle das Potential dieses nun dritten Application Servers im Produktportfolio kennt und nutzt. Berechtigt ist diese Hoffnung allemal, schließlich hat Oracle &lt;a href="http://oss.oracle.com/toplink-essentials-jpa.html"&gt;TopLink Essentials&lt;/a&gt; als JPA-Referenzimplementation zu GlassFish beigesteuert.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-6534395142722516426?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/6534395142722516426/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/04/oracle-kauft-sun.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6534395142722516426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/6534395142722516426'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/04/oracle-kauft-sun.html' title='Oracle kauft Sun'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-5840448393264734447</id><published>2009-04-08T19:44:00.004+02:00</published><updated>2009-04-08T20:09:38.695+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Serialisierung'/><title type='text'>Serialisierbarer ByteArrayOutputStream</title><content type='html'>Ein typisches Problem in einer mehrschichtigen Web-Anwendung besteht darin, eine Datei (beispielsweise ein auf dem Server generiertes PDF-Dokument) zum Client/Web-Frontend zu übertragen (oder nach einem Datei-Upload entsprechend umgekehrt). Die einfache Lösung mit Streams schlägt fehl, sobald Sender und Empfänger nicht mehr lokal in derselben Java Virtual Machine laufen, sondern entfernt in verschiedenen JVMs. Die Streams müssten nun entweder entfernt aufrufbar (Remote) oder aber serialisierbar (Serializable) sein – beides sind sie nicht. Die Serialisierbarkeit ist standardmäßig nicht vorgesehen, da Streams geräteabhängig sind.&lt;br /&gt;&lt;br /&gt;Eine einfache Lösung für das Versenden kleinerer Binärdateien (wenige hundert KB) macht den Standard-ByteArrayOutputStream serialisierbar, was kein Problem ist, da der ByteArrayOutputStream eine reine Java-Speicher-Implementierung und somit geräte&lt;span style="font-style: italic;"&gt;un&lt;/span&gt;abhängig ist. Der Sender kann den Stream wie gewohnt mit &lt;tt&gt;write()&lt;/tt&gt; füllen, und der Empfänger kann den Stream mit den üblichen Methoden auswerten. In einem Servlet kann man den Stream z.B. mit &lt;tt&gt;baos.writeTo(response.getOutputStream())&lt;/tt&gt; direkt zum Client schicken.&lt;br /&gt;&lt;br /&gt;Für die Implementierung des serialisierbaren ByteArrayOutputStreams reicht es nicht aus, die neue Unterklasse das Serializable-Interface implementieren zu lassen. Man muss zusätzlich noch die Methoden &lt;tt&gt;writeObject()&lt;/tt&gt; und &lt;tt&gt;readObject()&lt;/tt&gt; implementieren, die den internen Stream-Puffer explizit serialisieren:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class SerializableByteArrayOutputStream&lt;br /&gt;       extends ByteArrayOutputStream&lt;br /&gt;       implements Serializable {&lt;br /&gt;&lt;br /&gt;  private void writeObject(ObjectOutputStream stream)&lt;br /&gt;        throws IOException {&lt;br /&gt;    stream.writeInt( count );&lt;br /&gt;    stream.writeObject( buf );&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void readObject(ObjectInputStream stream)&lt;br /&gt;        throws IOException, ClassNotFoundException {&lt;br /&gt;    count = stream.readInt();&lt;br /&gt;    buf = (byte[]) stream.readObject();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Der vollständige Quelltext der Klasse&lt;br /&gt;&lt;tt&gt;SerializableByteArrayOutputStream&lt;/tt&gt; kann &lt;a href="http://www.muchsoft.com/java/source/SerializableByteArrayOutputStream.java"&gt;hier&lt;/a&gt; abgerufen werden.&lt;br /&gt;&lt;br /&gt;Wer eine umfassendere Lösung sucht oder große Dateien übertragen muss, sollte sich die &lt;a href="http://openhms.sourceforge.net/rmiio/"&gt;RMIIO&lt;/a&gt;-Bibliothek anschauen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-5840448393264734447?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/5840448393264734447/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/04/serialisierbarer-bytearrayoutputstream.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/5840448393264734447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/5840448393264734447'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/04/serialisierbarer-bytearrayoutputstream.html' title='Serialisierbarer ByteArrayOutputStream'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-7732253626678483314</id><published>2009-04-01T20:59:00.004+02:00</published><updated>2009-04-01T21:14:21.475+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='VisualVM'/><title type='text'>Proxy-Konfiguration für VisualVM</title><content type='html'>Wenn man mit VisualVM in einem Netzwerk arbeitet, das über einen &lt;a href="http://de.wikipedia.org/wiki/Proxy_%28Rechnernetz%29"&gt;Proxy&lt;/a&gt; ans Internet angebunden ist, hat VisualVM Probleme mit dem Nachladen seiner &lt;a href="https://visualvm.dev.java.net/plugins.html"&gt;Plugins&lt;/a&gt; – was schade ist, denn dadurch verschenkt man die Hälfte der Möglichkeiten.&lt;br /&gt;&lt;br /&gt;Der Proxy kann leider nicht in VisualVM selbst konfiguriert werden, sondern muss mit Aufrufparametern übergeben werden:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;visualvm -J-DproxyHost=mein.proxy.com -J-DproxyPort=1234&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Aber Achtung: Dies sind nicht die üblichen Java-Proxy-Parameter &lt;tt&gt;http.proxyHost&lt;/tt&gt; und &lt;tt&gt;http.proxyPort&lt;/tt&gt;! Das "http." fehlt jeweils.&lt;br /&gt;&lt;br /&gt;Außerdem scheint die Konfiguration mit dem im JDK 6 mitgelieferten VisualVM nicht zu funktionieren. Mit dem separat herunterladbaren &lt;a href="https://visualvm.dev.java.net/download.html"&gt;VisualVM 1.1.1&lt;/a&gt; klappt es aber wie gewünscht.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-7732253626678483314?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/7732253626678483314/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/04/proxy-konfiguration-fur-visualvm.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7732253626678483314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7732253626678483314'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/04/proxy-konfiguration-fur-visualvm.html' title='Proxy-Konfiguration für VisualVM'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-9080273441891656838</id><published>2009-03-28T20:12:00.001+01:00</published><updated>2009-03-28T20:20:43.052+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>Scala ist auch eine Oper</title><content type='html'>... aber natürlich vor allem eine funktionale, objektorientierte Programmiersprache für die &lt;a href="http://de.wikipedia.org/wiki/Java_Virtual_Machine"&gt;Java Virtual Machine&lt;/a&gt; :-)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; hat das Zeug dazu, die nächste große Sprache nach bzw. neben Java zu werden. Viele Ausdrücke lassen sich in Scala einfacher und kürzer als in Java schreiben, dennoch bleibt die statische und starke Typisierung wie bei Java erhalten. Ein großes Plus ist zudem die nahtlose Integration mit den unzähligen bestehenden Java-Bibliotheken. Und Scala ist nicht wirklich neu und nur irgendwie gerade cool, sondern bereits acht Jahre alt und &lt;span style="font-style: italic;"&gt;stabil&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Zum Einstieg verwendet man am besten &lt;a href="http://www.eclipse.org/downloads/"&gt;Eclipse&lt;/a&gt; 3.4 (das "Classic"- oder "Java EE"-Paket). Ein JDK 5.0 oder neuer sollte bereits installiert sein. Nun fehlt nur noch das &lt;a href="http://www.scala-lang.org/node/94"&gt;Scala-Plugin&lt;/a&gt;, das man in Eclipse im Menü &lt;span style="font-style: italic;"&gt;Help &gt; Software Updates...&lt;/span&gt; mit der Update-URL&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;http://www.scala-lang.org/scala-eclipse-plugin&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;herunterladen lässt.&lt;br /&gt;&lt;br /&gt;Wechselt man in die Scala-Perspektive, kann man unter &lt;span style="font-style: italic;"&gt;File &gt; New&lt;/span&gt; ein neues "Scala Project" anlegen. Wie aus Java gewohnt legt man ein Paket an und in diesem Paket dann ein "Scala Object" (!). Richtig gelesen, Scala unterstützt nicht nur Klassen, sondern auch einzelne Objekte. Wenn wir dieses Objekt von &lt;tt&gt;Application&lt;/tt&gt; erben lassen, entspricht das der &lt;tt&gt;main&lt;/tt&gt;-Methode in Java:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1bA4Fk08GL0/Sc4oXWv1M-I/AAAAAAAAABA/FJ3P4acvegE/s1600-h/eclipse-scala.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px; height: 214px;" src="http://3.bp.blogspot.com/_1bA4Fk08GL0/Sc4oXWv1M-I/AAAAAAAAABA/FJ3P4acvegE/s320/eclipse-scala.jpg" alt="" id="BLOGGER_PHOTO_ID_5318232591679435746" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Scala bietet Typinferenz, d.h. man muss beim Deklarieren einer Variablen nicht zwingend den Typ angeben, wenn Scala diesen aus dem Kontext eindeutig ableiten kann. Die Variable ist dann trotzdem zur Übersetzungszeit typsicher, man kann also keine inkompatiblen Werte zuweisen:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1bA4Fk08GL0/Sc48otMI-YI/AAAAAAAAABI/xfwPsgVaUFU/s1600-h/scala-typinferenz.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px; height: 164px;" src="http://3.bp.blogspot.com/_1bA4Fk08GL0/Sc48otMI-YI/AAAAAAAAABI/xfwPsgVaUFU/s320/scala-typinferenz.jpg" alt="" id="BLOGGER_PHOTO_ID_5318254879994083714" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Wie bei &lt;a href="http://de.wikipedia.org/wiki/Funktionale_Programmierung"&gt;funktionalen Sprachen&lt;/a&gt; üblich, liegt eine der Stärken in der Listenverarbeitung. Listen können mit einer Java-ähnlichen Syntax angelegt werden (es geht auch funktionaler, siehe erster Screenshot):&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;val früchte = List("Äpfel", "Birnen", "Orangen")&lt;br /&gt;&lt;br /&gt;&lt;/tt&gt;Entweder kann man die Liste dann mit einer Java 5-ähnlichen for-each-Schleife ausgeben:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;for (frucht &lt;- früchte) {   println(frucht) }&lt;span style="font-family:Georgia,serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/tt&gt;Oder man nutzt ein anonymes Funktionsliteral, eine sogenannte &lt;span style="font-style: italic;"&gt;Funktion höherer Ordnung&lt;/span&gt;, die man als Wert an die foreach-Methode der Liste übergibt:&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;früchte.foreach(f =&gt; println(f))&lt;br /&gt;&lt;br /&gt;&lt;/tt&gt;Da man den Punktoperator beim Methodenaufruf weglassen darf und println nur ein Argument erwartet, geht das auch noch kürzer:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;früchte foreach println&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;Und immer daran denken: Auch wenn das so langsam nach einer Skriptsprache aussieht (und tatsächlich ähnlich schnell programmiert werden kann), haben wir hierbei statische, starke, vom Compiler geprüfte &lt;a href="http://de.wikipedia.org/wiki/Typisierung_%28Informatik%29"&gt;Typisierung&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Soweit fürs Erste, das sollte als Appetitanreger reichen :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-9080273441891656838?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/9080273441891656838/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/03/scala-ist-auch-eine-oper.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/9080273441891656838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/9080273441891656838'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/03/scala-ist-auch-eine-oper.html' title='Scala ist auch eine Oper'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_1bA4Fk08GL0/Sc4oXWv1M-I/AAAAAAAAABA/FJ3P4acvegE/s72-c/eclipse-scala.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-488351253920429077</id><published>2009-03-25T21:07:00.001+01:00</published><updated>2009-03-25T21:16:51.397+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='VisualVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Monitoring und Profiling mit VisualVM</title><content type='html'>Am Wochenende habe ich einen kleinen &lt;a href="http://www.muchsoft.com/publikationen.html#talks"&gt;Vortrag&lt;/a&gt; über &lt;a href="https://visualvm.dev.java.net/"&gt;VisualVM&lt;/a&gt; gehalten. Dieses nützliche Werkzeug ist seit dem Update 7 fester Bestandteil des &lt;a href="http://java.sun.com/javase/downloads/"&gt;JDK 6&lt;/a&gt;. Es bietet gute Überwachungsmöglichkeiten für laufende Java-Anwendungen (sowohl lokal als auch auf entfernten Rechnern). Beim Profiling kann es zwar nicht ganz mit kommerziellen Lösungen mithalten, bietet aber dennoch für viele Situationen vollkommen ausreichende Auswertungen (z.B. die Aufrufstellen einer Methode).&lt;br /&gt;&lt;br /&gt;VisualVM benötigt Java 6 als Laufzeitumgebung, kann aber Anwendungen schon ab Java 1.4 überwachen. Faustregel: Je neuer die Laufzeitumgebung des auszuwertenden Programms ist und je lokaler sie läuft, desto bessere Informationen liefert VisualVM.&lt;br /&gt;&lt;br /&gt;Leider liefert Apple VisualVM auch mit dem neuesten &lt;a href="http://www.apple.com/downloads/macosx/apple/application_updates/javaformacosx105update3.html"&gt;Update&lt;/a&gt; ihrer Java SE 6-Implementation nicht mit. Sofern man dieses Update eingespielt hat, kann man VisualVM 1.1.1 aber problemlos separat &lt;a href="https://visualvm.dev.java.net/download.html"&gt;herunterladen&lt;/a&gt; und (durch Auspacken des ZIP-Archivs) installieren.&lt;br /&gt;&lt;br /&gt;Da es gute Gründe gibt, als Standard-Java-Version unter Mac OS X derzeit noch 5.0 einzusetzen, muss man Java 6 beim Aufruf im Terminal explizit als Parameter angeben:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;HeartOfGold:visualvm-1.1.1 much$ &lt;b&gt;bin/visualvm --jdkhome /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/ &amp;amp;&lt;/b&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_1bA4Fk08GL0/SceafvkyAUI/AAAAAAAAAA4/cFKDSbTbh5g/s1600-h/visualvm111.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px; height: 220px;" src="http://2.bp.blogspot.com/_1bA4Fk08GL0/SceafvkyAUI/AAAAAAAAAA4/cFKDSbTbh5g/s320/visualvm111.jpg" alt="" id="BLOGGER_PHOTO_ID_5316387755271520578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Das Profiling funktioniert mit der Apple-Java-Implementierung noch nicht wirklich zuverlässig... Eventuell ist ein älterer &lt;a href="https://visualvm.dev.java.net/troubleshooting.html#profmacosx"&gt;Bug&lt;/a&gt; immer noch nicht vollständig korrigiert. Immerhin stehen die Monitoring-Möglichkeiten komplett und stabil zur Verfügung.&lt;br /&gt;&lt;br /&gt;Mit dem neuen "Memory Sampler"-Plugin können aber zumindest Live-Speichervergleiche (Deltas) ermittelt werden, was einen wichtigen Aspekt des Memory-Profilings abdeckt. Und der Memory Sampler läuft zum Glück auch unter Mac OS X.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-488351253920429077?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/488351253920429077/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/03/monitoring-und-profiling-mit-visualvm.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/488351253920429077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/488351253920429077'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/03/monitoring-und-profiling-mit-visualvm.html' title='Monitoring und Profiling mit VisualVM'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_1bA4Fk08GL0/SceafvkyAUI/AAAAAAAAAA4/cFKDSbTbh5g/s72-c/visualvm111.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-1711716030501250205</id><published>2009-03-18T20:55:00.003+01:00</published><updated>2009-03-18T21:30:31.707+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='WebObjects'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><title type='text'>WebObjects-Anwendungen in Eclipse entwickeln</title><content type='html'>Still und heimlich hat Apple vor ein paar Wochen eine &lt;a href="http://developer.apple.com/documentation/DeveloperTools/Conceptual/WOTutorial/"&gt;Anleitung&lt;/a&gt; veröffentlicht, wie man &lt;a href="http://developer.apple.com/tools/webobjects/"&gt;WebObjects&lt;/a&gt;-Anwendungen in Eclipse mit den &lt;a href="http://wiki.objectstyle.org/confluence/display/WOL/Home"&gt;WOLips&lt;/a&gt;-Plugins entwickelt.&lt;br /&gt;&lt;br /&gt;Zur Erinnerung: WebObjects ist Apples Enterprise-Framework zur Entwicklung skalierbarer Web-Applikationen. Von NeXT bereits 1996 veröffentlicht, ist es heute die Software-Basis u.a. vom iTunes Store. 2001 wurde das bis dahin in Objective-C entwickelte Framework komplett neu geschrieben – in Java. Entsprechend kann WebObjects 5.x problemlos mit Java SE oder innerhalb eines Java EE-kompatiblen Servers genutzt werden.&lt;br /&gt;&lt;br /&gt;Nachdem Apple 2006 die Weiterentwicklung der eigenen, auf Xcode basierenden Entwicklerwerkzeuge eingestellt hat, unterstützt und verwendet Apple nun WOLips, eine OpenSource-Plugin-Sammlung für Eclipse, die die WebObjects-Entwicklertools nachbildet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-1711716030501250205?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/1711716030501250205/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/03/webobjects-anwendungen-in-eclipse.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1711716030501250205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1711716030501250205'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/03/webobjects-anwendungen-in-eclipse.html' title='WebObjects-Anwendungen in Eclipse entwickeln'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-7492205783242863712</id><published>2009-03-16T21:15:00.002+01:00</published><updated>2009-03-16T21:18:19.070+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GlassFish'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaFX'/><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Java EE und JavaFX für Mac OS X</title><content type='html'>Während nach wie vor Apple für das JDK (Java SE) unter Mac OS X verantwortlich ist und sich dabei &lt;a href="http://javabarista.blogspot.com/2009/03/aktuelle-java-versionen-fur-mac-os-x.html"&gt;nicht besonders gut um ältere Macs kümmert&lt;/a&gt;, sind andere Java-Technologien direkt von Sun für Mac OS X erhältlich:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;das &lt;a href="http://java.sun.com/javaee/downloads/"&gt;Java EE 5 SDK&lt;/a&gt; inkl. Sun Application Server (GlassFish)&lt;/li&gt;&lt;li&gt;das &lt;a href="http://java.sun.com/javafx/downloads/"&gt;JavaFX 1.1 SDK&lt;/a&gt; inkl. NetBeans IDE 6.5&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Beide Produkte können ab Mac OS X 10.4 genutzt werden, sowohl auf Intel- als auch auf PowerPC-G5-Macs – sofern Apples aktuellstes Java 5.0-Update installiert ist.&lt;br /&gt;&lt;br /&gt;Als JEE-Umgebung eignet sich natürlich auch der &lt;a href="http://www.jboss.org/jbossas/downloads/"&gt;JBoss AS 5.0&lt;/a&gt;, der ebenfalls problemlos unter Mac OS X betrieben werden kann.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-7492205783242863712?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/7492205783242863712/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/03/java-ee-und-javafx-fur-mac-os-x.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7492205783242863712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7492205783242863712'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/03/java-ee-und-javafx-fur-mac-os-x.html' title='Java EE und JavaFX für Mac OS X'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-4598325401479253654</id><published>2009-03-12T22:01:00.009+01:00</published><updated>2009-03-13T13:33:38.626+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenJDK'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Aktuelle Java-Versionen für Mac OS X</title><content type='html'>Im Netz taucht immer wieder die Frage auf, welche Java-Versionen aktuell unter Apples Mac OS X genutzt werden können – gerade wenn Java-Entwickler ihre Programme nicht selber auf einem Mac testen können.&lt;br /&gt;&lt;br /&gt;Für Mac OS X 10.5 sind die Java-Versionen 1.4, 5.0 und 6 direkt von Apple verfügbar und können über die Softwareaktualisierung ins System eingebunden werden (als JDKs, es gibt von Apple keine separaten JREs). Unter Mac OS X 10.4 war zusätzlich noch Java 1.3 nutzbar, dafür hat Apple für diese ältere Betriebssystemversion kein Java SE 6 herausgebracht.&lt;br /&gt;&lt;br /&gt;Aber Achtung: Gerade Java SE 6, also die einzige Version, die Ende dieses Jahres noch nicht &lt;a href="http://java.sun.com/javase/downloads/index_jdk5.jsp"&gt;EOL&lt;/a&gt; sein wird, steht nur für 64-Bit-Intel-Macs zur Verfügung. Das sind solche mit Core2Duo-Prozessor. PPC-Macs und ältere Intel-Macs mit CoreDuos bleiben leider außen vor...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_1bA4Fk08GL0/SbosLDsIKsI/AAAAAAAAAAw/vwILub-oYIQ/s1600-h/macosx105-java-einstellungen.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 270px;" src="http://1.bp.blogspot.com/_1bA4Fk08GL0/SbosLDsIKsI/AAAAAAAAAAw/vwILub-oYIQ/s320/macosx105-java-einstellungen.jpg" alt="" id="BLOGGER_PHOTO_ID_5312607278917495490" border="0" /&gt;&lt;/a&gt;Standardmäßig ist für Applets und Java Web Start-Anwendungen so oder so Java 5.0 eingestellt. Mit dem System-Utility &lt;span style="font-family:courier new;"&gt;/Programme/Dienstprogramme/Java/Java-Einstellungen&lt;/span&gt; kann man dies ändern (siehe Bildschirmfoto).&lt;br /&gt;&lt;br /&gt;Fazit: Java 6 ist in der Apple-Welt für Endbenutzer leider immer noch nicht wirklich angekommen. Wenn Ihre Java-Applikationen von möglichst vielen Apple-Nutzern eingesetzt werden sollen, sollten Sie derzeit noch Java 5.0 als Mindestanforderung voraussetzen.&lt;br /&gt;&lt;br /&gt;Und nun noch ein paar technische Details:&lt;br /&gt;&lt;br /&gt;Die aktuellen JDKs für Mac OS X haben die Versionsnummern 1.4.2_18, 1.5.0_16 und 1.6.0_07. Sie können mit den Software-Updates &lt;a href="http://support.apple.com/downloads/Java_for_Mac_OS_X_10_4__Release_7"&gt;Java for Mac OS X 10.4 Release 7&lt;/a&gt; bzw. &lt;a href="http://support.apple.com/downloads/Java_for_Mac_OS_X_10_5_Update_2"&gt;Java for Mac OS X 10.5 Update 2&lt;/a&gt; installiert werden (es gibt mittlerweile auch Release 8 und Update 3, aber dadurch wird nur Java Web Start aktualisiert und nicht nicht JDK-Version verändert).&lt;br /&gt;&lt;br /&gt;Das Java-Update für Mac OS X 10.5 installiert übrigens auch auf CoreDuo-Macs Java SE 6, nur leider lässt sich das auf diesen Rechnern trotzdem nicht ausführen...&lt;br /&gt;&lt;br /&gt;Seit einigen Jahren pflege ich eine detaillierte &lt;a href="http://www.muchsoft.com/java/macosxjavaversions.html"&gt;Liste von Mac OS X- und deren Java-Versionen&lt;/a&gt; inkl. der entsprechenden Download-Links.&lt;br /&gt;&lt;br /&gt;Unabhängig von Apples Java-Versionen gibt es mit &lt;a href="http://landonf.bikemonkey.org/static/soylatte/"&gt;SoyLatte&lt;/a&gt; seit einiger Zeit auch eine Portierung vom &lt;a href="http://openjdk.java.net/"&gt;OpenJDK&lt;/a&gt; für Mac OS X. Damit kann Java SE 6 nicht nur unter Mac OS X 10.5, sondern auch unter 10.4 genutzt werden. Allerdings ist auch SoyLatte nur für Intel-Macs verfügbar, und für grafische Ausgaben wird das für Mac-Oberflächen unübliche X11 anstelle von Cocoa genutzt.&lt;br /&gt;&lt;br /&gt;Bleibt zu hoffen, dass Sun es (mit Apples Hilfe?) ab Java 7 schafft, selber wieder ein vernünftiges JDK für Mac OS X herauszubringen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-4598325401479253654?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/4598325401479253654/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/03/aktuelle-java-versionen-fur-mac-os-x.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4598325401479253654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/4598325401479253654'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/03/aktuelle-java-versionen-fur-mac-os-x.html' title='Aktuelle Java-Versionen für Mac OS X'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_1bA4Fk08GL0/SbosLDsIKsI/AAAAAAAAAAw/vwILub-oYIQ/s72-c/macosx105-java-einstellungen.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-1665122179212302944</id><published>2009-03-04T18:48:00.008+01:00</published><updated>2009-03-04T19:24:22.200+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Swing'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X'/><title type='text'>Das Swing Application Framework lebt!</title><content type='html'>Desktop-Anwendungen mit Java zu entwickeln, war schon immer so eine Sache... Zwar gibt es die Swing-Bibliothek seit Ewigkeiten und deren GUI-Komponenten sind auch recht brauchbar. Was aber fehlte, war ein Framework, mit dem man den ganzen Lebenszyklus einer Desktop-Applikation einfacher handhaben konnte.&lt;br /&gt;&lt;br /&gt;Auch wenn im Laufe der Zeit mit der &lt;a href="http://platform.netbeans.org/"&gt;NetBeans Platform&lt;/a&gt; und &lt;a href="http://www.eclipse.org/home/categories/rcp.php"&gt;Eclipse RCP&lt;/a&gt; Alternativen entstanden sind, wollte Sun mit dem &lt;a href="https://appframework.dev.java.net/"&gt;Swing Application Framework&lt;/a&gt; (&lt;a href="http://jcp.org/en/jsr/detail?id=296"&gt;JSR 296&lt;/a&gt;) eine reine Swing-Lösung anbieten. Der Ansatz war gut, doch leider wurde es um diesen JSR in den vergangenen Monaten sehr still - so still, dass der JSR vor kurzem in den Status "inaktiv" versetzt wurde.&lt;br /&gt;&lt;br /&gt;Nun hat sich einer der Sun-Entwickler &lt;a href="http://weblogs.java.net/blog/alexfromsun/archive/2009/03/swing_applicati_1.html"&gt;zu Wort gemeldet&lt;/a&gt; und verkündet, dass nun wieder aktiv an Swing und dem Swing Application Framework (SAF)  gearbeitet wird. In der letzten Zeit gab es offenbar einfach wichtigere Dinge (vermutlich &lt;a href="http://javafx.com/"&gt;JavaFX&lt;/a&gt;?) zu erledigen.&lt;br /&gt;&lt;br /&gt;Bei den neuerlichen Aktivitäten ist interessant, dass nicht mehr nur &lt;a href="http://de.wikipedia.org/wiki/Multiple_Document_Interface"&gt;MDI&lt;/a&gt;-Anwendungen unterstützt werden sollen, sondern explizit auch die vor allem unter Mac OS X verbreiteten &lt;a href="http://de.wikipedia.org/wiki/Single_Document_Interface"&gt;SDI&lt;/a&gt;-Applikationen (und auch die beim Mac üblichen Menüzeilen ganz ohne offenes Dokument-Fenster). Das lässt hoffen, denn bisher war für solche GUI-Anpassungen ein nicht unerheblicher Mehraufwand nötig.&lt;br /&gt;&lt;br /&gt;Man darf gespannt sein, ob das Swing Application Framework Bestandteil von Java 7 sein wird, dessen Veröffentlichung mittlerweile für 2010 vorgesehen ist.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-1665122179212302944?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/1665122179212302944/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/03/das-swing-application-framework-lebt.html#comment-form' title='3 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1665122179212302944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/1665122179212302944'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/03/das-swing-application-framework-lebt.html' title='Das Swing Application Framework lebt!'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-7342979257741872910</id><published>2009-02-23T21:50:00.000+01:00</published><updated>2009-03-03T10:38:56.392+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Annotationen'/><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Dependency Injection'/><category scheme='http://www.blogger.com/atom/ns#' term='Struts'/><title type='text'>@EJB Dependency Injection für Struts 1.2/1.3 Action-Klassen</title><content type='html'>Auch wenn das Web-Framework &lt;a href="http://struts.apache.org/"&gt;Struts&lt;/a&gt; - gerade in den Versionen 1.x - schon etwas in die Jahre gekommen ist und mittlerweile zahlreiche Alternativen zur Verfügung stehen (JSF, Struts 2, Wicket, Stripes, GWT, Eclipse RAP...), wird es immer noch häufig eingesetzt, gerade wenn in diesem Bereich viel Entwickler-Know-How vorhanden ist.&lt;br /&gt;&lt;br /&gt;Unschön ist dabei allerdings die unnötig komplizierte Einbindung in aktuelle Java EE-Umgebungen, da zum Abfragen von Enterprise-Ressourcen (z.B. Session Beans) explizite JNDI-&lt;a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/ServiceLocator.html"&gt;ServiceLocator&lt;/a&gt;-Aufrufe nötig sind.&lt;br /&gt;&lt;br /&gt;In JEE-Standard-Klassen ("managed classes") wie Servlets und JSF Managed Beans steht dagegen &lt;a href="http://de.wikipedia.org/wiki/Dependency_Injection"&gt;Dependecy Injection&lt;/a&gt; (DI) zur Verfügung, wodurch man sich Referenzen auf  Enterprise-Ressourcen nicht mehr aktiv holen muss, sondern automatisch bereitgestellt bekommt.&lt;br /&gt;&lt;br /&gt;Mit meiner kleinen Bibliothek &lt;a href="http://code.google.com/p/struts-di/"&gt;Struts-DI&lt;/a&gt; funktioniert dies auch innerhalb von Struts-Actions:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MyAction extends org.apache.struts.action.Action {&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;@EJB&lt;br /&gt;  private MySessionBean msb;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public ActionForward execute(...) throws Exception {&lt;br /&gt;&lt;br /&gt;    String backendResponse = msb.myCall(...);&lt;br /&gt;    ...&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Die dazu notwendige Konfiguration ist denkbar einfach. Anstelle des Struts-RequestProcessors wird in der &lt;tt&gt;struts-config.xml&lt;/tt&gt; ein neuer RequestProcessor eingetragen:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;controller nocache="true"&lt;br /&gt; processorClass=&lt;br /&gt;   "com.muchsoft.struts.annotations.RequestProcessor"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Dies ist unter Struts 1.2 das übliche Vorgehen, um sich in die Action-Verarbeitung einzuklinken. Mit Struts 1.3 funktioniert dies ebenso (der dort vorhandene Chain-Mechanismus wird nicht verwendet).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-7342979257741872910?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/7342979257741872910/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/02/ejb-dependency-injection-fur-struts.html#comment-form' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7342979257741872910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/7342979257741872910'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/02/ejb-dependency-injection-fur-struts.html' title='@EJB Dependency Injection für Struts 1.2/1.3 Action-Klassen'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-951416721955590499.post-304109821042897442</id><published>2009-02-20T16:24:00.000+01:00</published><updated>2009-02-20T16:31:19.720+01:00</updated><title type='text'>Neues Jahr, neues Blog</title><content type='html'>Nachdem ich bisher unter &lt;a href="http://www.snailshell.de/blog/archives/cat_java.html"&gt;http://www.snailshell.de/blog/&lt;/a&gt; auf Englisch geschrieben habe, starte ich nun mein neues Java-Blog auf Deutsch. Viel Spaß damit!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/951416721955590499-304109821042897442?l=javabarista.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabarista.blogspot.com/feeds/304109821042897442/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://javabarista.blogspot.com/2009/02/neues-jahr-neues-blog.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/304109821042897442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/951416721955590499/posts/default/304109821042897442'/><link rel='alternate' type='text/html' href='http://javabarista.blogspot.com/2009/02/neues-jahr-neues-blog.html' title='Neues Jahr, neues Blog'/><author><name>Thomas Much</name><uri>http://www.blogger.com/profile/15594237205835321171</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='http://3.bp.blogspot.com/_1bA4Fk08GL0/SZ7HWL8q30I/AAAAAAAAAAM/PSVgiuN2cJI/S220/tmhh.jpg'/></author><thr:total>0</thr:total></entry></feed>
