Archiv für die Kategorie ‘Java’

WebServices mit JBossWS realisieren

Dienstag, 14. Dezember 2010

Zur Zeit befasse ich mit mit der Realisierung von WebServices mit JBossWS in einem JBoss AS 4.2.3.GA. Hier möchte ich kurz zusammenfassen, was ich beachtet habe und wie ich bei der Service-Implementierung vorgegangen bin.

JBoss AS und Java6

Betrieben wird ein JBoss AS 4.2.3.GA (und ein 4.2.2.GA; Java 5 compiled binaries) in einer Java 6 Umgebung. Auf die Gründe, wesghalb kein JBoss AS 5.x eingesetzt wird möchte ich nicht näher eingehen und wir nehmen die Umgebung als gegeben hin. In dieser Umgebung gilt es allerdings folgenden Konfigurationshinweis aus der 4.2.3.GA Distribution zu beachten, die analog für Version 4.2.2.GA gilt:

JBossAS 4.2.3.GA can be compiled with both Java5 & Java6. The Java5 compiled binary is our primary/recommended binary distribution. It has undergone rigorous testing and can run under both a Java 5 and a Java 6 runtime. When running under Java 6 you need to manually copy the following libraries from the JBOSS_HOME/client directory to the JBOSS_HOME/lib/endorsed directory, so that the JAX-WS 2.0 apis supported by JBossWS are used:

  • jboss-jaxrpc.jar
  • jboss-jaxws.jar
  • jboss-jaxws-ext.jar
  • jboss-saaj.jar
  • jaxb-api.jar

JAX-WS und JAX-RPC

“JAX-WS” und “JAX-RPC” laufen einem immer wieder über den Weg, sobald man sich mit WebServices in der Java-Welt beschäftigt. Anfangs stellte sich mir die Frage, was sich hinter diesen Begriffen verbirgt und was dabei der Unterschied ist. Ich fand hierzu einen interessanten Artikel von Vamshi Rapolu in dessen Blog und ich verzichte an dieser Stelle näher auf die Beantwortung meiner Frage einzugehen. Weitere Informationen findet der interessierte Leser in diesem Artikel und sicherlich auch über die Suchmaschine seines Vertrauens.

Warum nicht Axis2?

Warum ich mich für JBossWS als WebService Framework entschieden habe und nicht für Apache Axis2 hat folgende Gründe:

Axis2 eignet sich vor allem für den Einsatz in einem Servlet-Container wie z.B. einem Apache Tomcat - ohne den Rattenschwanz eines Applikationsservers wie dem JBoss (Was ist der Unterschied?). Axis2 wird einfach als eigenständige Applikation “deployed” und steht danach als WebService-Container zur Verfügung, in den wiederum die Services “deployed” werden. Für meine Zwecke war dies eher ungeeignet, da sich der WebService zusammen mit anderen Applikationskomponenten in einem *.ear-Archiv veröffentlicht werden soll. Zwar gibt es Wege auch Axis2 als weitere Applikationskomponente in das Archiv zu packen, doch das erschien mir alles irgendwie “zusammengeflickt”. Außerdem bringt der JBoss AS selbst ein WebService-Framework mit: JBoss WS. Und warum soll man nicht auf vorhandenes zurückgreifen? Ein weiterer Vorteil ist, dass WebServices direkt mit EJB3 Stateless Session Beans implemntiert werden können und innerhalb des Services per Dependency Injection auf vorhandene EJBs zugegriffen werden kann. Dies war schließlich ausschlaggebend für die Entwicklung eines JAX-WS WebServices und damit der Verwendung von JbossWS.

Zur weiteren Lektüre gibt es bei predic8.de einen Vergleich von Axis2, CXF und der JAX-WS Referenzimplementierung.

Das Service-Interface

MyService.java

package de.budisantoso.examples.jaxws;

import javax.ejb.Remote;
import javax.jws.WebService;

@Remote
@WebService()
public interface MyService {
    public static final String ENDPOINT_INTERFACE = "de.budisantoso.examples.jaxws";
    public static final String NAMESPACE = "http://jaxws.examples.budisantoso.de/";
    public static final String SERVICE_NAME = "MyService";

    public String echo(String input);
    public void foo();
}

Im Interface habe ich ein paar Konstanten definiert, um sie bequem an zentraler Stelle konfigurieren zu können. Die @Remote-Annotation gibt an, dass es sich um ein EJB-Remote-Interface handelt und die @WebService-Annotation gibt an, dass dieses Interface einen WebService definiert.

Die Stateless Session Bean

MyServiceBean.java

package de.budisantoso.examples.jaxws;

import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@Stateless
@WebService(endpointInterface = MyService.ENDPOINT_INTERFACE, serviceName = MyService.SERVICE_NAME)
@SOAPBinding(style = javax.jws.soap.SOAPBinding.Style.DOCUMENT)
public interface MyServiceBean implements MyService {
    public static final String ENDPOINT_INTERFACE = "de.budisantoso.examples.jaxws";
    public static final String NAMESPACE = "http://jaxws.examples.budisantoso.de/";
    public static final String SERVICE_NAME = "MyService";

    @EJB
    private AnotherBeanRemote anotherBean;

    @Override
    @WebMethod()
    public String echo(String input) {
        return input;
    }

    @Override
    @WebMethod()
    public void foo() {
        anotherBean.bar();
    }
}

Die Implementierung des Interface erhält drei Annotationen:

  • @Stateless - EJB-Annotation, die angibt, dass es sich um eine Stateless Session Bean handelt
  • @WebService(…) - gibt an, dass es sich bei dieser Klasse um eine WebService-Implementierung handelt
  • @SOAPBinding(…) - hierüber wird das Mapping des WebService auf das SOAP Message Protocol definiert

Weitere Infos zu den WebService-Annotationen gibt es im JBoss Community Wiki bzw. direkt in der JSR-181.

Deployment

Das Service-Interface und die Service-Implementierung können zusammen mit weiteren Applikationskomponenten in einer *.ear-Datei gepackt werden. Auf den genauen Build-, Assembly-und Deploy-Prozess und die Projekt- und Archivstruktur möchte ich jedoch nicht weiter eingehen. Hat man schließlich das *.ear-Archiv erstellt, “schiebt” man es in das Deploy-Verzeichnis des JBoss, z.B. [JBOSS_HOME]/server/default/deploy und startet den Applikationsserver. Zugriff auf die automatisch generierte WSDL erhält man dann über die JBossWS-Webapplikation, die beispielsweise (bei Standardinstallation eines JBoss auf dem lokalen Rechner) unter folgender URL erreichbar ist:
http://localhost:8080/jbossws/

Kurz erwähnen und empfehlen möchte ich an dieser Stelle noch das Tool “soap-UI“, mit dem man WebServices schnell und einfach testen kann.

Der Service-Client

Die Implementierung des Service Client kann auf mehrere Wege erfolgen. Zum einen kann der WebService über JAX-WS Direktzugriff angesprochen werde. Daneben gibt es die Möglichkeit, generierte “Stubs” zu verwenden (z.B. über “wsconsume” oder auch über das Axis2-Tool “WSDL2Java”).

Hier ein Beispiel für den direkten Zugriff:

MyServiceClient.java

package de.budisantoso.examples.jaxws;

import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class MyServiceClient {

    private static final String _wsdl = "http://localhost:8080/examples/MyServiceBean?wsdl";

    public static void main(String[] args) {
        try {
            URL wsdlLocation = new URL(_wsdl);
            QName serviceName = new QName(MyService.NAMESPACE, MyService.SERVICE_NAME);

            // Load the service implementation class
            Service remoteService = Service.create(wsdlLocation, serviceName);

            // Load a proxy for our class
            MyService myService = (MyService) remoteService.getPort(MyService.class);

            // Execute a WebMethod
            String echo = myService.echo("Hello WebService-World!");
            System.out.println(echo);

            // Execute another WebMethod
            myService.foo();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Weitere Informationen

Kommentare und Verbesserungsvorschläge zu meinem Artikel sind natürlich sehr willkommen. Und auch falls es Fragen gibt, werde ich versuchen diese zu beantworten - dabei liegt die Betonung auf “versuchen” ;)

Spring3 + Hibernate + Jasypt

Donnerstag, 20. Mai 2010

Ich habe ein neues Java-Projekt, indem ich Hibernate zum ersten mal mit Spring und Jasypt einsetze. Spring und Hibernate dürften eher bekanntere Begriffe aus der Javawelt sein, so dass ich nur kurz erwähnen möchte, was Jasypt ist.

Jasypt steht für Java simplified encryption und bietet dem Entwickler bei kombiniertem Einsatz mit Hibernate eine für die Businesslogik transparente Verschlüsselung von zu persitierenden Daten.

Ich habe versucht, der Anleitung zum Einsatz von Jasypt mit Hibernate 3 zu folgen, erhiel aber immer wieder die folgende EncryptionInitializationException:

Exception in thread "main" org.jasypt.exceptions.EncryptionInitializationException: No string encryptor registered for hibernate with name "strongHibernateStringEncryptor"
at org.jasypt.hibernate.type.AbstractEncryptedAsStringType.checkInitialization(AbstractEncryptedAsStringType.java:250)
at ...

Nachdem ich mehrere Stunden verzweifelt nach der Ursache und meinem Fehler gesucht habe - mittels Google und Try’n'Error - bin ich auf einen Beitrag gestoßen, der mich schließlich auf die Lösung gebracht hat.

Nach einer kleinen aber wirkungsvolle Änderung in meiner Spring-Konfigurationsdatei applicationContext.xml (rot markiert) war der Fehler behoben …

applicationContext.xml

<?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:tx=”http://www.springframework.org/schema/tx
 xsi:schemaLocation=”
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-2.0.xsd“>
  <bean id=”strongEncryptor”
class=”org.jasypt.encryption.pbe.StandardPBEStringEncryptor”>
    <property name=”algorithm”>
      <value>PBEWithMD5AndDES</value>
    </property>
    <property name=”password”>
      <value>xJxAxSxYxPxTx</value>
    </property>
  </bean>
  <bean id=”hibernateStringEncryptor”
  class=”org.jasypt.hibernate.encryptor.HibernatePBEStringEncryptor”>
    <property name=”registeredName”>
      <value>strongHibernateStringEncryptor</value>
    </property>
    <property name=”encryptor”>
      <ref bean=”strongEncryptor” />
    </property>
  </bean>
  <bean id=”datasource” class=”com.mchange.v2.c3p0.ComboPooledDataSource”
  destroy-method=”close”>
    <property name=”driverClass” value=”com.mysql.jdbc.Driver” />
    <property name=”jdbcUrl” value=”jdbc:mysql://localhost:3306/mydatabase” />
    <property name=”user” value=”myusername” />
    <property name=”password” value=”mysecretpassword” />
    <property name=”minPoolSize” value=”2″ />
    <property name=”maxPoolSize” value=”4″ />
  </bean>
  <bean id=”hibernateSessionFactory”
    class=”org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean”
    depends-on=”hibernateStringEncryptor”>
    <property name=”dataSource” ref=”datasource” />
    <property name=”configLocation” value=”classpath:hibernate.cfg.xml” />
  </bean>
  <bean id=”myService”
  class=”tld.domain.service.MyServiceImpl”>
    <property name=”myBusinessObjectDao” ref=”businessObjectDao” />
  </bean>  <bean id=”businessObjectDao”
  class=”tld.domain.persistence.BusinessObjectDaoImpl”>
    <constructor-arg ref=”hibernateSessionFactory” />
  </bean>
  <!– Transaction handling –>
  <tx:annotation-driven transaction-manager=”txManager” />
    <bean id=”txManager”
  class=”org.springframework.orm.hibernate3.HibernateTransactionManager”>
    <property name=”sessionFactory” ref=”hibernateSessionFactory” />
  </bean>
</beans>

JAX2010 - Workshop und Konferenztag I

Donnerstag, 06. Mai 2010

Montag morgen. Ich bin nach über einer Stunde Stau mit einer kleinen Verspätung in Mainz angekommen. Leider keine Zeit mehr für eine Tasse Kaffee, der Workshop hat bereits begonnen. Also setze ich mich in eine der hinteren Reihen und merke, dass ich nicht allzuviel verpasst hatte.

Um was ging es im Workshop? Ich besuchte den Power Workshop “Einführung in das Spring Framework 3.0″. Eberhard Wolff, Referent des Workshops und Autor des Buchs Spring 3: Framework für die Java-Entwicklung, gab zunächst eine Einführung in die Konzepte von Spring 3 und zeigte den Teilnehmern eindrucksvoll die Anwendung dieser Konzepte in Life-Demonstrationen. Der interessanteste Teil war für mich die Einführung in die apektorientierte Programmierung (AOP) mit dem Spring Framework. Auch die Vorstellung von SpringRoo war beeindruckend. Aber irgendwo hab ich das schonmal gesehen: Codegenerierung und Scaffolding :-)

Zusammenfassend kann ich sagen, dass mir der Workshop einen guten Einblick und Einstieg in die Welt von Spring gegeben hat. Die Fragen, die ich mir stelle und die ich noch nicht beantwortet habe und auch noch nicht beantworten kann ist folgende: Sind EJB3 und Spring gegensätzliche Technologien? Welche Vorteile bietet mir die eine Technologie gegenüber der anderen? Wann ist es Sinnvoll einen ebedded Container zu verwenden und wann macht es Sinn auf JEE zurückzugreifen? Wie gesagt, für den Einstieg war der Workshop eine gelungene Veranstaltung, die in mir auf jeden Fall das Interesse an Spring geweckt hat.

Am nächsten Tag begann die eigentliche JAX2010 Konferenz mit diversen Vorträgen. In der ersten Keynote sprach Mike Piech (Oracle) über Java, die Community, die Technologien, über bisherige und zukünftige Entwicklungen in dem Javauniversum und gab einen Ausblick in welche Richtung die Wege der Kombination aus Sun und Oracle führen.

Im Anschluss daran ging es zum nächsten Vortrag: “Die richtige Architektur bei AJAX-Anwendungen” von Alois Reitbauer (dynaTrace Software). Der Vortrag war irgendwie nicht das, was ich bei dem Titel erwartet hatte, dennoch gab der Vortrag interessante Impulse. Gezeigt wurde vor allem, was man generell beachten sollte, um (subjektiv) performante AJAX-Applikationen zu erstellen.

Der nächste Vortrag den ich besuchte wurde gehalten von Jason van Zyl (Sonatype) mit dem Thema “Developing for the Enterprise with Maven, M2Eclipse, Nexus und Hudson. Dieser Vortrag bestätigte mich im Einsatz dieser bzw. ähnlicher Technologien (Eclipse IAM statt M2Eclipse, Artifactory statt Nexus). Es wurden die Tools im Einzelnen vorgestellt und darüberhinaus vermittelt, wie diese zusammenarbeiten und ineinandergreifend den Softwareentwicklungsprozess unterstützen. Außerdem sprach Jason van Zyl in seinem Vortrag über die derzeitigen und zukünftigen Entwicklungen dieser Technologien, insbesondere über Maven 3.

Nach dem Mittagessen gab es die nächste Keynote. Die “Vorstellung”, die die beiden Herren von der Accenture GmbH auf der Bühne präsentierten, war irgendwie nicht das Gelbe vom Ei. Neben der Selbstpräsentation und einem Video (Did you Know? 3.0) war die Message des Vortrags “From Art to Engineering - Designing technical Architectures for industrialized Software Development” nichts neues. Die Kommentare und Kritiken, die es im Anschluss an die Keynote über Twitter hagelte, war gelinde gesagt nicht die nettesten. :-)

Der nächste Vortrag behandelte das Thema Refactoring. Manuel Bork (Yatta Solutions GmbH) präsentierte in “Text to Model to Text” eine in Eclipse integrierte Modeling IDE (UML Lab), mit der aus bestehendem Quelltext ein Modell generiert werden und aus diesem Modell wieder exakt der selbe Code generiert werden kann. Dadurch erhält der Entwickler ein Werkzeug, mit dem er ein bestehendes Programm über Manipulation des generieten Modells verändern kann. Änderungen am Modell spiegeln sich im Code wieder und auch Änderungen am Code werden direkt in das Modell übernommen. Ein weiterer Schritt in Richtung MDD.

Der letzte Vortrag “Continuous Deployment and agile Testing”, den ich mir auf der JAX2010 angehört habe, wurde von Alexander Grosse (Nokia) gehalten. “Continuous Deployment” ermöglicht Entwicklern Software jederzeit auszuliefern. Alexander Grosse sprach in seinem Vortrag über seine Erfahrungen dieses Konzept in seinem Bereich einzuführen und stellte uns Best Practices in dieser Domäne vor.

Nach dem Abendessen endete der Konferenztag für mich. Die Abendveranstaltung habe ich nicht mehr miterlebt, da ich mich dafür entschieden hatte, nicht zu spät nach Hause zu fahren. Insgesamt kann ich sagen, dass es sich für mich gelohnt hat, die Konferenz zu besuchen, da ich allein an dem einen Tag viele Eindrücke und Impulse sammeln konnte. Falls es klappt, würde ich auch nächstes Jahr wieder die JAX besuchen.

JAX2010 - ich komme

Donnerstag, 25. März 2010

Im Mai findet die diesjährige JAX statt und ich habe das Vergnügen einen Workshop-Tag und einen, evtl. sogar zwei Hauptkonferenztage besuchen zu dürfen. Wer die JAX nicht kennt, sei mit folgender Wikipedia-Erläuterung aufgeklärt:

Die JAX ist eine Fachkonferenz für Softwareentwicklung und zusammen mit der OOP eine der größten Informationsveranstaltungen der IT-Branche zu diesem Thema in Deutschland. Sie findet aktuell in Mainz statt. Veranstalter der Konferenz ist der Software & Support Verlag. Der Name JAX ist ein Akronym für Java, Apache und XML.

 Auf meiner Agenda stehen:

Ich weiß, das ist für einen Tag Hauptkonferenz ein sehr ambitioniertes Programm, aber solange die Vorträge interessant sind … :)

Auf jeden Fall werde ich einen zusammenfassenden Artikel zu meinem JAX2010-Besuch verfassen und vielleicht ist auch der ein oder andere Vortrag einen eigenen Artikel wert.

JBoss5 und Apache Webserver erfolgreich verheiratet

Mittwoch, 24. März 2010

Wie schon in meinem letzten Artikel angekündigt, habe ich die Anbindung meines JBoss AS über mod_proxy_ajp an den Apache2 Webserver eingerichtet. Die Anleitung, die ich ebenfalls in meinem letzten Artikel erwähnt hatte, war mir dabei eine große Hilfe. Außerdem bin ich auf einige hilfreiche Seiten gestoßen, die ich euch nicht vorenthalten möchte:

Anleitung zur Installation eines JBoss AS 5.1.0 GA auf Debian 5

Freitag, 19. März 2010

Nachdem ich einen Debian 5 Server aufgesetzt und dort webmin, sun-java6-jdk, subversion, apach2 webserver, … installiert hatte, wollte ich einen JBoss AS installieren und wie immer zunächst einmal ein wenig gegoogelt …

Ich war dabei auch erfolgreich und habe eine gute Anleitung zur Installation eines JBoss AS 5 GA auf einem Debian Linux Server gefunden. Bis auf ein/zwei nicht erwähnenswerte Kleinigkeiten konnte ich alle Schritte wie beschrieben befolgen und bin sehr schnell zum Ziel gekommen.

Der nächste Schritt ist nun, den JBoss mit dem Apach2 Webserver via mod_proxy_ajp zu verheiraten, aber genug für heute, es ist Wochenende :)

Stripes 1.5 JAR dem “locale maven repository” hinzufügen

Mittwoch, 27. August 2008

Dank Daniel Ambrósios Blogeintrag war es mir ein leichtes, die aktuelle Version von Stripes (1.5) in meinem Projekt zu verwenden.

Folgende Schritte sind dazu notwendig:

  1. Download der aktuellen Version (zipped binary)
  2. Entpacken der Zip-Datei
  3. folgenden Befehl ausführen:
    mvn install:install-file -DgroupId=net.sourceforge.stripes -DartifactId=stripes -Dversion=1.5 -Dpackaging=jar -Dfile=./stripes-1.5/lib/stripes.jar(Nicht vergessen: ggf. Pfad anpassen!)

und das war’s dann auch schon :)

Stripes

Freitag, 22. August 2008

… and Java web development is fun again

So lautet der Titel des Buches zum Stripes Framework. Was ist Stripes eigentlich? Das BSI erklärt dies folgendermaßen:

Es handelt sich hierbei um ein Web-Framework für Java. Die Aufgabe des Stripes Framework ist es, die Entwicklung von Web-Applikation so weit wie möglich zu vereinfachen.

Ich bin zur Zeit dabei eben eine solche Web-Applikation zu programmieren und habe mich aufgrund der Anforderungen dafür entschieden, dies nicht in PHP zu tun, sondern eine Kombination aus Java, Hibernate, PostgerSQL, Tomcat und Stripes zu verwenden.

Das faszinierende an Stripes ist, wie einfach und unkompliziert es ist. Das Quickstart-Beispiel der Stripes-Website habe ich in null-komma-nix zum laufen gebracht, nachdem ich eine kleine Hürde geschafft hatte: Wie lautet die Maven IDs für Stripes?

Hier hat sich der Blick in die FAQ gelohnt und auch das Maven Repository hilft weiter. Für alle, die an dieser Stelle nicht weitersuchen möchten:
<dependency>
<groupId>net.sourceforge.stripes</groupId>
<artifactId>stripes</artifactId>
</dependency>

Bisher bin ich richtig begeistert und hoffe, das meine Begeisterung auch im Verlauf meines derzeitigen Projekts anhält.