Watching a new world…

April 7th, 2007

Debugging SSH

Beim öffnen einer SSH-Verbindung zu einem Remoteserver, beispielsweise über scp, gibt es häufig mal Probleme, wel mal wieder irgendwas nicht stimmt. In den Logfiles ist über die Ursache in aller Regeln nicht viel zu finden. Hier ein Trick, um das ganze zu debuggen:

Ã?ber das Kommano

/usr/sbin/sshd -D -p8022 -dwird ein zweiter SSH-Deamon im Debugmodus gestartet (natürlich auf einem anderen Port, hier 8022).

Wird nun ein SSH-Connect auf den Server (natürlich über diesen alternativ-Port) durchgeführt, so teil dieser einem alle seine Sorgen direkt über die Console mit. Beispiel:

getnameinfo failed
Server listening on :: port 8022.
debug1: Bind to port 8022 on 0.0.0.0.
Bind to port 8022 on 0.0.0.0 failed: Address already in use.
Generating 768 bit RSA key.
RSA key generation complete.
debug1: Server will not fork when running in debugging mode.
debug1: rexec start in 4 out 4 newsock 4 pipe -1 sock 7
debug1: inetd sockets after dupping: 3, 3
Connection from 111.222.111.222 port 4810
debug1: Client protocol version 2.0; client software version JSCH-0.1.32
debug1: no match: JSCH-0.1.32
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-1.99-OpenSSH_4.1
debug1: permanently_set_uid: 71/65
debug1: list_hostkey_types: ssh-rsa,ssh-dss
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: client->server 3des-cbc hmac-md5 none
debug1: kex: server->client 3des-cbc hmac-md5 none
debug1: expecting SSH2_MSG_KEXDH_INIT
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: KEX done
debug1: userauth-request for user jboss service ssh-connection method none
debug1: attempt 0 failures 0
debug1: PAM: initializing for "jboss"
Failed none for jboss from 111.222.111.222 port 4810 ssh2
debug1: PAM: setting PAM_RHOST to "p57a0dc1b.dip.t-dialin.net"
debug1: PAM: setting PAM_TTY to "ssh"
debug1: userauth-request for user jboss service ssh-connection method publickey
debug1: attempt 1 failures 1
debug1: temporarily_use_uid: 1002/1000 (e=0/0)
debug1: trying public key file /data/jboss/.ssh/authorized_keys
Authentication refused: bad ownership or modes for file
/data/jboss/.ssh/authorized_keys

debug1: restore_uid: 0/0
debug1: temporarily_use_uid: 1002/1000 (e=0/0)
debug1: trying public key file /data/jboss/.ssh/authorized_keys2
debug1: restore_uid: 0/0
Failed publickey for jboss from 111.222.111.222 port 4810 ssh2
Received disconnect from 111.222.111.222: 3: com.jcraft.jsch.JSchException: Auth fail
debug1: do_cleanup
debug1: PAM: cleanup
debug1: do_cleanup
debug1: PAM: cleanup
Nach dem ersten Connection-Versuch wird der Prozess automatisch wieder beendet.

Hieraus ist z.B. zu lesen, dass die Berechtigungen für authorized_keys nicht korrekt sind. Na da wär ich doch sonst niemals drauf gerkommen…

April 5th, 2007

SCP über ANT mit public rsa key

Normalerweise ist bei einigermaÃ?en sicheren SSH-Servern die Passwortauthentifizierung deaktiviert.

Nun möchte man aber dennoch gerne Automatisches Deployment auf diese Server mittels SCP-Task über ANT realisieren.

Dies ist möglich über RSA-Keys. Da ich immer wieder vergesse, was man da nun genau machen muss, hier nun ein Kochrezept:

  1. Per SSH mit dem User, der auch der Deploy-User wird, auf das Zielsystem einloggen
  2. Im Home-Verzeichnis das Verzeichnis .ssh anlegen
    > md .ssh
  3. Den SSH-Keygenerator starten
    > ssh-keygen -t rsa -f ./.ssh/id_rsa
    Generating public/private rsa key pair.
    Enter passphrase (empty for no passphrase):
  4. Ein Passwort (Passphrase) eingeben:
    Enter same passphrase again:
  5. Nochmal:
    Your identification has been saved in ./.ssh/id_rsa.
    Your public key has been saved in ./.ssh/id_rsa.pub.
    The key fingerprint is:
    0a:c2:a5:bc:90:fb:5d:37:2c:95:21:54:6f:0b:86:38 jboss@blablabla
    Nun sind zwei Dateien entstanden:

    ls -la .ssh/
    -rw------- 1 jboss jboss 1743 2007-03-08 11:51 id_rsa
    -rw-r--r-- 1 jboss jboss 398 2007-03-08 11:51 id_rsa.pub

  6. Dem Verzeichnis .ssh die Rechte für others nehmen:
    > chmod 750 .ssh
  7. Die Datei id_rsa wird auf den lokalen Rechner kopiert
  8. Die Datei id_rsa.pub wird umbenannt zu authorized_keys
    > cd .ssh
    > mv id_rsa.pub authorized_keys
  9. So, nun kann der SCP-Task entsprechend gestartet werden:
    <scp
    port="${scp.port}"
    trust="yes"
    remoteTodir="${scp.user}:${scp.pass}@${scp.host}:${scp.dir}"
    verbose="yes"
    passphrase="${scp.pass}"
    keyfile="${scp.keyfile}">
    <fileset dir="jboss" includes="**/*" />
    </scp>
    …wobei ${scp.keyfile} der Pfad zu der lokalen Datei id_rsa und ${scp.pass} die eingegebene Passphrase ist.

Alles gut!

March 14th, 2007

Data too long for column [bit] in MySQL

Immer wieder stoÃ?e ich unter Jboss/MySQL auf den selben Fehler:

Data truncation: Data too long for column 'MODIFIABLE' at row 1

Wobei das Feld MODIFIABLE vom Typ bit ist und hier der Wert ‘1‘ eingefügt werden soll.

Die Lösung ist simpel: Es handelt sich um einen Bug im MySQL JDBC-Treiber Version 5.0.3. Also: Upgrade auf z.B. 5.0.4 und gut is.

March 10th, 2007

Alfresco 2.0 auf JBoss AS 4.0.5 unter Portal 2.4.1

Hier mal ein erster Eindruk: Auf den ersten Blick hat sich nicht viel verändert. Interessanterweise ist das XForms-Framework Chiba in der neue Version integriert. Nicht schlecht… Der Navigation (Baumansicht der Verezeichnisstruktur) klappt jetzt AJAX-mäÃ?ig auf und zu (vermutlich Chiba?)

So, jetzt kommt die Herausforderung: Integration von Alfresco 2.0 in JBoss AS 4.0.5 unter Portal 2.4.1 und MySQL. Zunächst also mal in den Alfresco-Foren gestöbert. Die schlechte Nachricht: Es geht nicht. Die gute Nachricht: Es geht doch, wenn man sich etwas Mühe gibt. Die Kernaussage dieses Wiki-Eintrages ist, dass im aktuellen Release einige Issues existieren, die den Betrieb von Alfresco 2.0 unter JBoss Portal 2.4.1 unmöglich machen. Diese Issues sin in aktuellen Revisionen des SVN-Repositories jedoch bereits gefixt, so dass ein manuelles Build eines SVN-Snapshots nötig ist. Es gibt glücklicherweise eine Wiki-Eintrag, der beschreibt, wie das zu bewerkstelligen ist. Na dann wollen wir mal sehen, ich werd das jetzt mal ganz brav step-bystep befolgen…

  1. SVN-Client Installieren (Subclipse beispielsweise)
  2. Das Alfresco-Repository unter svn://svn.alfresco.com/alfresco/HEAD konnektieren und Revision 574 holen (dauert erwartungsgemäÃ? ewig…)
  3. Die Umgebungsvariable JBOSS_HOME auf die JBoss AS Installation setzen
  4. Ant herunterladen und als Standalone installieren. Das ANT-bin-Verzeichnis in die Umgebungsvariable PATH aufnehmen. Umgebungsvariable ANT_HOME setzen.
  5. JAVA_HOME aufs JDK setzen
  6. In dem Verzeichnis root/common des Alfresco-Projektes das Tartget build-jboss ausführen: ant build-jboss. Es entstehen folgende Dateien, die vom build-Script freundlicherweise gleich deployed werden:
    • ${jboss.home}/bin/.hotspot_compiler (was auch immer der macht…)
    • ${jboss.home}/server/default/lib/mysql-connector-java-5.0.3-bin.jar (andere MySQL-Treiber werden entfernt)
    • ${jboss.home}/server/default/deploy/alfresco.war
  7. In der Datei ${jboss.home}/bin/run.bat (bzw. run.sh) folgenden Code zu den JAVA_OPTS hinzufügen:
    -server -XX:MaxPermSize=128m cvx (Siehe auch: Das PermgenSpace-Problem)
  8. Leere Datenbank “alfresco” in MySQL anlegen:
    create database alfresco;
    grant all privileges on alfresco.* to 'alfresco'@'localhost'
    identified by 'alfresco' with grant option;
    grant all privileges on alfresco.* to 'alfresco'@'localhost.localdomain'
    identified by 'alfresco' with grant option;
  9. Und go!

So, jetzt kommt also der Moment, in dem die Kuh den Schwanz hebt… uuund … läuft! Fast.

Ein Problem gibt es jetzt noch: Nach dem erfolgreichen Einklinken des AlfrescoClientWindow-Portlets bzw. beim Anzeigen desselben erscheint die Fehlermeldung:

Unable to find setter method for attribute acceptCharset in /jsp/browse/browse.jsp.

Ein Blick in diese Dateio zeigt:

<h:form acceptCharset="UTF-8" id="browse">

Der h-Namespace kommt von MyFaces. Achja, da war ja noch was, die MyFaces-Bibliotheken sollten ohnehin ersetzt werden. Also:

${jboss.home}/server/default/deploy/jbossweb-tomcat55.sar/jsf-libs/myfaces-* löschen und durch aktuelle (1.1.5+) ersetzen. Und? Nee!

Nun kommt im AlfrecoClientWindow:

javax.faces.FacesException: org.apache.jasper.JasperException:
The absolute uri: http://java.sun.com/jsf/html
cannot be resolved in either web.xml or the jar files
deployed with this application

Na toll, was soll das jetzt? Nach einiger Recherche habe ich nun die myfaces-libs in der Version 1.1.1 nach ${jboss.home}/server/default/deploy/jbossweb-tomcat55.sar/jsf-libs kopiert. Nun ist alles super!

13:29:40,531 INFO [org.jboss.system.server.Server] JBoss (MX MicroKernel)
[4.0.5.GA (build: CVSTag=Branch_4_0 date=200610162339)]
Started in 4m:11s:235ms (hmpf...)

March 10th, 2007

Alfresco 2.0 mit WCMS

Seit einigen Tagen ist Das Enterprise DMS (Document Management System) Alfresco in der Version 2.0 drauÃ?en.

Da wir gerade dabei sind, Alfresco (ursprünglich in der Version 1.4) bei einem unserer Kunden einzuführen, stellt sich nun
natürlich die spannende Frage, was uns dieses Major Release nun konkret bringt.

Zunächst wäre da mal die lange erwartete WCMS-Komponente, also ein JSR-170 konformes System für Webcontent.

Hier zunächst mal ein Ausschnitt aus dem Original Post:

[...] This release introduces a number of new features, including:

  • GPL with FLOSS exception
  • Web Content Managment 1.0 with:
    • Web Project Wizard
    • Forms Management Wizard
    • Website Development and Staging
    • XML Content Authoring
    • FreeMarker, XSL and XSL-FO transformations
    • Virtualization and In-Context Preview
    • Workflow for change sets
  • Federated Search
  • OpenSearch support
  • Add-on Module Management
  • Tree Navigation (AJAX)
  • Multilingual Services

[...]

Nun gut, sagt mir erstmal noch so viel, muss ich gestehen. Werde mich mal dranmachen, das ganze zu evaluieren…

March 7th, 2007

JBoss AS mit JNDI auf Port 1199

Das Problem war eigentlich ganz einfach: Bei der Installation des JBoss AS 4.0.5 inklusive JBoss ESB (Enterprise Service Bus), Portal und einigen Seam-Applikationen auf einem Kundenserver stellte sich heraus, dass der Port 1099, der standardmäÃ?ig vom Java Naming Service JNDI verwendet wird, bereits belegt ist. Die Umkonfiguration auf einen anderen Port (ich entschied mich für 1199) stellte sich jedoch als ein steiniger Weg dar…

Folgende Schritte waren letztendlich nötig:

1. Server Konfiguration

In der Datei ${jboss.home}/server/default/conf/service.xml muss folgender Block eingefügt (bzw. einkommentiert und angepasst) werden:

<mbean code="org.jboss.services.binding.ServiceBindingManager"
name="jboss.system:service=ServiceBindingManager">
<attribute name="ServerName">ports-01</attribute>
<attribute name="StoreURL">
${jboss.home.url}/server/default/conf/service-bindings.xml
</attribute>
<attribute name="StoreFactoryClassName">
org.jboss.services.binding.XMLServicesStoreFactory
</attribute>
</mbean>
Damit wird über service-bindings.xml ein alternatives Binding, also eine alternative Portkonfiguration definiert. Diese Date findet man als Vorlage unter ${jboss.home}/docs/examples/binding-manager/sample-bindings.xml

Inder Datei service-bindings.xml werden zwei Serverkonfigurationen definiert: ports-default, die bleibt so wie sie ist, und server-01, das ist unsere modifizierte Konfiguration.

Hier die wichtigen Stellen aus dieser Datei:

<service-bindings>
<!-- Standardkonfiguration -->
<server name="ports-default">
<service-config name="jboss:service=Naming"
delegateClass="org.jboss.services.binding.AttributeMappingDelegate">
<delegate-config portName="Port" hostName="BindAddress">
<attribute name="RmiPort">1098</attribute>
</delegate-config>
<binding port="1099" host="${jboss.bind.address}" />
</service-config>
<service-config name="jboss:service=WebService"
delegateClass="org.jboss.services.binding.AttributeMappingDelegate">
<delegate-config portName="Port" />
<binding port="8083" />
</service-config>
<!-- usw. für alle definierten Portnummern -->
</server>
<!-- Hier wirds spannend... -->
<server name="ports-01">
<!-- Umkonfiguration des Naming-Dienstes -->
<service-config name="jboss:service=Naming"
delegateClass="org.jboss.services.binding.AttributeMappingDelegate">
<delegate-config portName="Port" hostName="BindAddress">
<attribute name="RmiPort">1198</attribute>
</delegate-config>
<binding port="1199" host="${jboss.bind.address}" />
</service-config>
<!-- Der Rest bleibt wie er ist... -->
</server>
</service-bindings>

2. Patch für JBoss ESB 4.0

Beim Hochfahren der jUDDI-Registry ver sucht der ESB, diese bei localhost:1099 anzumelden, was ja normalerweise auch richtig ist. Nutzt man den ESB mit jUDDI, so muss im Verzeichnis ${jboss.home}/server/default/conf die Datei juddi.properties vorhanden sein. In dieser lässt sich so einiges bzgl. der Registry für den Service-Bus konfigurieren, unter Anderem folgendes:

# JNDI settings (used by RMITransport
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1199
java.naming.factory.url.pkgs=org.jboss.naming
Super, genau, was man braucht! Denkste. Die olle Registry meldet sich immer noch auf localhost:1099 an. Der Grung dafür ist ein Bug im JBoss ESB, genauer am jUDDI-Proxy. Folgende Klasse existiert im ESB:

# JNDI settings (used by RMITransport)
package org.jboss.internal.soa.esb.dependencies;
import java.io.File;
import java.net.URI;
import java.util.Properties;
import java.io.IOException;
import java.io.InputStream;
import javax.naming.InitialContext;
public class JuddiRMIService extends ServiceMBeanSupport
implements JuddiRMIServiceMBean {
private Logger logger = Logger.getLogger(this.getClass());
protected void startService() throws Exception {
logger.info("starting juddi RMI service");
final String confURL = System.getProperty("jboss.server.config.url") ;
final URI confDirURI = new URI(confURL) ;
final File confDir = new File(confDirURI) ;
System.setProperty("juddi.propertiesFile", confDir + "/juddi.properties");
JNDIRegistration.register();
}
protected void stopService() throws Exception {
logger.info("Unbinding juddi services");
final InitialContext ic = new InitialContext() ;
ic.unbind(JNDIRegistration.INQUIRY_SERVICE) ;
ic.unbind(JNDIRegistration.PUBLISH_SERVICE) ;
}
}
Der Fehler tritt bei JNDIRegistration.register() auf. Das Problem ist, dass die jUDDI-Konfiguratiuon beim Aufruf dieser Static-Methode noch gar nicht eingelesen ist, also wird fröhlich weiter beim Standard JNDI-Port localhost:1099 angemeldet. Hier der Patch:

package org.jboss.internal.soa.esb.dependencies;
import java.io.File;
import java.net.URI;
import java.util.Properties;
import java.io.IOException;
import java.io.InputStream;
import javax.naming.InitialContext;
import org.apache.juddi.registry.RegistryEngine;
import org.apache.juddi.registry.rmi.JNDIRegistration;
import org.apache.log4j.Logger;
import org.jboss.system.ServiceMBeanSupport;
import org.apache.juddi.util.Config;
import org.apache.juddi.util.Loader;
public class JuddiRMIService extends ServiceMBeanSupport
implements JuddiRMIServiceMBean {
private Logger logger = Logger.getLogger(this.getClass());
private static final String PROPFILE_NAME = "juddi.properties";
protected void startService() throws Exception {
logger.info("starting juddi RMI service");
final String confURL = System.getProperty("jboss.server.config.url") ;
final URI confDirURI = new URI(confURL) ;
final File confDir = new File(confDirURI) ;
System.setProperty("juddi.propertiesFile", confDir + "/juddi.properties");
logger.info("** Patch om@form4: start preloading properties");
try {
InputStream stream = Loader.getResourceAsStream(PROPFILE_NAME);
if (stream != null) {
Properties props = new Properties();
props.load(stream);
Config.addProperties(props);
logger.info("** Patch
om@form4: preloading properties successful");
}
} catch (IOException ioex) {
logger.error("An error occured while loading properties
from: "+PROPFILE_NAME,ioex);
}

JNDIRegistration.register();
}
protected void stopService() throws Exception {
logger.info("Unbinding juddi services");
final InitialContext ic = new InitialContext() ;
ic.unbind(JNDIRegistration.INQUIRY_SERVICE) ;
ic.unbind(JNDIRegistration.PUBLISH_SERVICE) ;
}
}
Jetzt muss noch das Build der JBoss ESB-Quellen angeschmissen werden und es entsteht u. A. die Datei jbossesb-dependencies.jar, die in der Original-Distribution ersetzt werden muss.

Nun geht auch das.

3. Umkonfiguration des ESB

Was auch stundenlanges Debuggen erfordert hat, ist eigentlich ganz einfach: In der Datei ${jboss.home}/server/default/conf/jbossesb.xml wird die jndi-url lapidar mit “localhost” angegeben. Das muss konkretisiert werden. Aus:

<jms-provider name="JBossMQ"
connection-factory="ConnectionFactory"
jndi-context-factory="org.jnp.interfaces.NamingContextFactory"
jndi-URL="localhost">
wird:

<jms-provider name="JBossMQ"
connection-factory="ConnectionFactory"
jndi-context-factory="org.jnp.interfaces.NamingContextFactory"
jndi-URL="localhost:1199">
Ã?hnliches nochmal in ${jboss.home}/server/default/conf/jbossesb-properties.xml . Aus:

<property name="org.jboss.soa.esb.jndi.server.url" value="localhost"/>wird:

<property name="org.jboss.soa.esb.jndi.server.url" value="localhost:1199"/>

4. jndi.properties umkonfigurieren

Zu guter letzt noch in der Datei ${jboss.home}/server/default/conf/jndi.properties folgende Zeile ergänzen:

java.naming.provider.url=jnp://localhost:1199Jetzt ist alles gut!

March 5th, 2007

Das permgen space-Problem unter JBoss

Unter JBoss AS 4.x hat man leider mit dem Problem zu kämpfen, dass nach mehreren Deployments der PermGen-Space der JVM voll ist:
java.lang.OutOfMemoryError: PermGen space
Dies ist leicht durch ein kleines Patch zu beheben. In der Datei ${jboss.root}/bin/run.bat bzw. ${jboss.root}/bin/run.bat zu den JAVA_OPTS folgende Optionen hinzufügen:
-XX:+CMSPermGenSweepingEnabled -XX:MaxPermSize=128m
So wird aus dieser Zeile:
set JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx512m
-Dsun.rmi.dgc.client.gcInterval=3600000
-Dsun.rmi.dgc.server.gcInterval=3600000

folgende:
set JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx512m
-XX:+CMSPermGenSweepingEnabled -XX:MaxPermSize=128m
-Dsun.rmi.dgc.client.gcInterval=3600000
-Dsun.rmi.dgc.server.gcInterval=3600000

Der PermGenSpace liegt standardmä�ig bei 64m, was für den feisten JBoss AS offensichtlich etwas knapp bemessen ist. Hierüber wird dieser Wert auf 128m erhöht.
Trotzdem geht der JBoss mit dem PermGenSpace offensichtlich etwas schluderig um, denn auch bei 128m ist dieser nach einem Tag Intensiver Entwicklung voll, und der Server muss neu gestartet werden. Deutet auf ein Speicherleck hin…

February 27th, 2007

Marshalling mit smooks – Erweiterung der javabeans-Cartridge

Für mein aktuellen JBoss-ESB-Projekt habe ich mir in den Kopf gesetzt eine eingehende XML-Datei in Entity-Beans zu transformieren. JBoss-ESB bietet das von Hause aus über die Integration des Smooks-Frameworks.

Kurz zur Erklärung: Smooks ist ein Framework zur generischen Verarbeitung von XML-Dateien, bzw. XML-Fragmenten. Die Verarbeitung ist einfach: In einer Mapping-datei wird für jeden XML-Pfad ein Handler definiert, der über das Visitor-Pattern irgendetwas ausführt. So kann für ein Element (oder einen Teilbaum) z.B. ein XSLT ausgeführt werden oder auch völlig individueller Java-Codeausgeführt werden.

Hier ein Beispiel aus der Mapping-Datei (smooks-res.xml):

<smooks-resource selector="ORDER"
useragent="from-type:text/xml:fullfillorder and
from:dvdstore:orderdispatchservice"
path="org.milyn.javabean.ProcessingPhaseBeanPopulator" >
<param name="beanId">ORDER</param>
<param name="beanClass">org.jboss.soa.esb.dvdstore.Order</param>
<param name="addToList">true</param>
</smooks-resource>
<smooks-resource selector="ORDER"
useragent="from-type:text/xml:fullfillorder and
from:dvdstore:orderdispatchservice"
path="org.milyn.javabean.ProcessingPhaseBeanPopulator" >
<param name="beanId">order</param>
<param name="attributeName">orderId</param>
</smooks-resource>
<!-- ... repeat for each attribute ... -->

In diesem Beispiel wird für jedes Element “ORDER” der ProcessingPhaseBeanPopulator “besucht”. Der ProcessingPhaseBeanPopulator wird vom smooks-Framework über eine sog. Cartridge mitgeliefert. Er hat die Aufgabe, aus dem element “ORDER” ein POJO, also eine Java-Klasse zu generieren. Attribute können zu Java-Properties gemappt werden und für Unterelemente können ebenfalls Visitors definiert werden, die beispielsweise wiederum Properties setzen. Sowie sogut. Das Problem ist bloss, dass bei “echten” Business-Daten die Datenstrukturen nicht so trivial sind, wie in dem vom ESB mitgelieferten Sample “quickstarts/transformXML2POJO“. Habe ich ein ORDER-Element mit 30 oder mehr Unterelementen, die die Properties der ORDER definieren, wird mein smooks-mappingfile recht umfangreich und vor allem sehr wartungsfeindlich.

Schön wäre eine Smooks-Cartridge, die die Unterlemente eines XML-Elements automatisch auf die Properties (genaugesagt auf die Setter) meines POJO Mappt. So kann mit minimaler Konfiguration eine ganze Reihe von umfangreichen XML-Strukturen auf POJOs transformiert werden, ohne tonnenweise quasi-redundanten Konfigurationscode zu erzeugen.

Hierzu habe ich die von smooks mitgelieferte javabeans-cartridge etwas modifiziert, so dass folgende Konfiguration möglich ist:

<smooks-resource selector="ORDER"
useragent="from-type:text/xml:fullfillorder and
from:dvdstore:orderdispatchservice"
path="org.milyn.javabean.MyProcessingPhaseBeanPopulator" >
<param name="beanId">order</param>
<param name="beanClass">org.jboss.soa.esb.dvdstore.Order</param>
<param name="attributesFromChildren">true</param>
</smooks-resource>

Damit das funktioniert, habe ich in der Klasse ProcessingPhaseBeanPopulator etwas Code ergänzt.

Zunächst das Einlesen der Konfiguration, die nun den Parameter “attributesFromChildren” unterstützen soll:

public void setConfiguration(SmooksResourceConfiguration config) {
// ... existing code
// START Added by om, form4
attributesFromChildren =
config.getBoolParameter("attributesFromChildren", false);
// END Added by om, form4
}

Und das Processing im eigentlichen Visitor:

public void visit(Element element, ContainerRequest request) {
Object bean = getBean(request);
// START Added by om, form4
if (attributesFromChildren) {
NodeList children = element.getElementsByTagName("*");
for (int i = 0; i < bean.getClass().getMethods().length; i++) {
Method method = bean.getClass().getMethods()[i];
if (method.getName().startsWith("set")) {
String attr = method.getName().replaceAll("^set", "").toLowerCase();
for (int j = 0; j < children.getLength(); j++) {
Element child = (Element) children.item(j);
if (attr.equalsIgnoreCase(child.getNodeName())) {
try {
String val = DomUtils.getAllText(child, false);
method.invoke(bean, new Object[] { val });
} catch (Exception e) {
logger.error(e); // etwas ignorant...
}
break;
}
}
}
}
}
// END Added by om, form4
// ... go on with original code ...
}

February 25th, 2007

Integation von Seam in JBoss ESB?

Derzeit wird bei JBoss über eine mögliche Integration von Seam in den JBoss Enterprise Service Bus (ESB) nachgedacht. Die Idee ist, eine Seam-Komponente zu entwickeln, die sich als ein Service im Sinne des ESB verhält. So könnte die Seam Integration aus Sicht des ESB z.B. folgerderma�en aussehen (möglicher Ausschnitt aus der jbossesb.xml):

<action class="org.jboss.soa.esb.actions.SeamProxy" name="MySeamComponent"/>

Der Name MySeamComponent würde innerhalb einer solchen Out-of-the-Box-Action automatisch auf das @Name der Seam-Komponente gemappt werden (die Action löst das intern über einen JNDI-Lookup).

Weiterhin im Gespräch ist ein Action-Interface MarshalledActionProcessor mit einer einzigen Methode mit folgender Signatur:

public Object process(Object[] objects) throws ActionProcessingException;

So kann innerhalb von Seam, wie in Seam üblich, mit einem ganz normalen Objekt gearbeitert werden, während sich das ESB-Developer-Team von JBoss überlegt wie sie eine ESB-Message in ein Objekt transformiert (marshalled).

Dies sind jedoch lediglich erste Gedanken der ESB-Entwickler. Die Diskussion hierüber kann derzeit im JBoss ESB Developer Forum nachvollzogen werden.

February 24th, 2007

Mini Cooper in SL

Ich habe einen gelben Mini Cooper S in SL gefunden! Hier zwei Snapshots (ich war mal so frei probezusitzen ;) ):

mini1mini2

klipal online pharmacy buy online cialis viagra online xanax cream for women order zyban online oxazepam buy alternative erection lorazepam cheap drugs 2003 tramadol tramadol market sales tramadol rx pills diazepam discount retail alternative to valium at gnc online drugstore tenuate order order levitra discount cialis buy the cheapest propecia online cheapest generic viagra online drugstore order cialis soft tabs over internet need no doctor cheapest levitra prices woman viagra soft tabs natural substitutes for viagra soft tabs online viagra natural levitra substitutes female cialis alternative