Mittwoch, 30. Dezember 2009

Vorbereitung für Zertifizierungen zum SCWCD & SCWSD

Wer die Prüfung zum Sun Certified Java Programmer (SCJP) hinter sich hat und in letzter Zeit geplant hat, weitere Zertifizierungen zu holen, traf in den letzten Monaten auf ein mehr oder minder großes Problem. Es gab keine passenden Bücher zur aktuellen Version von Java 5 bzw. Java 6. Es blieb nur, sich direkt mit den Tutorials von SUN auseinander zu setzen oder alternativ die teuren Schulungsunterlagen von SUN zu bestellen.

Hier hat sich nun endlich wieder ein wenig getan. Zumindest mal im Bereich der Prüfungsvorbereitung für den Sun Certified Web Component Developer (SCWCD 5) bzw. den Sun Certified Web Services Developer (der ja erst neu in das Sortiment der SUN-Prüfungen aufgenommen wurde).

Zum einen sei da das HEAD FIRST - Werk zu erwähnen, welches ich aktuell bestellt habe. Ich werde diesen Post bei Gelegenheit updaten, um meine Erfahrung mit dem Buch einfließen zu lassen. Allerdings habe ich dieses Buch entsprechend der Amazon-Empfehlung auf Englisch bestellt und plane auch weiterhin, meine Zertifizierungen auf Englisch vorzunehmen. Hier also der Link für alle, die SCWCD werden wollen ;)



Zu diesem Buch gibt es sogar eine Alternative, welche jedoch Einsteigern wohl aufgrund des Schwierigkeitsgrades weniger zu empfehlen ist als die zuerst genannte Variante:



Für den Sun Certified Web Services Developer (SCWSD 5) muß man sich noch ein wenig gedulden. Februar ist jedoch eine Zeit, die man wohl noch abwarten kann. Denn dann erscheint das jetzt schon vorbestellbare Werk mit dem schönen Titel "Sun Certified Developer for Java Web Services: Study Guide (Exam 310-220) (Certification Press)". Letzteres erwähntes Buch erscheint von Mcgraw-Hill Professional, von denen ich persönlich aufgrund meiner bisherigen Erfahrung ehrlich gesagt ziemlich begeistert bin. Das Buch wird also definitiv auf meinem Schreibtisch landen und ist eine Empfehlung wert:



Mich würde an dieser Stelle auch ein Feedback interessieren, wer schon Erfahrung mit den CDs oder Web-Kursen von SUN direkt gemacht hat. Wie waren diese aufgebaut, lohnte sich die Zusatzausgabe und wie umfangreich war dieses Material? Vielleicht meldet sich ja an dieser Stelle der eine oder andere Leser ... Ihr seid gefragt ;)

Dienstag, 1. Dezember 2009

Filtern von Problemen auf Projektebene

Ein nettes kleines Feature von Eclipse, welches bei mir bisher leider unterging, habe ich heute kennengelernt und möchte es euch nicht vorenthalten. Ausgehend von einer Situation, in der man mehrere Projekte in seinem Eclipse offen hat, kann man ggf. schnell den Überblick verlieren, wenn man das nicht richtig managed. Beispielsweise werden Kompilierfehler und Warnungen von allen Projekten in einer Liste angezeigt. Arbeitet man jedoch aktuell nur an einem Projekt, muß man nicht zwingend alle anderen Projekte schließen. Es reicht, den folgenden Filter einzurichten, und man findet umso schneller wieder zu den Fehlermeldungen, die auch wirklich im aktuell zu bearbeitenden Projekt vorliegen.

Donnerstag, 17. September 2009

Leidenschaftliches Java

Ich bin heute auf eine sehr umfangreiche und interessante Seite gestoßen, welche Online-Kurse und viel Material zu Java und vielen damit zusammenhängenden Themen anbietet. Wer seine Kentnisse zu Java etwas vertiefen will, sollte hier unbedingt mal vorbeischauen:

http://www.javapassion.com

Freitag, 28. August 2009

Die Suche nach Beispielen...



Ich bin gerade auf eine interessante Homepage gestoßen. Diese kann hilfreich sein, wenn man mal nach beispielhaften Anwendungen diverser Java-Befehle suchen möchte. Dabei wird der eingegebene Begriff, wie z.B. Calendar oder Properties genommen und in Open Source Anwendungen nach Anwendungsbeispielen gesucht. Diese werden dann mit Packagenamen und sauber formatiertem Quellcode präsentiert. Ich denke, das kann durchaus dem einen oder anderen helfen. Der Link ist:

http://www.jexamples.com/search.html

Donnerstag, 16. Juli 2009

Checkliste JBoss-> Glassfish

Ich bin derzeit damit beschäftigt, meine JavaEE Anwendung soweit zu konfigurieren und zu testen, daß sie unter mehreren, führenden Applicationservern sowie Persistence Providern deployed werden kann. Mein Vorhaben war erfolgreich, stellte sich jedoch als anfangs etwas aufwändig heraus. Ich kann hier keinen vollständigen Bericht abliefern, was alles getan werden muß, um eine in JBoss laufende Applikation in Glassfish zum Deployen zu bekommen. Jede Anwendung ist an sich auch unterschiedlich. Aber eine kleine Checkliste möchte ich niemandem vorenthalten. Meine Anwendung verwendet dabei EJB3, JPA, Hibernate unter JBoss sowie Toplink unter Glassfish, JSF und Facelets.

Die einzige Konfigurationsdatei, an die man beim Deployen in einer anderen Umgebung noch anfassen muß in meinem Fall, ist die persistence.xml. Grund hierfür ist der Persistence Provider. Dieser wird von mir verwendet, um Tabellen automatisch generieren zu lassen.

Hibernate

Create:
<property name="hibernate.hbm2ddl.auto" value="update"/>

Drop & Create:
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>

Toplink

Create:
<property name="toplink.ddl-generation" value="create-tables"/>
<property name="toplink.ddl-generation.output-mode" value="both"/>

Drop & Create:
<property name="toplink.ddl-generation" value="drop-and-create-tables"/>

EclipseLink

Create:
<property name="eclipselink.ddl-generation" value="create-tables"/>

Drop and create
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>

Eine beispielhafte persistence.xml könnte also so aussehen:


<?xml version="1.0" encoding="UTF-8"?>
<!--
(C) 2009 Frederik Mortensen
-->
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="yourPU" transaction-type="JTA">

<!-- GlassFish Configuration //-->
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<jta-data-source>jdbc/yourdb</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="toplink.ddl-generation" value="create-tables"/>
<property name="toplink.ddl-generation.output-mode" value="both"/>
</properties>
<!-- End of GlassFish configuration -->

<!-- JBoss Configuration -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/yourdb</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
<!-- End of JBoss Configuration -->

</persistence-unit>
</persistence>


Desweiteren muß für eine Unabhängigkeit von der Implementation des Application Servers dafür gesorgt werden, daß alle benötigten .JAR-Dateien vorhanden sind. JBoss liefert einige dieser .JARs bereits mit, die beim Deployen in GlassFish leider fehlen.

Auch über das Logging muß man sich Gedanken machen. Wer in JBoss log4J nutzte, wird feststellen, daß GlassFish hier mit dem in Java mitgelieferten Logging einen anderen Weg beschreitet. Mit einer gültigen log4j.xml sowie log4j.dtd im /src - Verzeichnis kann man jedoch weiterhin auf dieses Protokollierungsverfahren bauen. Anbei ein kleines Beispiel, wie dieses Logging integriert werden kann:

Log4j.dtd
Enthalten im Log4J-Bundle (evtl. also bereits auf Ihrer Festplatte):
Log4J v1.2

Log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<!--
(C) 2009: Frederik Mortensen
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="yourappAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="datePattern" value="'.'yyyy-MM-dd" />
<param name="file" value="logs/yourappWeb.log" />
<param name="Append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{dd.MM.yyyy HH:mm:ss} %C: %m %n" />
</layout>
</appender>

<root>
<priority value="INFO" />
<appender-ref ref="yourappAppender" />
</root>

</log4j:configuration>


Hat man also dafür gesorgt, daß alle JAR-Dateien (commons-logging, log4j, RichFaces...) nun inkludiert sind und die persistence.xml angepasst wurde, sowie das Logging berücksichtig wurde, gibt es noch zwei größere Baustellen: Queries und Lookups.

Bei den EJBQueries ist darauf zu achten, daß sie wie in den Spezifikationen verwendet werden. Das heißt voll ausgeschrieben wie beispielsweise:
"SELECT alias FROM ENTITY alias WHERE..."
JBoss war da weniger restriktiv, da konnte man auch einmal nur mit der FROM clause beginnen, unter Umständen auch mal mit einem kleingeschriebenen "from" oder ähnlichem. Dies führt jedoch in Glassfish zu Problemen. Passt man seine Queries entsprechend an, laufen sie weiterhin in JBoss, aber nun auch in Glassfish.

Hier noch kurz die Unterschiede zwischen JBoss-Lookups und Glassfish-Lookups (ich arbeite daran, eine Lösung zu finden, die in JBoss und Glassfish einheitlich funktioniert). Ich habe den Lookup in eine Klasse EJBService ausgelagert:


package de.mortensenit.yourproject.web.util;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;

public class EJBService {

private static EJBService singleton;
private static Context ctx;

private EJBService() throws NamingException {

if (ctx == null) {
ctx = new InitialContext();
}
}

public static T lookup(Class ejbClassType, String name) {

if (singleton == null) {
try {
singleton = new EJBService();
} catch (NamingException ne) {
throw new RuntimeException(ne.getLocalizedMessage(), ne);
}
}

try {
InitialContext ctx = new InitialContext();
// JBoss: final Object object = ctx.lookup("yourapp/" + name);
// Glassfish: final Object object = ctx.lookup(ejbClassType.getName()); //Name of the interface
final Object object = ctx.lookup(ejbClassType.getName());

if (ejbClassType.isAssignableFrom(object.getClass())) {
return (T) object;
} else {
throw new RuntimeException("EJBService - Class found: " + object.getClass() + " cannot be assigned to type: " + ejbClassType);
}

} catch (NamingException e) {
throw new RuntimeException("EJBService - Unable to find ejb for " + ejbClassType.getName(), e);
}
}

}


Wer neu bei Glassfish ist, muß vor dem Deployen seiner Anwendung zuerst mal ein paar Dinge beachten. Es muß eine Domain erstellt werden, in der die Anwendung letztlich laufen wird. Es muß der JDBC-Treiber in diese Domain kopiert werden und ein Connection Pool angelegt werden. Wenn man also all die aufgezählten Punkte dieses Posts in einer Checkliste zusammenfassen möchte, kommt man in etwa hierzu:

- Anlegen der Domain (asadmin > create-domain --adminport 4848 yourapp)
- Kopieren von postgres/mysql... jdbc.jar in das yourdomain\lib\ext Verzeichnis
(Falls postgres genutzt wird, JDBC4 verwenden!)
- Erzeugen eines ConectionPools im JSF Admin Dialog des Glassfish AppServers (per Ping testen!)
- Erzeugen einer JDBC Connection, die den ConnectionPool benutzt (jdbc/yourapp)
- Wenn log4j verwendet wird, einbinden von log4j.dtd and log4j.xml (JBoss didnt need
- Ggf. Lookups anpassen
- persistence.xml anpassen auf den aktuellen Persistence Provider
- Falls man @mappedsuperclass verwendet hat, muß diese Annotation gelöscht und durch @Entity ersetzt werden, da @mappedsuperclass in Glassfish leider nicht funktioniert (derzeit).
- EJBQueries ggf. anpassen auf den JavaEE5 Standard, siehe oben
- Falls das Schema der Datenbanktabellen in JBoss durch Hibernate angelegt wurde, muß dieses evtl. bei früherer Verwendung von @mappedsuperclass gedroppt und neu angelegt werden. Allerdings sind die datenbankseitigen Unterschiede zwischen Hibernate und Toplink minimal.

Das wars. Viel Glück und bei Fragen wie immer einfach einen Kommentar hinterlassen ;)

Mehr Informationen zum Thema:
EclipseLink JPA
Logging Patterns

Sonntag, 12. Juli 2009

Dependency Injection in JSF

Neben dem klassischen Lookup gibt es in JavaEE5 die Verwendung von Annotations und der Dependency Injection (kurz DI). Diese DI wird auch in JSF unterstützt. So ist es in JBoss wie auch in Glassfish möglich, eine Session Bean per DI wie folgt injecten zu lassen:


//imports

class MyManagedBean {

@EJB private MySessionBeanLocalIF mySessionBean;

//some class using mySessionBean

}


Das erspart das Tippen des Lookups. Die einzigen Bedingungen sind dabei, daß die Variable weder static noch final sein darf. Nähere Informationen dazu gibt es auch in den JavaEE5 Specs:



Link zur Spezifikation, Abschnitt 5.2.3 Annotations and Injection

Weiterhin ist dabei zu beachten, daß managed Beans NICHT einfach per new-Operator instanziiert werden dürfen in diesem Fall. Hat man beispielsweise in einem Converter eine Methode, die über das managed Bean auf eine Session Bean zugreifen möchte, wird es zu einer NullpointerException kommen. Managed Beans holt man sich in diesem Fall also nicht per Instanziierung, sondern wie folgt:


ELContext elContext = FacesContext.getCurrentInstance().getELContext();
ELResolver elResolver = context.getApplication().getELResolver();
AccountManagementMB accountManagement = (AccountManagementMB) elResolver.getValue(elContext, null, "accountManagement");
return accountManagement.findCountryByName(value);


Dies führt dazu, daß die Dependency Injection berücksichtig wird und im managed Bean (hier beispielsweise AccountManagement) auf dessen Session Bean zugegriffen werden kann.

Sonntag, 5. Juli 2009

Missing dependencies - JBoss 5 Deployment

Ich habe gerade leider viel zu viel Zeit mit einem sehr unscheinbaren Fehler verbracht. Um diesen Ärger und die lange Fehlersuche anderen zu ersparen, poste ich hier einmal die Fehlermeldung und die dazugehörige Lösung, welche simpler nicht hätte sein können (wenn man es weiß):


2009-07-06 00:01:36,500 ERROR [org.jboss.system.server.profileservice.ProfileServiceBootstrap] (main) Failed to load profile: Summary of incomplete deployments (SEE PREVIOUS ERRORS FOR DETAILS):

DEPLOYMENTS MISSING DEPENDENCIES:
Deployment "jboss.j2ee:ear=myProject.ear,jar=myProjectCore.jar,name=MySessionBean,service=EJB3" is missing the following dependencies:
Dependency "&lsaquounknown ear="myProject.ear,jar="myProjectCore.jar,name="MySessionBean,service="EJB3">" (should be in state "Described", but is actually in state "** UNRESOLVED Demands 'persistence.unit:unitName=myProject.ear/myProjectCore.jar#myPersistenceUnitPU' **")
...
...
...
Deployment "persistence.unit:unitName=myProject.ear/myProjectCore.jar#myPersistenceUnitPU" is missing the following dependencies:
Dependency "jboss.jca:name=
java:/mypostgresdb
,service=DataSourceBinding" (should be in state "Create", but is actually in state "** NOT FOUND Depends on 'jboss.jca:name=
java:/mypostgresdb
,service=DataSourceBinding' **")

DEPLOYMENTS IN ERROR:
Deployment "&lsaquounknown ear="myProject.ear,jar="myProjectCore.jar,name="MySessionBean,service="EJB3">" is in error due to the following reason(s): ** UNRESOLVED Demands 'persistence.unit:unitName=myProject.ear/myProjectCore.jar#myPersistenceUnitPU' **
Deployment "jboss.jca:name=
java:/mypostgresdb
,service=DataSourceBinding" is in error due to the following reason(s): ** NOT FOUND Depends on 'jboss.jca:name=
java:/mypostgresdb
,service=DataSourceBinding' **


Des Rätsels Lösung hierbei war der Eintrag in der persistence.xml:


<jta-data-source>java:/mypostgresdb</jta-data-source>

versus

<jta-data-source>
java:/mypostgresdb
</jta-data-source>


Diese Datasource MUSS zwingend in einer Zeile erfolgen, ein Zeilenumbruch innerhalb des jta-data-source-Tags ist nicht möglich.

Freitag, 3. Juli 2009

Webservices mit EJB3 - Teil II

Mittlerweile konnte ich (mit ein Wenig Hilfe, Danke an dieser Stelle ;) ) feststellen, daß das Benutzen von Webservice-Clients in Java6 auch ohne Axis2 möglich ist. Auch den für Eclipse erwähnten Webservice-Client-Wizzard kann man ersetzen, indem man direkt die von diesem Wizzard aufgerufene EXE namens wsimport.exe aufruft, welche in JDK6 enthalten ist. Eine genauere, aber kompakte Beschreibung, wie man vorzugehen hat, findet sich auch hier:

http://www.vogella.de/articles/JavaWebservice/article.html#wsexample_client

Viel Spaß beim Ausprobieren.

Samstag, 20. Juni 2009

XHTML in Eclipse validieren

Ich bin derzeit am Erstellen einer Webapplikation mit JSF. Dabei benutze ich Facelets und somit .xhtml-Seiten anstatt der herkömlichen .jsf-Seiten. Die normale Eclipse Ganymede Installation unterstützt allerdings erstmal im Web page editor keine Validierung von XHTML. Auch die Auto-Vervollständigung mittels Code Assistent will nicht so, wie man es gewohnt ist. Diese Probleme kann man jedoch ändern unter
  • Windows
  • Preferences
  • General
  • Content Types
  • JSP
  • File associations -> Add...
Da ich das für sehr nützlich halte und selbst immer mal wieder darüber stolpere, poste ich diese Info zusammen mit dem Screenshot kurz an dieser Stelle. Kann aber durchaus sein, daß das Editieren mit den JBoss Tools noch komfortabler von statten geht. Nur sind diese nicht immer in jedem Eclipse installiert.


Desweiteren bin ich mir nicht sicher, einen Tipp in dieser Arbeit bereits einmal bei javathreads.de nachgelesen zu haben. Falls mich mein Gedächtnis trügt, lohnt es sich dennoch trotzdem, ab und an bei diesem Blog vorbeizusehen ;) Ich jedenfalls halte es für einen großen Vorteil, mit RSS-Feeds zu arbeiten und sich bei vielen guten Java-Seiten und Blogs auf dem Laufenden zu halten. Das erweitert das Wissen um Java ungemein. Wer ein Google Konto besitzt, kann dafür gleich auf seiner personalisierten iGoogle-Startseite den NewsReader sowie GoogleMail angezeigt bekommen und im NewsReader sogar anhand von Begriffen nach Artikeln über seine abonnierten Quellen suchen lassen. Aber ich schweife ab... ;)

Donnerstag, 18. Juni 2009

Webservices mit EJB3

In einem schon etwas älteren Artikel bin ich bereits auf das Arbeiten mit JPA / EJB3 eingegangen. Ziel war es, mit Entity Beans Datenbanktabellen generieren zu lassen. In EJB3 Projekten kommen aber neben den Entity Beans natürlich auch Stateless und Statefull Session Beans zum Einsatz. Darin wird die Geschäftslogik gehalten. In diesem Artikel will ich nun etwas kompakt zeigen, wie diese Stateless Session Beans als Webservices genutzt werden können und wie man per SOAP auf diese Webservices zugreifen kann.

Entscheidend sind dabei folgende Annotations, die mal anhand eines Beispieles aufgezeigt werden:


package de.mortensenit.webservicedemo.person.actions;

import java.util.Date;

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
* Session Bean implementation class PersonActionDemo
*
* © 2009
*
* @author Frederik Mortensen
*/
@WebService
@SOAPBinding(style = Style.RPC)
@Stateless
public class PersonActionDemo
implements PersonActionDemoLocal,
PersonActionDemoRemote {

/**
* Person maintainance webservice, takes care of inserting and upating the
* person
*
* @param surname
* @param forename
* @param birthdate
* @return
*/
@Override
@WebMethod
public Boolean maintainPersonWS(
@WebParam(name = "surname") String surname,
@WebParam(name = "forename") String forename,
@WebParam(name = "birthdate") Date birthdate) {

// do soemething...
return true;

}

}


Die ersten zwei verwendeten Annotations betreffen dabei die Klasse an sich und lauten:
  • @WebService
  • @SOAPBinding(style=Style.RPC)
Diese Annotations ermöglichen es der Klasse, als Webservice Endpoint zu fungieren, weitere Parameter der Annotation sind optional.

Die eigentliche, aufgerufene Methode des Webservices erhält ebenfalls Annotationen:

  • @WebMethod
  • @WebParam(name="surname")
Mit der WebParam Annotation hat man hier die Möglichkeit, den nach aussen hin sichtbaren Parameter des Webservices umzubenennen und sprechende Namen zu verwenden.

Deployt man nun sein Projekt auf dem Application Server, sieht man in der JBoss Management Console unter "jboss.ws" den eigenen, neu kreierten Endpoint. Desweiteren wird nun von JBoss aus eine WSDL-Datei generiert, welche unter folgendem Pfad erreichbar sein sollte:

http://localhost:8080/{context}/{endpoint}?wsdl (Context und Endpoint sieht man in der Management Console)

Alles, was man nun zu seinem Glück noch braucht, ist ein Webservice Client. Den kann man in den aktuellen IDEs wie Eclipse und NetBeans bereits selbständig generieren lassen. Auch in .NET ist dies vollautomatisch möglich. Wer es in Eclipse ausprobieren möchte, muß zuerst Axis2 installiert haben. In Eclipse sollte man nun unter...

  • Windows
  • Preferences
  • Web Services
  • Axis2 Preferences
die Axis2 Runtime Location angeben. Ist dies einmal gespeichert, steht ein neuer Wizzard zur Verfügung:
  • File
  • New
  • Other
  • Web Service Client
Dort muß unter "Service definition" der Pfad zur WSDL-Datei angegeben werden. Nun wird ein Stub und ein CallbackHandler generiert. Wer statt mit Eclipse lieber den klassischen Weg über die Konsole gehen möchte, kann auch direkt die nötige Batch-Datei aufrufen. Zu finden ist diese unter:

{axis2installordner}\bin\wsdl2java.bat


Ruft man diese Batch-Datei mit dem Parameter -uri auf und gibt den Pfad zur WSDL-Datei an, wird ein src-Ordner erstellt, der ebenfalls Stub und CallbackHandler als generierte Klassen enthält.

Sind also Stub und co. durch den Wizzard erst einmal generiert, kann man folgende Testklasse mit Main-Methode erstellen, um den SOAP-Aufruf durchzuführen:


package de.mortensenit.webserviceclientdemo.person;

import java.rmi.RemoteException;
import java.util.Calendar;
import org.apache.axis2.AxisFault;
import de.mortensenit.webserviceclientdemo.PersonActionDemoServiceStub.MaintainPersonWS;

public class SoapTest {

public static void main(String[] args) {

try {
//filling webservice parameters
MaintainPersonWS webService = new MaintainPersonWS();
webService.setForename("Frederik");
webService.setSurname("Mortensen");
webService.setBirthdate(Calendar.getInstance());

//calling webservice
new PersonActionsServiceStub().maintainPersonWS(webService);
}
catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
catch (RemoteException remoteException) {
remoteException.printStackTrace();
}

}

}


Ruft man nun die Main-Methode auf, wird der Webservice via SOAP aufgerufen und mit den Parametern befüllt, die man ausgewählt hat. Soeben haben Sie Ihren ersten Webservice erstellt. Sollten Probleme oder Fragen auftreten, bin ich gerne bereit, auf Kommentare auch per E-mail zu antworten und zu helfen.

Mögliche Fehlerquellen:
Leider hat mir die bei mir im Einsatz befindliche JBoss-Version jboss-4.2.3.GA echte Bauchschmerzen bereitet mit folgender Exception:


ERROR [SOAPFaultHelperJAXWS] SOAP request exception
java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage

Herausgekommen ist, daß sich diese JBoss-Variante mit der aktuellen Java6-Version nicht verträgt. Es gibt jedoch ein leichtes Workaround. Man muß die von JBoss verwendete Datei {jboss-installordner}\lib\jboss-saaj.jar in das Unterverzeichnis endorsed kopieren. Dies führt dazu, daß die von JBoss mitgelieferte Implementierung der Klasse SOAPMessage vorgezogen wird vor dem installierten JRE.

Quellen:
https://jax-ws.dev.java.net/jax-ws-ea3/docs/annotations.html

Donnerstag, 11. Juni 2009

Auf zu neuen Zielen ... SCBCD

Die Entscheidung ist gefallen! Der Sun Certified Business Components Developer (SCBCD) wartet auf mich. Der SCJP hat meinen Appetit nach mehr geweckt. Außerdem befasse ich mich ja sowieso bereits mit den Thematiken, die Inhalt dieser Prüfung sind. Nur diesmal scheint es etwas schwerer zu werden. Nicht nur aufgrund des neuen Stoffes, sondern leider auch aufgrund der Tatsache, daß es keine aktuellen Bücher als Prüfungsvorbereitung gibt.

Eine Übersicht aller Zertifizierungen findet man hier:
https://www.suntrainingcatalogue.com/eduserv/client/learningPath.do?p=/training/certification/java/index.html

Die genaue Bezeichnung der von mir gewählten Prüfung lautet:
Sun Certified Business Component Developer for the Java Platform, Enterprise Edition 5 (CX-310-091).

Hierzu empfohlen werden von SUN zwei Schulungen, die man beispielsweise als CD-ROM oder Web-Variante käuflich erwerben kann:
Da ich bisher mit den CD-ROMs als Prüfungsvorbereitung keine Erfahrungen gemacht habe, würde ich mich über ein Feedback und einen Erfahrungsbericht natürlich sehr freuen. Bis dahin kann ich zumindest allen interessierten Lesern schon einmal folgende Links nahelegen, um nähere Informationen zur Prüfungsvorbereitung zu erhalten:

Die Java-Ranch und deren SCBCD-Forum:
http://www.coderanch.com/forums/f-70/EJB-Certification-SCBCD

Der SCBCD 5.0 Study Guide von Mikalai Zaikin:
http://java.boot.by/scbcd5-guide/

Wenn ich weitere Informationen über die Prüfung finde, stelle ich sie hier gerne zur Verfügung. Ich würde mich aber wie schon erwähnt freuen, auch von euch Feedback und Tipps zu erhalten. Allen, die diese Prüfung selbst demnächst in Angriff nehmen, wünsche ich natürlich viel Glück und Erfolg! Oder wie man auf klingonisch (einer Sprache, die Java bereits mit eigenem language code unterstützt) so schön sagt,.. Qapla’!

Mittwoch, 3. Juni 2009

SyntaxHighlighter

Ich habe gerade ein wenig am Blog geschraubt und bin nun glücklicherweise in der Lage, den geposteten Quellcode noch sauberer formatiert anzeigen zu lassen. Inklusive der Möglichkeit, den Quellcode kopieren und ausdrucken zu können sowie mit Anzeige von Zeilennummern. Zu verdanken ist diese Anzeige einem netten und leicht einzubindenden Tool namens SyntaxHighlighter. Zu finden ist es hier:

http://alexgorbatchev.com/wiki/SyntaxHighlighter

Und installierbar ist es umso einfacher. Der folgende Quellcode dient somit gleichzeitig als Installationsanleitung und erste Demo ;) Einfach unter Anpassen in der Menüleiste von blogger auf die Lasche Layout wechseln, dort auf HTML bearbeiten klicken und zu guter Letzt nach dem <head> Tag folgende Zeilen einfügen:


<!-- ANFANG SyntaxHighlighter//-->
<link href="'http://alexgorbatchev.com/pub/sh/2.0.278/styles/shCore.css'" rel="'stylesheet'" type="'text/css'/">
<link href="'http://alexgorbatchev.com/pub/sh/2.0.278/styles/shThemeDefault.css'" rel="'stylesheet'" type="'text/css'/">
<script src="'http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shCore.js'" type="'text/javascript'/">
<script src="'http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushJScript.js'" type="'text/javascript'/">
<script src="'http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushCSharp.js'" type="'text/javascript'/">
<script src="'http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushSql.js'" type="'text/javascript'/">
<script src="'http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushJava.js'" type="'text/javascript'/">
<script src="'http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushXml.js'" type="'text/javascript'/">
<script type="'text/javascript'">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
</script>
<!-- ENDE SyntaxHighlighter //-->


Wenn man diese Änderungen speichert und beim nächsten Post im HTML-Bearbeitungsmodus das folgende Tag nutzt, erscheint der Quellcode künftig formatiert:

<pre class="brush: java">
public class Test {
private String name = "myName";
}
</pre>


public class Test {
private String name = "myName";
}


Vielleicht habe ich damit ja dem einen oder anderen helfen können.

Montag, 18. Mai 2009

UTF8 in Eclipse - OpenSource trotz Windows

Sollte der eine oder andere Leser planen, demnächst ein neues Projekt zu starten und dies eventuell sogar online zu stellen, habe ich hier einen kleinen Tipp. Wichtig ist es auch für Unternehmen, in denen Windows und Linux als Betriebssysteme für Entwicklungsrechner gemischt eingesetzt werden. Denn sollte man einmal eine eingecheckte Datei eines Kollegen bekommen und sich über Sonderzeichen wundern, wird das wohl an den unterschiedlichen Zeichensätzen liegen.

Um daher nicht nach der Hälfte des Projektes alle eingecheckten Dateien noch einmal anfassen zu müssen, empfiehlt sich in Eclipse folgende Einstellung:

"Windows - Preferences" -> "General - Text File Encoding" - Other: UTF-8.

Somit sollten zumindest alle Java-Dateien in UTF-8 gespeichert sein. Die .properties-Dateien jedoch sind weiterhin in LATIN-1 (ISO 8859-1) gespeichert. Wer darüber mehr lesen will, kann dies hier nachlesen:

http://www.thoughtsabout.net/blog/archives/000044.html

Freitag, 15. Mai 2009

Eclipse - Einblenden versteckter Dateien

Es passiert mir immer mal wieder, daß Eclipse interne Konfigurationsdateien anpasst, die für das Projekt benötigt werden. Da diese mit einem . als Dateinamen anfangen, werden sie jedoch im Package Explorer nicht angezeigt. Löscht man nun ein eingechecktes Projekt beispielsweise und checkt es später wieder aus in SVN oder anderen Versionsverwaltungstools, kann es passieren, daß das Projekt invalid ist oder weitere Konfiguration benötigt, die man bereits vorgenommen hatte und von der man davon ausging, sie wäre eingecheckt.

Um das zu verhindern, kann man im Package Explorer in der oberen rechten Ecke auf ein nach unten zeigendes Dreieck klicken. Dabei öffnet sich ein Kontextmenü, in dem man unter anderem die Filter editieren kann. In diesem Filterdialog muß der Haken bei .* resources. weggenommen werden. Dann sieht man wirklich alles, was man benötigt.

Montag, 11. Mai 2009

Shared persistence

Nachdem ich im Internet viel gesucht und nicht viel gefunden habe, habe ich mich dazu entschlossen, selbst einen kleinen Artikel zu folgendem Thema zu verfassen:

"shared persistence / jboss / jpa"
"multiple ejb3 modules sharing one persistence"

Die Anforderung ist relativ einfach erzählt. Man möchte:

  • eine mehrschichtige Anwendung entwickeln

  • möglichst alle Module einzeln austauschbar gestalten

  • auf einem Application Server deployen (in unserem Fall JBoss)

  • möglichst für alle Module nur einen Persistence Kontext definieren

  • die Java Persistence API (JPA) in Verbindung mit EJB3 verwenden, um keine harten Inserts und Selects mehr selbst pflegen zu müssen


Grundinstallation

Und wie sieht das ganze nun aus? Eine vollständige und funktionierende Installation von JDK wird hier vorausgesetzt. Als Datenbank setze ich hier PostgreSQL ein. Um eine andere Datenbank nutzen zu können, muß allerdings nur die persistence.xml angepasst werden. Dazu ändert man den dort eingestellten Dialect entsprechend ab. Eine funktionierende Installation eines AppServers, hier JBoss, wird ebenfalls benötigt, wobei JBoss in dem Fall ja nur entzippt werden muß. Nach der Installation des JBoss muß im server/default/lib - Verzeichnis eine JDBC-Treiberdatei, z.B. postgresql-8.3-603.jdbc3.jar, abgelegt werden.

Als nächstes legen wir eine Testdatenbank an. Dies passiert in postgreSQL über den pgAdmin III. Der Datenbank wird nun der Produktname gegeben, beispielsweise myproduct. Um nun dem JBoss Application Server zu ermöglichen, auf diese DB zugreifen zu können, muß im server/default/deploy - Verzeichnis eine sogenannte DataSource hinzugefügt werden. Diese verweist auf den gewählten Datenbankdialekt und kann wie folgt aussehen:

myproduct-ds.xml:

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

<datasources>
<local-tx-datasource>
<jndi-name>myproductds</jndi-name>
<connection-url>
jdbc:postgresql://localhost:5432/myproduct
</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<user-name>postgres</user-name>
<password>postgres</password>

<metadata>
<type-mapping>PostgreSQL</type-mapping>
</metadata>
</local-tx-datasource>

</datasources>


Wird nun der Server gestartet und die erzeugte log-Datei geprüft, sollten keine Exceptions auftreten und man sollte in der Management Console unter http://localhost:8080/jmx-console die erzeugte Datenbankverbindung vorfinden. Alternativ kann man auch prüfen, ob in der Log-Datei ein Eintrag ähnlich diesem erfolgt:

[ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=ConnectionFactoryBinding,name=myproductdb' to JNDI name 'java:myproductdb'

Somit ist eine Datenbankverbindung verfügbar. Was man nun braucht, sind die einzelnen...

Projekte
In Eclipse ist es relativ einfach, sich folgende Projekte zu erstellen:


  • Ein Java enterprise archive Projekt (EAR), genannt myproduct

  • Ein oder mehrere EJB Projekte, als Beispiel sei genannt myproductEJB

  • Ein leeres Standard Java Project, genannt myproductPersistence



Man kann diese Projekte natürlich auch per Hand konfigurieren. Wichtig dabei sind die folgenden Punkte.

Das EAR Projekt muß eine META-INF/application.xml beinhalten. Diese solle ähnlich der folgenden aussehen...

application.xml:

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/application_5.xsd"
id="Application_ID" version="5">
<display-name>myproduct</display-name>
<module>
<ejb>myproductEJB.jar</ejb>
</module>
<module>
<ejb>myproductPersistence.jar</ejb>
</module>
</application>


Der Inhalt des EJB Projektes beschränkt sich in unserem Beispiel auf eine Entity, deren Tabelle erzeugt werden soll. In der Praxis werden aber für die einzelnen, austauschbaren Module jeweils eigene EJB Projekte erzeugt und somit eigene ejbmodule.jar Dateien deployed. Die Testbean sieht wie folgt aus...

Person Entity:

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Person implements Serializable {

private static final long serialVersionUID = -3293858472L;

@Id
private long Id;
private String name;

public long getId() {
return Id;
}

public void setId(long id) {
Id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}


Wichtig hierbei sind die verwendeten Annotations @Entity und @Id. Diese sind völlig ausreichend, um die Tabelle durch Hibernate erzeugen zu lassen. Für die Vergabe der IDs sollte man natürlich von long-Variablen absehen und stattdessen besser UUID benutzen, aber das ist ein anderes Thema.

Zu guter Letzt bleibt noch das Standard Java Projekt, welches das wichtigste für dieses Beispiel ist. Dieses Projekt ist nicht zwingend ein JPA Projekt, wie es in Eclipse angeboten wird. Es reicht, darin einen Ordner META-INF mit einer persistence.xml zu erzeugen. Der Rest des Projektes, welches später als myproductPersistence.jar deployed wird und uns den Persistenzkontext liefert, kann leer bleiben. Und hier die...



persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="myproduct"
transaction-type="JTA">
<jta-data-source>
java:/myproductdb
</jta-data-source>
<jar-file>
myproductEJB.jar
</jar-file>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.hbm2ddl.auto"
value="update"/>
</properties>
</persistence-unit>
</persistence>


Damit sind alle nötigen Schritte vollzogen, um die Tabelle erzeugen zu lassen. Für jedes Modul wird ein weiteres EJB Projekt mit eigenen Entity Beans erzeugt. Alle diese Projekte nutzen die gemeinsame Persistenz und werden durch Hibernate automatisch erkannt, solange man die einzelnen EJB Projekte als jar-file Einträge in der persistence.xml aufführt.

Wird nun die EAR Datei erzeugt und in das server/default/deploy - Verzeichnis des JBoss gelegt, sollte eine neue Tabelle namens Person in eurem Besitz sein. Dabei muss darauf geachtet werden, daß die EAR-Datei die Jar-Dateien myproductEJB.jar und myproductPersistence.jar beinhaltet.

Hinweis: Nutzt man JBoss 4.x, muß ein vorhandener Bug noch durch einen Workaround ausgebessert werden, indem man im Tag der persistence.xml als relativen Pfad angibt: ../myproductEJB.jar!

Sollten bei euch Fehler beim Testen auftreten, könnt ihr diese gerne hier loswerden in der Kommentarfunktion.

Viel Spaß beim Probieren!

Montag, 20. April 2009

Oracle kauft Sun

So wie es aussieht, ist die Entscheidung gefallen. Sun wurde wohl nun von Oracle für geschätzte 7,4 Mrd. USD aufgekauft. Das frühere Angebot von IBM wurde ausgeschlagen, weil es preislich wohl für Sun Microsystems uninteressant war. Was dies für die Zukunft von Java bedeutet und wie es weitergehen wird, darauf wird man wohl gespannt sein dürfen.

Quelle: http://www.faz.net/d/invest/meldung.aspx?id=103330309
Quelle: http://www.sun.com/third-party/global/oracle/index.jsp

Dienstag, 14. April 2009

It´s done... SCJP!

Lange genug hab ich es hinausgezogen, oft genug Freunde vertröstet. Jetzt ist es geschafft. Die Prüfung zum Sun Certified Java Programmer (310-065) in Englisch liegt erfolgreich beim ersten Versuch hinter mir. Und das auf Englisch. Würde mich ja interessieren, wer noch alles in Regensburg diese Prüfung abgelegt hat :)

Wie sich übrigens herausgestellt hat, ist genau das Buch, was ich empfohlen habe, auch die beste Vorbereitung, die man für dieses Examen bekommen kann.

Da ich die Prüfung auf Englisch gemacht habe, hat mir die Zeit gereicht. Allerdings hätte man es wohl auch in den 180 min. geschafft, die einem in Amerika zur Verfügung gestanden wären. Die zusätzliche halbe Stunde habe ich für ein nochmaliges Review der Fragen genutzt. Wie immer gilt, ich stehe per Email oder Kommentarfunktion gerne für Rückfragen zur Verfügung.

Lang lebe Sun ;)

Montag, 13. April 2009

Threads / Nebenläufigkeit

Hier mal eben ein kleines Beispiel zum Thema Nebenläufigkeit in Java. Ein kleines Beispiel, wie man in Java mit Threads arbeiten kann. Erklärung erfolgt vielleicht demnächst noch, bis dahin hoffe ich einfach, es ist selbsterklärend ;) Ihr könnt aber natürlich jederzeit per Kommentar nachfragen...


public class Test {
public static void main(String[] args) {

final String lock = "theLock";

MyThread a = new MyThread("A");
MyThread b = new MyThread("B");

a.setLock(lock);
b.setLock(lock);

Thread anonymous = new Thread() {
public void run() {
synchronized(lock) {
System.out.println("I was active...");
lock.notifyAll();
}
}
};

a.start();
b.start();
anonymous.start();

}

}

class MyThread extends Thread {

public MyThread(String name) {
super(name);
}

private String lock;

public void setLock(String lock) {
this.lock = lock;
}

public void run() {
synchronized(lock) {
try {
lock.wait();
System.out.println(getName()
+ " holds lock: " + holdsLock(lock));
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}

Dienstag, 7. April 2009

SCJP

In letzter Zeit ist es sehr ruhig hier im Blog gewesen. Das liegt daran, daß ich mich auf die Prüfung zum Sun Certified Java Programmer (SCJP) vorbereite. Wer sich ebenfalls für dieses Thema interessiert, kann mich gerne einmal anschreiben. Grundsätzlich kann ich aber für alle Interessierten, die nicht vor englischer Literatur zurückschrecken, das folgende Buch wärmstens empfehlen:

Sun Certified Programmer for Java 6 Study Guide - Exam 310-065
Verlag: Osborne-McGraw-Hill
Autoren: Kathy Sierra, Bert Bates
ISBN: 978-0071591065



Ich habe bereits 2 Bücher davor gelesen (darunter auch in Deutsch), welche zum einen nicht mehr up-to-date waren und zum anderen Beispiele und Erklärungen hatten, daß einem grauste (gespickt von Fehlern!). Das von mir erwähnte Buch ist alleine schon deshalb ein Muss für alle Prüflinge, weil es direkt von den Machern der SCJP-Prüfung stammt. Sie arbeiten bei SUN und haben die Prüfungen entworfen. Das heißt, diese Leute wissen, wovon sie reden ;) In dem Buch sind jede Menge Tipps und Warnungen, was in der Prüfung alles abgefragt werden kann. Außerdem ist eine CD-ROM mit dabei, mit deren Hilfe man insgesamt 3 Prüfungen erfolgreich durchpauken kann und sich somit umfangreich auf den echten Test vorbereiten kann. Und zu guter Letzt ist es so gründlich, leicht verständlich und gleichzeitig witzig geschrieben, daß es sogar für Programmierneulinge als Einsteigerbuch geeignet ist.

Bleibt bei der aktuellen Entwicklung nur noch zu hoffen, daß ich SCJP werde, bevor es SUN nicht mehr gibt ;)

Freitag, 30. Januar 2009

OutOfMemoryError: PermGen Space

Seit meinen Erfahrungen mit dem JBoss Application Server hab ich des öfteren eine Fehlermeldung erhalten, die vielen anderen wohl auch bekannt vorkommt. Arbeitet man länger mit dem JBoss und deployt mehrmals während der Entwicklung seine Webapplikation, kann es schon durchaus vorkommen, daß der AppServer keinen Speicher mehr hat.

Wer nun Eclipse nutzt, kann dieses Problem in der Server-Ansicht mittels Doppelklick und Ändern der Werte ändern, indem man dem unter "Open Launch Configuration" - Lasche Arguments - folgende VM Argumente ändert bzw. einträgt:

-Dprogram.name=run.bat -Djava.endorsed.dirs="C:/Programme/jboss-4.2.3.GA/bin/../lib/endorsed" -Xms128m -Xmx512m -XX:PermSize=128 -XX:MaxPermSize=256m

Welcher Speicher da jedoch genau erweitert wird und warum, das erfahrt ihr ausführlich in diesem sehr guten Artikel zum Thema:

freshblurbs.com Artikel

Zuletzt sei dabei auch noch auf die JBoss JMX Management Console verwiesen. Dort besteht die Möglichkeit, unter jboss.system - type=serverInfo mehr über den gerade laufenden JBoss AppServer auszulesen. Unter anderem das Betriebssystem sowie der verbrauchte und verfügbare Speicher.

http://localhost:8080/jmx-console

Am Anfang war die NullPointerException

Und hier ist er nun, der 1.000.000te Blog, den man im Internet finden kann. Und ihr habt euch trotzdem hierher verirrt. Dann kläre ich mal kurz auf, worum es hier gehen soll.

Wenn ich mal Revue passieren lasse, was ich in Sachen Java in den letzten Jahren für eine Entwicklung durchgemacht habe, ist es im Nachhinein echt interessant, die Veränderungen zu sehen. Ich bin also jemand, der sich mit Java beschäftigt. Und damit meine ich nicht die Insel und nicht den Kaffee, sondern die Programmiersprache, wie soll es auch anders sein. Beschäftigt hab ich mich damit wohl sauber zu viel, wenn man den Schlafmangel betrachtet, den ich schon kräftig spüre. Trotzdem bin ich noch lange kein Profi, gelernter Anwendungsentwickler hin oder her. Man lernt nie aus. Und genau darum geht es. Ich möchte für mich und für alle anderen, die es interessiert, meine Erfahrungen in Sachen Java / JavaEE festhalten. Und da ich allgemein die Dienste von Google sehr gerne nutze und im Google Profil auch dieser Blog integrierbar war, landetet ich also hier.

Und warum der Abwasch? Naja wer weiß, vielleicht rutscht mir ja doch das eine oder andere mal auch was privates Raus. Was hält einen Entwickler schon am ehesten von seinem geliebten Eclipse ab? Genau....der Haushalt. Also sollte es vorkommen, daß sich Freunde / Bekannte hierher verirren, tuts mir leid. Ich wollte euch nicht eure sinnvolle Zeit klauen und hiermit verschwenden ^^.

Genug getextet, ich werd besser die Label Funktion fleißig nutzen, um interessierte Leser von Nicht-Java-Posts zu verschonen.

Achja, Java ist groß. Worum gehts überhaupt? Also derzeit eher um Java Server Faces (kurz JSF), Facelets, JBoss Application Server, Enterprise Java Beans in Version 3 (EJB3) und vieles mehr. Ich hoffe mal stark, ich werde nicht irgendwann wieder bei Swing oder noch schlimmerem landen ^^

Viel Spaß beim Lesen und ich freue mich immer über Feedback.

Fred