Java ist auch eine Insel

Samstag, Mai 17, 2008

YUI4JSF: JSF-Komponenten auf der Basis der Yahoo UI Library

YUI4JSF (http://yui4jsf.sourceforge.net/) bietet auf der Basis der The Yahoo! User Interface Library (YUI) neue JSF-Komponenten:

Die Webseite schreibt über das YUI4JSF-Projekt:

Components that wrap around builtin YUI Widgets. YUI has many widgets like calendar, slider, autocomplete, treeview, inputColor and etc. YUI4JSF takes these widgets and provides pure JSF Components which take care of the javascript and server side interaction.

Components powered by YUI Utilities. YUI Utilities like DragDrop Utils are used to create custom components like SortList or Accordion Panel.

AJAX Forms (Beta). YUI4JSF Ajax components like ajaxCommandButton ajaxifies your existing forms in few seconds.

Layout Engine (Experimental). YUI4JSF provides a templating engine that helps creating a flexible layout mechanism in your JSF pages.

Das Demo (http://www.nightdev.devisland.net/yui4jsf-examples) zeigt die Komponenten live. Wenn ich allerdings das Look-and-Feel der YUI-Beispiele mit denen von YUI4JSF vergleiche, kommt YUI4JSF irgendwie schlechter weg.

License: Apache License V2.0

Labels: ,

AddThis Social Bookmark Button

VisualVM 1.0 RC

Vom VisualVM (https://visualvm.dev.java.net/) gibt es eine erste 1.0 Version.

May 6th, 2008: VisualVM 1.0 RC released. This is mainly a stabilization release: many bugs have been fixed and performance and memory management have been significantly improved. The only new feature is the Start Page which contains useful links to VisualVM documentation and JDK monitoring and troubleshooting guides. Sources for this release are available in release10 branch.

screenshot of profier tab with profiling results

Es sieht so aus, als ob VisualVM in Java 7 als weiteres Tool neben der JConsole einzieht. (Oder vielleicht auch VisualVM sich die JConsole einverleibt und dann VisualVM das "Hauptprogramm" wird. VisualVM erlaubt -- genauso wie auch die JConsole -- Plugins, und eines ist eben für MBeans.)

screenshot of Plugins window

Labels: ,

AddThis Social Bookmark Button

Donnerstag, April 17, 2008

Neue Video-/Audio-Library

Also wenn

MediaManager.installNativeLibrary(true);
// enable file protocol
MediaManager.getInstance().registerProtocol(FileProtocol.URL_PREFIX, FileProtocol.FACTORY);
// create Swing frame
JFrame frame = new JFrame();
frame.setSize(new Dimension(480, 300));
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// add Java2D-based video renderer to Swing frame
final IVideoRenderer renderer = new Java2DRenderer();
frame.add(renderer.getVisualComponent());
// show frame
frame.setVisible(true);
// open movie file & find stream info (resolution, audio channels,...)
AVFormatContext formatContext = AVFormatContext.openFile(FileProtocol.computeUrl(new File("samples/elephantsdream.avi")));
formatContext.findStreamInfo();
// create media player
final MediaPlayer player = new MediaPlayer(renderer);
player.open(formatContext);

alles ist, was man für ein Video abzuspielen bracht, dann prima. pulsar (http://dev.getpulsar.com/) ist eine neue Open-Source Bib mit einer nativen Komponente, zum Abspielen von Audio und Video.

Pulsar includes a media library to encode, decode and playback audio and video files. Pulsar makes use of projects like FFmpeg, X264, liba52, FAAD2 and LAME to support a variety of codecs like MPEG, H.264, AC3 and MP3. The input can be a local file, a HTTP stream or an arbitrary other input implementing IMediaProtocol. The media library is distributed in two files, a Java library "pulsar_media.jar" and a native library "pulsar_media.*". There are precompiled versions of the native library for Windows, Mac OS X and Linux.

Labels: ,

AddThis Social Bookmark Button

Dienstag, März 11, 2008

Inselupdate: Quantifizierer mit Wiederholungen, nicht gierige Operatoren

Wiederholungen

Neben Quantifizierern ? (einmal oder keinmal), * (keinmal oder beliebig oft) und + (einmal oder beliebig oft), gibt es drei weitere Quantifizierer, die es erlauben, die Anzahl eines Vorkommens genauer zu beschreiben.

  • X{n}. X muss genau n-mal vorkommen
  • X{n,}. X kommt mindestens n-mal vor
  • X{n,m}. X kommt mindestens n aber maximal m-mal vor

Beispiel   Eine E-Mail Adresse endet mit einem Domain-Namen, der 2 oder 3 Zeichen lang ist.

static Pattern p = Pattern.compile( "[\\w|-]+@\\w[\\w|-]*\\.[a-z]{2,3}" );

 

Gierige und nicht gierige Operatoren

Die drei Operatoren ?, * und + haben die Eigenschaft, die längste mögliche Zeichenfolge abzudecken – das nennt sich gierig (engl. greedy). Deutlich wird diese Eigenschaft, bei dem Versuch, in einem HTML-Strings alle fett gesetzten Teile zu finden. Gesucht ist also ein Ausdruck, der im String

String string = "Echt <b>fett</b>. <b>Cool</b>!";

die Teilfolgen <b>fett</b> und <b>Cool</b> erkennt. Der erste Versuch für ein Programm:

Pattern pattern = Pattern.compile( "<b>.*</b>" );

Matcher matcher = pattern.matcher( string );

while ( matcher.find() )

System.out.println( matcher.group() );

Nun ist die Ausgabe aber <b>fett</b>. <b>Cool</b>! Das verwundert nicht, denn mit dem Wissen, dass * gierig ist, passt <b>.*</b> auf die Zeichenkette vom ersten <b> bis zum letzten </b>.

Die Lösung ist der Einsatz eines nicht gierigen Operators (auch „genügsam“, „zurückhaltend“, „non-greedy“, „reluctant“ genannt). Dieser Operator bekommt einfach hinter dem Qualifizierer ein Fragezeichen gestellt.

Mit diesem nicht-gierigen Operator lösen wir einfach das Fettproblem:

Pattern pattern = Pattern.compile( "<b>.*?</b>" );

Matcher matcher = pattern.matcher( "Echt <b>fett</b>. <b>Cool</b>!" );

while ( matcher.find() )

  System.out.println( matcher.group() );

Die Ausgabe ist:

<b>fett</b>

<b>Cool</b>

Labels: ,

AddThis Social Bookmark Button

Donnerstag, März 06, 2008

Java nach C# Übersetzer von ILOG Open-Source

ILOG hat ihren Übersetzer von Java nach C# quelloffen gemacht. Da Projekt ist unter SourceForge gehostet. Eingebunden ist es über Eclipse und dann macht man einfach nur ein File > Export. Es unterstützt Java 6 mit allen Java 5 Features wie Generics, Enums, foreach.

PS: Aktualisiertes tutego-Seminar Oracle Discoverer für Anwender

Labels: ,

AddThis Social Bookmark Button

Mittwoch, März 05, 2008

Alternative Sprachen für die und auf der JVM

Java hat seine Monopolstellung eingebüßt – die hochoptimierte JVM und die umfangreichen Java-Bibliotheken lassen sich mittlerweile durch alternative Programmiersprachen nutzen. Auf der einen Seite existieren klassische Interpreter und Compiler für existierende Sprachen, wie Ruby, Prolog, LISP, BASIC, Python, die bestmöglich auf die Java-Umgebung portiert werden. Auf der anderen Seite sind es ganz neue Programmiersprachen (wie Groovy), die sich als echte Alternative zur Programmiersprache Java etablieren. Skriptsprachen werden oft über die JSR 223: Scripting for the Java Platform, einer standardisierten API, angesprochen.

JavaScript

Seit Java 6 ist über Rhino – ein Projekt der Mozilla Foundation – eine JavaScript-Laufzeitumgebung integriert. Die Script-Engine erlaubt die dynamische Übersetzung in Bytecode, was schnelle Ausführungszeiten der prozeduralen, funktionalen, objektorientierten Programmiersprache garantiert.

Groovy

[Logo]Groovy bietet eine starke Syntax mit Closures, Listen/Mengen, Reguläre Ausdrücke, eine dynamische und statische Typisierung und vielem mehr. Moderne IDEs wie Eclipse oder NetBeans unterstützen Groovy durch Plugins. Der Groovy-Compiler erzeugt für die Groovy-Klassen den typischen Bytecode, sodass normale Java-Klassen problemlos Groovy-Klassen nutzen können – oder umgekehrt. Zwei Vorträge zum Einlesen:

JRuby

[Logo]JRuby ist die Java-Version der dynamisch getypten Programmiersprache Ruby. Sun beschäftigt mit Charles Nutter und Thomas Enebo (die ›JRuby Guys‹) zwei Entwickler, und bringt auch mit der Integration in die NetBeans IDE (J)Ruby weit nach vorne. Ruby wird mit einem Atemzug mit dem Web-Framework Ruby on Rails genannt, ein Framework für Web-Applikationen, welches dank JRuby auch auf jedem Tomcat und Java Application-Server läuft.

Jython

[Logo]Die beliebte Programmiersprache Python bringt Jython auf die Java-Plattform. Auch Jython übersetzt Python-Programme in Java-Bytecode und erlaubt relativ schnelle Ausführungszeiten. Jython 2.2 implementiert Python auf 2.2, doch hat sich (C-)Python mit Version 2.6 und 3 schon weiter entwickelt. Auch sonst gibt es Unterschiede, etwa bei den eingebauten (nativen) Funktionen. Sun hat im März 2008 Ted Leung und Frank Wierzbicki (Hauptentwickler von Jython) eingestellt, um Python auf der JVM weiter zu fördern.

Scala

[Logo]Scala ist eine Funktionale, objektorientierte Programmiersprache, die in der Java-Community große Zustimmung findet, obwohl sie von Martin Odersky erst 2001 entwickelt und 2004 vorgestellt wurde. Ein Eclipse-Plugin steht ebenfalls bereit. Für die .NET-Plattform gibt es ebenfalls eine Implementierung. Besonders zeichnet Scala ein durchdachtes Typsystem aus.

Quercus

Quercus ist eine Implementierung von PHP, welches insbesondere dazu geeignet ist, bestehende und beliebte PHP-Projekte in einer Java-Umgebung ablaufen zu lassen. In der Java-Welt werden zwar nicht alle PHP-Funktionen unterstützt, aber es gibt in der Java-Welt keine Speicherüberläufe oder Sicherheitsprobleme.

Jatha

Jatha ist eine ›Common LISP library in Java‹, eine Implementierung von Common LISP. Mit einer API lassen sich LISP-Programme aus Java heraus aufrufen.

LuaJava

[Logo]LuaJava implementiert die Programmiersprache Lua für die JVM. Die aus Brasilien stammende dynamisch getypte Programmiersprache Lua zählt zu den performantesten, interpretierten Skriptsprachen. Sie ist in erster Linie als eingebettete Programmiersprache zur Applikationssteuerung entworfen worden; prominete Nutzer sind Sim City, World of Worcraft, Adobe Photoshop Lightroom, SciTE.

Pnuts

Pnuts gehört zu den schnellsten Skriptsprachen auf der JVM. Die Sprache hat eine einfache Syntax und übersetzt Programme ebenfalls in Bytecode.

JBasic

Mit JBasic gibt es für die Java-Plattform einen BASIC-Dialekt, der sich an GW-BASIC anlehnt.

JLog

JLog implementiert einen ISO-Standardisierten PROLOG-Interpreter. JLog läuft in einem eigenen Fenster mit Quellcode-Editor, Query-Panel, Hilfe, Debugger, oder es kann in einem eigenen Java-Programm eingebettet werden.

Jacl

Jacl implementiert einen TCL-Interpreter in Java. Die Entwicklung ist nicht mehr aktiv.

 

Die Webseite http://www.robert-tolksdorf.de/vmlanguages.html führt weitere Programmiersprachen für die JVM auf. Allerdings sind viele der gelisteten Sprachen für sehr spezielle Anwendungsfälle entworfen, experimentell oder werden nicht mehr gepflegt.

Labels:

AddThis Social Bookmark Button

Donnerstag, Dezember 13, 2007

Beispiel für Apache Commons Events

http://commons.apache.org/sandbox/events/ bietet Wrapper für java.util Datenstrukturen, um Ereignisse beim Zugriff zu senden.

List<?> list = new ArrayList<String>();

ObservableList observedList = ObservableList.decorate( list );
observedList.getHandler().addPreModificationListener( new StandardPreModificationListener() {
public void modificationOccurring( StandardPreModificationEvent event )
{
if ( event.getType() == ModificationEventType.ADD )
System.out.println( event.getChangeObject() );
}
} );

observedList.add( "huhu" );
observedList.remove( 0 );

Die Bib ist schon älter, aber dennoch nur über die Versionsverwaltung zu bekommen. Schade eigentlich. Auch die Programm-API ist etwas "umständlich", und die Doku unvollständig.

Labels:

AddThis Social Bookmark Button

Freitag, November 23, 2007

jodconverter für OpenOffice Dateiformatkonvertierungen

Der zweite Schritt meiner Rechnungserstellung ist die Konvertierung in PDF. Auch dazu gibt es eine prima Bibliothek: http://www.artofsolving.com/opensource/jodconverter. (Einziger Nachteil: viele Jars.) Damit kann man Word, PowerPoint, RTF und alles andere in ein bliebiges Zielformat bringen.

private static void ensureStartedOpenOfficeService()
{
  try
  {
    new Socket( "127.0.0.1", 8100 );
  }
  catch ( Exception e )
  {
    String path = "C:/Programme/OpenOffice.org 2.3/program/";
    ProcessBuilder processBuilder = new ProcessBuilder( path+"soffice", "-headless", "-accept=\"socket,host=127.0.0.1,port=8100;urp;\"", "-nofirststartwizard" );

    try
    {
      processBuilder.start();
    }
    catch ( IOException ioe )
    {
      throw new RuntimeException( ioe );
    }
  }
}

public static void convert( String source, String destination )
{
  ensureStartedOpenOfficeService();

  OpenOfficeConnection connection = null;

  try
  {
    connection = new SocketOpenOfficeConnection( 8100 );     
    connection.connect();
    DocumentConverter converter = new OpenOfficeDocumentConverter( connection );
    File inputFile = new File( source );
    File outputFile = new File( destination );
    converter.convert( inputFile, outputFile );
  }
  catch ( ConnectException e )
  {
    throw new RuntimeException( e );
  }
  finally
  {
    connection.disconnect();
  }
}

Für meine Rechnungen also:

String destination    = "S:/Private/Traida/Bills/bill1";
String destinationOds = destination + ".ods";
String destinationPdf = destination + ".pdf";
convert( destinationOds, destinationPdf );

Labels: ,

AddThis Social Bookmark Button

OpenOffice als Template-Engine: Dokument einlesen, verändern, schreiben

Da ich meine Rechnungen automatisch generiert und als PDF konvertiert haben möchte, habe nach einer Lösung gesucht, wie ich die Rechnungsdaten aus einer Datenquelle in der Template einsetzten kann, und am Ende eine PDF bekomme. Klar sind Report-Generatoren dafür auf der Welt, aber meine Vorlagen möchte ich nicht für Eclipse BIRT oder Jasper schreiben, sondern in Word bzw. OpenOffice. RTF ist relativ leicht zu schreiben und für ein Template meines Erachtens ganz gut. Meine Gedanken kreisten daher einige Zeit um RTF->PDF, doch da gibt es keine freie Lösung. Auch Wege wie RTF->FO->PDF sind möglich, aber dafür gibt es ebenfalls keine leichtgewichtigen freien Lösungen.

Schon für meinen PowerPoint->PDF-Konverter habe ich mit OpenOffice gearbeitet und das klappte ganz gut. Das habe ich für meine Templates nun wieder überlegt -- ein recht harter Weg für simple RTFs zwar, aber es funktioniert. Doch anstatt RTF zu nutzen, wollte ich gleich das XML-Format verwenden. Dazu muss man wissen, dass OO ein Zip-Archiv für das OO-Dokument vorsieht und dort in einer XML-Datei den Content ablegt. Mit der großartigen Open-Source-Bibliothek https://truezip.dev.java.net/ ist der Zugriff auf Archive sehr einfach.

Mit TrueZIP ist eine einfache Lösung entstanden, ein OO-Dokument mit Template-Anweisungen wie ${address} zu lesen, Ersetzungen vorzunehmen, und alles wieder zu schreiben. Diesen Text hier zu schreiben hat länger gedauert, als die 90 Zeilen Quellcode. Also los:


import java.io.*;
import java.nio.channels.FileChannel;
import de.schlichtherle.io.ArchiveDetector;

public class OpenOfficeUtils
{
  public static void main( String[] args )
  {
    String source      = "S:/Private/Traida/Bills/template.ods";
    String destination = "S:/Private/Traida/Bills/bill1.ods";

    copyFile( source, destination );

    String content = readOpenOfficeContent( source );

    content = content.replace( "${addressline1}", "Christian Ullenboom" );

    writeOpenOfficeContent( destination, content );
  }

  public static String readOpenOfficeContent( String filename )
  {
    Reader is = null;

    try
    {
      de.schlichtherle.io.File file = new de.schlichtherle.io.File( filename + "/content.xml", ArchiveDetector.ALL );
      char[] fileContent = new char[ (int) file.length() ];
      is = new de.schlichtherle.io.FileReader( file );  // TODO: <?xml version="1.0" encoding="UTF-8"?>
      is.read( fileContent );

      return new String(fileContent);
    }
    catch ( IOException e )
    {
      throw new IllegalArgumentException( e );
    }
    finally
    {
      try { is.close(); } catch ( Exception e ) { }
    }
  }

  public static void writeOpenOfficeContent( String filename, String content )
  {
    Writer os = null;

    try
    {
      de.schlichtherle.io.File file = new de.schlichtherle.io.File( filename + "/content.xml", ArchiveDetector.ALL );
      os = new de.schlichtherle.io.FileWriter( file );
      os.write( content );
    }
    catch ( IOException e )
    {
      throw new IllegalArgumentException( e );
    }
    finally
    {
      try { os.close(); } catch ( Exception e ) { }
    }
  }

  public static void copyFile( String in, String out )
  {
    FileChannel inChannel  = null;
    FileChannel outChannel = null;

    try
    {
      inChannel  = new FileInputStream( new File(in) ).getChannel();
      outChannel = new FileOutputStream( new File(out) ).getChannel();
      inChannel.transferTo( 0, inChannel.size(), outChannel );
    }
    catch ( IOException e )
    {
      throw new IllegalArgumentException( e );
    }
    finally
    {
      try { inChannel.close(); } catch ( Exception e ) { }
      try { outChannel.close(); } catch ( Exception e ) { }
    }
  }
}

Labels: ,

AddThis Social Bookmark Button

Dienstag, März 13, 2007

JAX-WS 2.1 with Spring under Java 6

First you need some jars in your classpath of an web application

  • commons-logging.jar
  • jaxw-api.jar
  • jaxws-rt.jar
  • jaxws-spring-1.1.jar
  • saaj-api.jar
  • saaj-impl.jar
  • spring.jar
  • stax-ex.jar
  • streambuffer.jar
  • xbean-spring-2.8.jar

The Jars are from Spring itself, http://geronimo.apache.org/xbean/, https://jax-ws.dev.java.net/ (jax-ws 2.1, JAXWS2.1_nightly.zip) and https://jax-ws-commons.dev.java.net/spring/ (jaxws-spring-1.1.jar). It is although important to place

  • jaxb-api.jar
  • jaxb-impl.jar

under C:\Programme\Apache Software Foundation\Tomcat 5.5\common\endorsed.

This was the necessary and boring preparation.

Next the Web Service itself

package com.tutego.service;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class GreeterService
{
@WebMethod
public String greet( String name )
{
return "Hello " + name + "!"
}
}

And web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>SpringWeb</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>jaxws-servlet</servlet-name>
<servlet-class>
com.sun.xml.ws.transport.http.servlet.WSSpringServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jaxws-servlet</servlet-name>
<url-pattern>/greet</url-pattern>
</servlet-mapping>
</web-app>

The applicationContext.xml follows the suggestions with the namespace.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core.xsd
http://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet.xsd">
<ws:service id="greeterService"
impl="com.tutego.service.GreeterService" />
<wss:bindings id="jax-ws.http">
<wss:bindings>
<wss:binding url="/greet" service="#greeterService" />
</wss:bindings>
</wss:bindings>
</beans>

Now you can consume your WS. If your Web-Context is SpringWeb use http://localhost:8080/SpringWeb/greet?wsdl. Enjoy it!

Labels:

AddThis Social Bookmark Button

Spring in einer Web-Applikationen nutzen - so einfach ist das

Mit dem WTP ist es eine Sache von Minuten.

Lege ein Dynamic-Web-Projekt an. Nenne es etwa spring.

Aus dem Spring-all-in-one-glücklich.zip kopiere spring.jar und common-loggings.jar in das WEB-INF/lib.

Lege in WEB-INF eine Datei applicationContext.xml.

Setze in die Datei:

<?xml version="1.0" encoding="UTF-8"?> 


<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

<bean id="date" class="java.util.Date" />

</beans>


Setzte in WEB-INF/web.xml die Zeilen:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>


Schreibe eine index.jsp

<%@page import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@page import="org.springframework.context.ApplicationContext"%>
<%
ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
%>

<%= appContext.getBean("date") %>


Das war's. Unter http://localhost:8080/spring/ gibt's dann das Datum.

Labels:

AddThis Social Bookmark Button

Freitag, Februar 09, 2007

Absonderliche Schreibweise bei einer Feld-Rückgabe

Da blättere ich gerade durch das "Just Java" Buch und glaube, schon einen Fehler gefunden zu haben, da sagt mir der Compiler, dass alles in Ordnung ist:
public class T
{
public static int foo()[]
{
return new int[] { 1, 2, 3 };
}

public static void main( String[] args )
{
System.out.println( foo().length );
}
}

Diese sonderbare Rückgabe habe ich noch nie gesehen und ist mir in der Grammatik der Sprache Java auch noch nie aufgefallen.

Labels:

AddThis Social Bookmark Button