Planet ObjectWeb

January 29, 2008

Orbeon

Default face

Keeping your session alive

Rotor

A couple of weeks ago I attempted to order prints from Flickr. I added a few photos to my cart and was redirected to a service called QOOP. This has a neat interface that allows you organize photos for printing in a book format. I played a bit with the interface and then was caught by other tasks. When I came back to my browser window and attempted to preview the photo album, I got a wonderful error message about a session having expired. The result: my album was lost. I gave up.

My adventure with expired sessions is quite common and I can bet you have had this kind of issues in the past. The least that can be said about this is that it is not user-friendly!

To address this kind of issues, we recently introduced a new feature in Orbeon Forms called the “session heartbeat”. The idea is that if you happen to leave a browser window open on your computer, chances are that you will get back to that window and keep using the application. The last thing you want to happen when you come back is lose your session and therefore your data, as happened to me.

This is not always a correct guess of course: you may just happen to leave a window or tab open without planning to use it again. Conversely you may have a page which is not actually visible, for example in your browser history, yet you will come back to it. This approach wouldn’t be good for banking applications either. Still, in many situations, such as filling-out large forms, it sounds like a good idea to keep your session alive for open pages.

To achieve this goal you could make all server sessions longer. However this is harder to configure for the application developer, and this won’t discriminate between pages that are actually open on a client and the ones that are not. And while it may be ideal to have infinitely long sessions, unfortunately many applications are not ready for this kind of approach.

So we turned to the idea of implementing a “session heartbeat”. Here is how this works:

Note that whenever an application keeps sessions alive for a long time, it is a good idea to keep as little data as possible in the session. The Orbeon Forms XForms engine itself uses a global state store and does not use session objects for storage, but do remember to keep your sessions small!

Hopefully, this will help prevent many occurrences of the infamous “session expired” error message. The beauty of it is that as an Orbeon Forms application developer you don’t have to worry about anything: the session heartbeat is enabled by default (but it can be turned off globally in properties.xml or individually for each page).

January 29, 2008 03:36 PM

January 27, 2008

Christophe Hamerling

Default face

Too many open files IOException with large number of Axis2 Servic

This is a problem we met in the PEtALS SOAP Binding Component with large number of Axis2 Service Clients.
In this case, this error happens when too many sockets are open ant are waiting to be closed. Even if I have found some JIRAs about this problem and possible solutions, the only one which work for us is to cleanup the connection after each service call.
It is done like this :

...

ServiceClient client = new ServiceClient(null, service);

Options options = new Options();

...

options.setCallTransportCleanup(true);

client.setOptions(options);


OMElement outBodyElement = null;

try {

outBodyElement = serviceClient.sendReceive(soapAction, inBodyElement);

} catch (AxisFault e) {

throw e;

}



After 10 minutes test with 200 threads creating 'one shot ' ServiceClient and almost 275000 service calls, all worked fine.

January 27, 2008 11:50 PM

Going to JavaPolis 07

See you next week JavaPolis '07 on the OW2 Consortium booth to talk about and make some 'demos' of the PEtALS Enterprise Service Bus project.



January 27, 2008 11:50 PM

PEtALS Standalone 1.4.3

PEtALS Standalone platform 1.4.3 is out. This is a maintenance release.
Look at the release notes for more details.

January 27, 2008 11:50 PM

CIMERO2 Editor for PEtALS ESB

The CIMERO2 editor is an Eclipse plugin originally developed by Bull. This plugin provides features to create a visual representation of your Enterprise Service Bus based architecture. After the design step, the plugin offers the possibility to generate the JBI artifacts (Service Assemblies), and the Ant deployment scripts which will be used to deploy the configuration on the ESB.

We, at eBM WebSourcing, are currently working on better integration of the PEtALS JBI components. You can find a Flash demonstration on how we you can use this plugin on the PEtALS project website demonstration page.

Finally, it is good to notice that this plugin is currently under integration into the Eclipse SOA Tools Platform project (Eclipse STP).



January 27, 2008 11:50 PM

Installing SVN Client on Mac OSX

I am happy to see that Fink (http://finkproject.org/) is no more needed to easily install a Subversion client on Mac OSX. A client has been packaged by this guy Martin Ott (http://homepage.mac.com/martinott/).
Installation done by clicking on the package...

I am also happy to see that there is a Subversion GUI client for OSX. Working with terminal is cool but sometimes clicking on the mouse is not so bad...
You can found this client on 'La chose interactive' website (http://www.lachoseinteractive.net/fr/communaute/subversion/).

Configuration seems very intuitive... Going to test it for PEtALS project...

January 27, 2008 11:50 PM

PEtALS PACK 2.0

Friday (evening) September 28th 2007



PEtALS ESB 2.0 is finally out!
It is released at the same time as a 'pack' including all new/compatible modules which have been developed since months.
These modules are :
Complete release note will be available on the PEtALS Website.


January 27, 2008 11:50 PM

PEtALS last week releases

We have done some releases last week :

1. petals-standalone 1.4 :
    - Integration of a faster message transporter (Dream based)
    - Load balancing
    - Robustness
    - and of course several bug fixes and code optimization

2. petals-component-framework 2.0 :
    - This framework replaces the Component Development Kit (also known as CDK). It allows developers to quickly create powerful JBI components.

3. petals-bc-soap 2.0 :
    - Based on the petals-component-framework.
    - WS security
    - WS notification

Zip archives and documentation are available for download on the PEtALS downloads page.


January 27, 2008 11:50 PM

Road to PEtALS 2.0

PEtALS 2.0 is on the way. The beta version will be out in few weeks with cool features :




January 27, 2008 11:50 PM

PEtALS Azalee Pack

The PEtALS Azalée Pack is finally out. It includes all the latest stable versions of project artefacts.
You can download it here and get release note here.

Technorati Tags     ,,,,,,

January 27, 2008 11:50 PM

PEtALS community news - May

PEtALS news #1, 2007 May 16th


The PEtALS community is growing. Thanks to everyone for the interest you give to the project. Here is the first newsletter dedicated to this great project...


Releases and more

More information on the future release note...

Main developments


Documentation


Others


Please do not hesitate to send your comments, ideas, and more...







Technorati Tags     ,

January 27, 2008 11:50 PM

Creating fully compatible JBI components

As JBI container developers (PEtALS), we have created a framework which allows developers to easily create JBI components.

This Component Development Kit (also called PEtALS CDK) is based on the JBI specification and allows to create components which are 100% compatible with the JBI specification. In other words, you can use the CDK to create components that can be installed on all JBI implementations.

Note that most of the PEtALS components (Service Engines and Binding Components) are based on this CDK.
An online documentation is available on the projet wiki here and you can download the CDK here.

Technorati Tags     ,

January 27, 2008 11:50 PM

Implementing the DynamicMBean interface

Implementing DynamicMBean interface

Introduction

Using JMX (Java Management eXtensions) to manage part of your application is a great java feature. The standard Mbeans mechanisms which consist of creating a class which implements an MBean interface is quite simple and already allows to manage most of your application.
In this article, I will describe how can we implements the DynamicMBean interface to do more 'complex' things. Especially, we will look on how we can we expose and modify a set of properties, and how can we expose methods by specifiing their names (The java code will be more clear than my poor english).

The following examples are taken from the work I have done on the PEtALS CDK (Component Development Kit) in order to expose a set of JBI extensions and bootstrap methods for management.

How to expose a set of properties?

The standards MBeans automatically expose the setters and getters methods as MBean attributes. Imagine that you have a set of properties (a HashMap/Properties...). How can you manage this object, how can you change a value in the set? Simply by creating an implementation of the DynamicMBean interface.

The following code snippet shows how we can do such a thing.


    /*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#getAttribute(java.lang.String)
*/

public synchronized Object getAttribute(String attribute)
throws AttributeNotFoundException, MBeanException, ReflectionException {

String value = managedBootstrap.getComponentPropertiesManager()
.getProperties().getProperty(attribute);
if (value != null
&& !value
.startsWith(ComponentPropertiesManager.MANAGED_METHOD_PREFIX)) {
return value;
} else {
throw new AttributeNotFoundException("Attribute '" + attribute
+ "' does not exists");
}
}

/*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#getAttributes(java.lang.String[])
*/

public synchronized AttributeList getAttributes(String[] attributes) {
AttributeList list = new AttributeList();
for (String name : attributes) {
String value = managedBootstrap.getComponentPropertiesManager()
.getProperties().getProperty(name);
if (value != null
&& !value
.startsWith(ComponentPropertiesManager.MANAGED_METHOD_PREFIX))
list.add(new Attribute(name, value));
}
return list;
}

/*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#setAttribute(javax.management.Attribute)
*/

public synchronized void setAttribute(Attribute attribute)
throws AttributeNotFoundException, InvalidAttributeValueException,
MBeanException, ReflectionException {
String name = attribute.getName();
if (managedBootstrap.getComponentPropertiesManager().getProperties()
.getProperty(name) == null) {
throw new AttributeNotFoundException(name);
}

Object value = attribute.getValue();
if (!(value instanceof String)) {
throw new InvalidAttributeValueException(
"Attribute value not a string: " + value);
}

// set the property and save the properties file
managedBootstrap.getComponentPropertiesManager().getProperties()
.setProperty(name, (String) value);
try {
save();
} catch (IOException e) {
throw new MBeanException(e);
}
}

/*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#setAttributes(javax.management.AttributeList)
*/

public synchronized AttributeList setAttributes(AttributeList list) {
AttributeList result = new AttributeList();

for (Object object : list) {
Attribute attr = (Attribute) object;
String name = attr.getName();
Object value = attr.getValue();
if (managedBootstrap.getComponentPropertiesManager()
.getProperties().getProperty(name) != null
&& value instanceof String) {
managedBootstrap.getComponentPropertiesManager()
.getProperties().setProperty(name, (String) value);
result.add(new Attribute(name, value));
}
}

try {
save();
} catch (IOException e) {
return new AttributeList();
}
return result;
}

The previous methods are the ones which are called by the JMX implementation for management. In our case it is quite simple since a property entry is directly mapped into an attribute...

Note 1 : The managedBootstrap attribute is a class which contains a Properties object.
Note 2 : We persist the properties in a file each time a property is modified.

In order to expose these attributes, we will see later that we need to create a set of MBeanAttributeInfo that will be used by the getMBeanInfo method to create the information object used by JMX to expose all of this.

    /**
* Dynamically get attributes for the MBean. The attributes are the ones
* from the properties file.
*
* @return
*/

protected MBeanAttributeInfo[] getAttributesInfos() {
// get the attributes names as sorted strings
Set<String> attributeKeys = managedBootstrap
.getComponentPropertiesManager().getExposedAttributeKeys();

// build the MBeanAttributeInfo
MBeanAttributeInfo[] attrs = new MBeanAttributeInfo[attributeKeys
.size()];
Iterator<String> it = attributeKeys.iterator();
for (int i = 0; i < attrs.length; i++) {
String name = it.next();
attrs[i] = new MBeanAttributeInfo(name, "java.lang.String",
"Property " + name, true, true, false);
}
return attrs;
}

How to expose a set of methods?

Building the MBeanInfo

In the previous chapter, I have introduced how we can dynamically expose properties. Now we will focus on how we can choose the methods to expose through JMX. There are several methods to do this. Here I have choosen to expose only the public methods that are programatically defined in a list. I have choosen this simple way to allow the component developer to simply define the methods he wants to expose by returning a list of methods names... Simple and efficient!

    /**
* Dynamically get the operations for the MBean. The operations are defined
* in the properties manager with a special prefix.
*
* @return
*/

protected MBeanOperationInfo[] getOperationsInfos() {
List<String> methods = managedBootstrap.getComponentPropertiesManager()
.getExposedMethodNames();
MBeanOperationInfo[] result = null;

List<MBeanOperationInfo> operations = new ArrayList<MBeanOperationInfo>();
Method methodList[] = managedBootstrap.getClass().getMethods();

for (int i = 0; i < methodList.length; i++) {
Method method = methodList[i];
String name = method.getName();

// add method if it has been defined by the user
if (methods.contains(name)) {
MBeanOperationInfo oper = new MBeanOperationInfo(
"Operation description", method);
operations.add(oper);
}
}

result = new MBeanOperationInfo[operations.size()];
operations.toArray(result);

return result;
}

This time again, we are are creating a set of MBeanOperationInfo from a list methods names. We retrieve the methods from the class we want to manage from the managedBootstrap class by reflection.

This method will be then used to create the MBeanInfo that is returned by the method getMBeanInfo:

    /*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#getMBeanInfo()
*/

public synchronized MBeanInfo getMBeanInfo() {
// get the attributes
MBeanAttributeInfo[] attrs = getAttributesInfos();
// get the operations
MBeanOperationInfo[] opps = getOperationsInfos();

// create MBeanInfo with no constructors and no notifications
return new MBeanInfo(this.getClass().getName(),
"Property Manager MBean", attrs, null, opps, null);
}

Invoking a method

Doing java reflection is out of this article scope. Have a look on the implementation to see how it is done.

Complete implementation


/**
* PETALS - PETALS Services Platform.
* Copyright (c) 2007 EBM Websourcing, http://www.ebmwebsourcing.com/
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* -------------------------------------------------------------------------
* $Id$
* -------------------------------------------------------------------------
*/

package org.objectweb.petals.component.common;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.ReflectionException;
import javax.management.RuntimeOperationsException;

/**
* The MBean used to expose component attributes and operations via JMX.
*
* @author Christophe HAMERLING - eBMWebSourcing
*
*/

public class ExtensionMBean implements DynamicMBean {

private ManagedBootstrap managedBootstrap;

private final static Hashtable<String, Class<?>> primitiveClasses = new Hashtable<String, Class<?>>(
8);
{
primitiveClasses.put(Boolean.TYPE.toString(), Boolean.TYPE);
primitiveClasses.put(Character.TYPE.toString(), Character.TYPE);
primitiveClasses.put(Byte.TYPE.toString(), Byte.TYPE);
primitiveClasses.put(Short.TYPE.toString(), Short.TYPE);
primitiveClasses.put(Integer.TYPE.toString(), Integer.TYPE);
primitiveClasses.put(Long.TYPE.toString(), Long.TYPE);
primitiveClasses.put(Float.TYPE.toString(), Float.TYPE);
primitiveClasses.put(Double.TYPE.toString(), Double.TYPE);
}

/**
* Creates a new instance of {@link ExtensionMBean}
*
* @param bootstrap
*/

public ExtensionMBean(ManagedBootstrap bootstrap) {
this.managedBootstrap = bootstrap;
}

/*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#getAttribute(java.lang.String)
*/

public synchronized Object getAttribute(String attribute)
throws AttributeNotFoundException, MBeanException, ReflectionException {

String value = managedBootstrap.getComponentPropertiesManager()
.getProperties().getProperty(attribute);
if (value != null
&& !value
.startsWith(ComponentPropertiesManager.MANAGED_METHOD_PREFIX)) {
return value;
} else {
throw new AttributeNotFoundException("Attribute '" + attribute
+ "' does not exists");
}
}

/*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#getAttributes(java.lang.String[])
*/

public synchronized AttributeList getAttributes(String[] attributes) {
AttributeList list = new AttributeList();
for (String name : attributes) {
String value = managedBootstrap.getComponentPropertiesManager()
.getProperties().getProperty(name);
if (value != null
&& !value
.startsWith(ComponentPropertiesManager.MANAGED_METHOD_PREFIX))
list.add(new Attribute(name, value));
}
return list;
}

/*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#setAttribute(javax.management.Attribute)
*/

public synchronized void setAttribute(Attribute attribute)
throws AttributeNotFoundException, InvalidAttributeValueException,
MBeanException, ReflectionException {
String name = attribute.getName();
if (managedBootstrap.getComponentPropertiesManager().getProperties()
.getProperty(name) == null) {
throw new AttributeNotFoundException(name);
}

Object value = attribute.getValue();
if (!(value instanceof String)) {
throw new InvalidAttributeValueException(
"Attribute value not a string: " + value);
}

// set the property and save the properties file
managedBootstrap.getComponentPropertiesManager().getProperties()
.setProperty(name, (String) value);
try {
save();
} catch (IOException e) {
throw new MBeanException(e);
}
}

/*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#setAttributes(javax.management.AttributeList)
*/

public synchronized AttributeList setAttributes(AttributeList list) {
AttributeList result = new AttributeList();

for (Object object : list) {
Attribute attr = (Attribute) object;
String name = attr.getName();
Object value = attr.getValue();
if (managedBootstrap.getComponentPropertiesManager()
.getProperties().getProperty(name) != null
&& value instanceof String) {
managedBootstrap.getComponentPropertiesManager()
.getProperties().setProperty(name, (String) value);
result.add(new Attribute(name, value));
}
}

try {
save();
} catch (IOException e) {
return new AttributeList();
}
return result;
}

/*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#getMBeanInfo()
*/

public synchronized MBeanInfo getMBeanInfo() {
// get the attributes
MBeanAttributeInfo[] attrs = getAttributesInfos();
// get the operations
MBeanOperationInfo[] opps = getOperationsInfos();

// create MBeanInfo with no constructors and no notifications
return new MBeanInfo(this.getClass().getName(),
"Property Manager MBean", attrs, null, opps, null);
}

/**
* Dynamically get the operations for the MBean. The operations are defined
* in the properties manager with a special prefix.
*
* @return
*/

protected MBeanOperationInfo[] getOperationsInfos() {
List<String> methods = managedBootstrap.getComponentPropertiesManager()
.getExposedMethodNames();
MBeanOperationInfo[] result = null;

List<MBeanOperationInfo> operations = new ArrayList<MBeanOperationInfo>();
Method methodList[] = managedBootstrap.getClass().getMethods();

for (int i = 0; i < methodList.length; i++) {
Method method = methodList[i];
String name = method.getName();

// add method if it has been defined by the user
if (methods.contains(name)) {
MBeanOperationInfo oper = new MBeanOperationInfo(
"Operation description", method);
operations.add(oper);
}
}

result = new MBeanOperationInfo[operations.size()];
operations.toArray(result);

return result;
}

/**
* Dynamically get attributes for the MBean. The attributes are the ones
* from the properties file.
*
* @return
*/

protected MBeanAttributeInfo[] getAttributesInfos() {
// get the attributes names as sorted strings
Set<String> attributeKeys = managedBootstrap
.getComponentPropertiesManager().getExposedAttributeKeys();

// build the MBeanAttributeInfo
MBeanAttributeInfo[] attrs = new MBeanAttributeInfo[attributeKeys
.size()];
Iterator<String> it = attributeKeys.iterator();
for (int i = 0; i < attrs.length; i++) {
String name = it.next();
attrs[i] = new MBeanAttributeInfo(name, "java.lang.String",
"Property " + name, true, true, false);
}
return attrs;
}

/*
* (non-Javadoc)
*
* @see javax.management.DynamicMBean#invoke(java.lang.String,
* java.lang.Object[], java.lang.String[])
*/

public Object invoke(String actionName, Object[] params, String[] signature)
throws MBeanException, ReflectionException {
Object result = null;

final Class objClass = managedBootstrap.getClass();
final ClassLoader loader = objClass.getClassLoader();
final Class[] parameters = ((signature == null) ? null
: findSignatureClasses(signature, loader));

// Query the metadata service to get the right method
//
Method method = null;
try {
method = objClass.getMethod(actionName, parameters);
} catch (Exception e) {
}

if (method == null) {
throw new ReflectionException(
new NoSuchMethodException(actionName),
"The operation with name " + actionName + " could not be found");
}

try {
// invoke method
result = method.invoke(managedBootstrap, params);
} catch (IllegalAccessException e) {
throw new ReflectionException(e, "IllegalAccessException"
+ " occured trying to invoke operation " + actionName);
} catch (RuntimeException e) {
throw new RuntimeOperationsException(e, "RuntimeException"
+ " occured trying to invoke operation " + actionName);
} catch (InvocationTargetException e) {
throw new MBeanException(e, "Exception thrown in operation "
+ actionName);
}
return result;
}

/**
* Find the classes of the signature
*
* @param signature
* @param loader
* @return
* @throws ReflectionException
*/

private Class[] findSignatureClasses(String signature[], ClassLoader loader)
throws ReflectionException {
if (signature == null)
return null;

final int length = signature.length;
final Class tab[] = new Class[length];

if (length == 0)
return tab;

try {
for (int i = 0; i < length; i++) {

// try to get the primitive class
final Class primCla = (Class) primitiveClasses
.get(signature[i]);
if (primCla != null) {
tab[i] = primCla;
} else {
// try to get the class if not primitive one
tab[i] = Class.forName(signature[i], false, loader);
}
}
} catch (ClassNotFoundException e) {
throw new ReflectionException(e,
"The parameter class could not be found");
} catch (RuntimeException e) {
throw e;
}
return tab;
}

/**
* Save the properties to a file
*
* @throws IOException
*/

private void save() throws IOException {
managedBootstrap.getComponentPropertiesManager().save();
}


About

I am a software engineer and community manager on the open source PEtALS ESB project at eBM WebSourcing.
You can get this article as PDF file on my scribd space or on my work blog.

January 27, 2008 11:50 PM

PEtALS 1.2 and Axis2BC new features

PEtALS 1.2 is finally out (http://petals.objectweb.org ).
This new release introduces lot of new features and improvements like:

As I have worked again on the Axis2 binding component (Axis2BC), here are some new improvements on this component:
How does SOAP attachment works?
As simple as:
  1. For incoming messages, all the SOAP attachments are placed as JBI ones
  2. For outgoing messages, all the JBI attachments are placed as SOAP ones
With Axis2, two types of attachments are possible, MTOM(Message Transmission Optimization Mechanism) and SWA (SOAP With Attachments).
Both of them allows to handle large amounts of binary data. More explanations are available on the Web...
In the Axis2BC we use the MTOM approach.

Adding SOAP attachments is as simple as (code snippet from org.objectweb.petals.binding.axis2.listener.jbi.JBIListener class):
    protected OMElement createSOAPMessage(NormalizedMessage nm,
        ServiceClient client) throws XMLStreamException,
        FactoryConfigurationError, PEtALSComponentSDKException {

        // create the root element
        OMFactory fac = OMAbstractFactory.getOMFactory();
        Source body = nm.getContent();
        String content = SourceHelper.createString(body);
        XMLStreamReader parser = XMLInputFactory.newInstance()
            .createXMLStreamReader(new StringReader(content));
        StAXOMBuilder builder = new StAXOMBuilder(parser);

        OMElement document = builder.getDocumentElement();

        // add attachments if any
        if (nm.getAttachmentNames().size() > 0) {
            // enable MTOM
            client.getOptions().setProperty(
                Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE);

            // Add JBI attachments to the document element
            Set names = nm.getAttachmentNames();
            for (Object key : names) {
                String name = (String) key;
                DataHandler attachment = nm.getAttachment(name);
                OMText attach = fac.createOMText(attachment, true);
                document.addChild(attach);
            }
        }

        return document;
    }

And getting SOAP attachments from SOAP message (code snippet from org.objectweb.petals.binding.axis2.listener.soap.PetalsReceiver class) :
    private void copySOAPAttachmentsToJBI(MessageContext messageContext,
        NormalizedMessage nm) throws MessagingException {

        if (nm != null && messageContext != null) {
            Attachments attachments = messageContext.getAttachmentMap();
            if (attachments != null) {
                Set set = attachments.getContentIDSet();
                for (Object object : set) {
                    String id = (String) object;
                    DataHandler dh = attachments.getDataHandler(id);
                    nm.addAttachment(id, dh);
                }
            }
        }
    }

A simple test scenario
A simple scenario to test the SOAP attachments with PEtALS is described below. We use the PEtALS sample client to send data to a service that will write it into a directory. In order to use the Axis2 binding component, it is placed between the client and the targeted endpoint. The 'workflow' is:
  1. Send data and attachments to Axis2BC provided endpoint. This endpoint provides access to an external web service.
  2. The Axis2BC takes all the data from the incoming JBI message and put it into the SOAP message
  3. The Axis2BC sends the SOAP message to the external web service
  4. Axis2BC is also configured to handle external on the address previously invoked. It consumes an endpoint provided by the File Transfer binding component (FTBC)
  5. Axis2BC handle the incoming SOAP message and put all the data (and attachments) into a new JBI message
  6. The JBI message is sent to the FTBC endpoint
  7. The FTBC endpoint receives the JBI message and write all the data to files
  8. Response is sent to client...

All the needed service units are available on the PEtALS use cases section here.

This blog entry is also available at http://docs.google.com/Doc?id=dcrqrprg_27hnpbfk


January 27, 2008 11:50 PM

Install configure and use a corporate maven repository and a maven proxy

Maven proxy is a nice tool but documentation available on the web is not...
This blog entry describes how to install, configure and use the maven-proxy. It also defines how to create a corporate maven repository.

Maven2 installation

Binary installation

Download the latest binary version of maven (http://maven.apache.org ) and as root:
cd /usr/share
tar zxvf maven-x.y.z-bin.tar.gz
ln -s maven-x.y.z maven2

Configuration

Add environment variables to the /etc/profile file (or in your .bashrc if you want)
M2_HOME=/usr/share/maven2
MAVEN_OPTS=-Xmx256M
PATH=$PATH:$M2_HOME/bin
export M2_HOME
export MAVEN_OPTS
export PATH

Create a deployer user

This user will be used to deploy new artifacts in maven repositories.
mkdir /home/maven
useradd -g buildauto -d /home/maven maven
passwd maven
chown -R maven:buildauto /home/maven

Create Maven2 corporate repositories

We create two repositories, one for the the artifacts that can not be installed for licence reasons and the other for the artifacts snapshots that will only be accessible directly. You have to install apache first(out of scope of this blog entry, tell your system admin to install it or ask google how to do it if you don't know how).

Directories

As root:
mkdir /var/lib/m2-repo
mkdir /var/lib/m2-repo-snapshots
chown -R maven:buildauto /var/lib/m2-repo /var/lib/m2-repo-snapshots

Create symbolic links to be abble to access these repositories with http. If apache handle directories in /var/www, simply create the links:
ln -s /var/lib/m2-repo /var/www/maven2
ln -s /var/lib/m2-repo-snapshots /var/www/maven2-snapshots

Repositories are now accessible at addresses http://repo_host/maven2 and http://repo_host/maven2_snapshots.

How to install artifacts

To install an artifact in the repository, use maven2 command:
mvn deploy:deploy-file
      -Durl=scp://repo_host:/var/lib/m2-repo
      -DrepositoryId=corpo-maven-repository
      -Dpackaging=<packaging>
      -DgroupId=<groupId>
      -DartifactId=<artifactId>
      -Dversion=<version>
      -Dfile=<file>

or this one if you already have the pom of the artifact:
mvn deploy:deploy-file
    -Durl=scp://repo_host:/var/lib/m2-repo
    -DrepositoryId=corpo-maven-repository
    -DpomFile=<pomfile>
    -Dfile=<jarfile>


You can specify the repositoryId in your maven2 configuration file to avoid entering user name and password each time (in $M2_HOME/conf/settings.xml):
<server>
   <id>corpo-maven-repository</id>
   <username>maven</username>
   <password>xxx</password>
</server>

Maven proxy installation

Download the maven-proxy standalone : http://maven-proxy.codehaus.org

Connect your maven server as root and enter these commands:
cd /usr/share
tar zxvf maven-proxy-standalone-x.y.z.tar.gz
mkdir maven-proxy
cd maven-proxy
ln -s ../maven-proxy-x.y.z/maven-proxy-standalone-x.y.z-app.jar maven-proxy-standalone-app.jar

Next we need to create the cache directory (the proxy will download the required files here)
mkdir /var/cache/maven-proxy

Copy the maven properties file in /etc/maven/maven-proxy.properties. You can download a sample of this file from the maven-proxy website.
In this file, you are going to specify the repositories you want to access through the proxy. For example:

################ GLOBAL SETTINGS
# This is where maven-proxy stores files it has downloaded
repo.local.store=/var/cache/maven-proxy
...
################ SNAPSHOT HANDLING
#If you want the proxy to look for newer snapshots, set to true
snapshot.update=false
...
################# REPOSITORIES
#This is not just a hack, it specifies the order repositories should be checked
#Note that the proxy adds a "/" which is why the urls aren't suffixed with a "/"
repo.list=local-repo,www-ibiblio-org
repo.local-repo.url=file:////var/lib/m2-repo
repo.local-repo.description=My corpo - Maven2 Repository
repo.local-repo.copy=false
repo.local-repo.hardfail=true
repo.local-repo.cache.period=0
#www.ibiblio.org
repo.www-ibiblio-org.url=http://www.ibiblio.org/maven2
repo.www-ibiblio-org.description=www.ibiblio.org
repo.www-ibiblio-org.hardfail=true
repo.www-ibiblio-org.cache.period=3600
repo.www-ibiblio-org.cache.failures=true
#other repo
...

If you want to add logs, you can modify the log4j properties file in the proxy jar file to add logs (extract and jar it again):
# Set root logger level to DEBUG
log4j.rootLogger=DEBUG,CONSOLE,R
# ConsoleAppender.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
# Console PatternLayout.
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d [%-5p] %-20c{3} %x - %m%n
log4j.logger.org.mortbay=WARN
log4j.logger.httpclient.wire=INFO
log4j.logger.org.apache.commons.httpclient=INFO
log4j.logger.org.apache.jasper=INFO
# File appender
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=/var/log/maven-proxy.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

Proxy daemon

Installing the proxy as daemon in /etc/init.d/maven-proxy
#! /bin/sh
set -e
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="Maven Proxy"
NAME=maven-proxy
JAVA_HOME=/home/dev/bin/java
DAEMON=$JAVA_HOME/bin/java
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
MAVENPROXY_HOME=/usr/share/$NAME
MAVENPROXY_JAR=$MAVENPROXY_HOME/maven-proxy-standalone-app.jar
# Gracefully exit if the package has been removed.
test -r $MAVENPROXY_JAR || exit 0
# Function that starts the daemon/service.
d_start() {
# We change dir to /var/log, because Velocimacro logfile is created in the current directory
   start-stop-daemon --chdir /var/log --start --background --quiet \
                     --pidfile $PIDFILE --make-pidfile --exec $DAEMON -- -jar $MAVENPROXY_JAR \
                                                        /etc/maven-proxy/maven-proxy.properties
}
# Function that stops the daemon/service.
d_stop() {
   start-stop-daemon --stop --quiet --pidfile $PIDFILE --signal TERM
}
# Function that sends a SIGHUP to the daemon/service.
d_reload() {
   start-stop-daemon --stop --quiet --pidfile $PIDFILE --signal 1
}
case "$1" in
  start)
   echo -n "Starting $DESC: $NAME"
   d_start
   echo "."
   ;;
  stop)
   echo -n "Stopping $DESC: $NAME"
   d_stop
   echo "."
   ;;
  restart|force-reload)
   #
   # If the "reload" option is implemented, move the "force-reload"
   # option to the "reload" entry above. If not, "force-reload" is
   # just the same as "restart".
   #
   echo -n "Restarting $DESC: $NAME"
   d_stop
   sleep 1
   d_start
   echo "."
   ;;
  *)
   echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
   exit 1
   ;;
esac
exit 0

Create the links for host startup:
ln -s ../init.d/maven-proxy /etc/rc3.d/S22maven-proxy
ln -s ../init.d/maven-proxy /etc/rc4.d/S22maven-proxy
ln -s ../init.d/maven-proxy /etc/rc5.d/S22maven-proxy

And start the proxy as root like this
/etc/init.d/maven-proxy start

Use the proxy

Now that the environment has been setted up, you can use it for your developments.

Configuration file

You have to tell maven that you want it uses the proxy. To do this, you must add the settings.xml file to your local repository (in $HOME/.m2/).
<settings>
        <profiles>
                <profile>
                        <id>default-profile</id>
                        <activation>
                                <activeByDefault>TRUE</activeByDefault>
                        </activation>
                        <repositories>
                                <repository>
                                        <id>myproject-repository-repohost</id>
                                        <name>repohost Repo</name>
                                        <url>http://192.168.1.230:9999/repository/</url>
                                        <snapshots>
                                                <enabled>TRUE</enabled>
                                        </snapshots>
                                        <releases>
                                                <enabled>TRUE</enabled>
                                        </releases>
                                </repository>
                        </repositories>
                        <pluginRepositories>
                                <pluginRepository>
                                        <id>myproject-repository-repohost</id>
                                        <name>repohost Repo</name>
                                        <url>http://192.168.1.230:9999/repository/</url>
                                        <snapshots>
                                                <enabled>TRUE</enabled>
                                        </snapshots>
                                        <releases>
                                                <enabled>TRUE</enabled>
                                        </releases>
                                </pluginRepository>
                        </pluginRepositories>
                </profile>
        </profiles>
</settings>

Now you can remove all the repositories from your pom files and let maven get artifacts from the proxy.

January 27, 2008 11:50 PM

The PEtALS v1.1 Axis2 binding component

PEtALS 1.1 is finally out with lot of new features and improvements.
I have done many changes to the Axis2 binding component (Axis2BC) which is currently based on Axis2 v1.1.1.
This binding component is used to handle incoming and outgoing SOAP requests from/to the JBI container. It uses the PEtALS Component Development Kit (CDK) and offers lot of new features in its current 1.1 version.

The current article details the main features of the BC and also introduces the methodology used to offer these features.

How to embed a Jetty Server ?

As a binding component, the SOAP have to be able to handle incoming SOAP requests. The choice of using a Jetty server to handle incoming SOAP requests comes from:
  1. The simple server provided with Axis has poor performances. This server was used on the previous version of the BC. The performance study I have made shows that handling web service calls into a dedicated server is better.
  2. Jetty is easily embeddable (Tomcat is not as easy as Jetty)
  3. Servlets can be deployed easily on Jetty

Like mentioned above, embedding a Jetty server is quite simple. You also have to create a new instance of the server like this (snippet from class org.objectweb.petals.binding.axis2.listener.soap.AxisJettyServer):

public AxisJettyServer(ConfigurationContext configurationContext, int port) throws AxisFault {
this.port = port;
this.configurationContext = configurationContext;
this.server = new Server(this.port);

// create context handlers
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);

// create the axis context
Context axis2 = new Context(contexts, "/axis2", Context.SESSIONS);

// create servlet holders
ServletHolder axisServlet = new ServletHolder(new AxisJettyServlet(
configurationContext));
axisServlet.setName("AxisServlet");
axisServlet.setInitOrder(1);

// do servlet mappings
axis2.addServlet(axisServlet, "/services/*");
// axis2.addServlet(axisRESTServlet, "/rest/*");
axis2.addServlet(axisServlet, "/servlet/AxisServlet");
// axis2.addServlet(axisAdminServlet, "/axis2-admin/*");

// AXIS
ListenerManager listenerManager = configurationContext
.getListenerManager();
TransportInDescription trsIn = new TransportInDescription(new QName(
Constants.TRANSPORT_HTTP));
trsIn.setReceiver(this);
if (listenerManager == null) {
listenerManager = new ListenerManager();
listenerManager.init(configurationContext);
}
listenerManager.addListener(trsIn, true);
}

In the above code, we create the context and we register a the servlet AxisJettyServlet that will be used to handle incoming SOAP requests.
To start and stop the server you have simply to call the start and stop method like this:

public void start() throws AxisFault {
// start the jetty server in a separate thread
Runnable httpListenerRunnable = new Runnable() {
public void run() {
try {
server.start();
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
};
Thread httpThread = new Thread(httpListenerRunnable,
"Jetty started Thread");

try {
httpThread.start();
httpThread.join();
} catch (InterruptedException e) {
throw new AxisFault(e.getMessage());
} catch (Exception e) {
throw new AxisFault(e.getMessage());
}
}

Even if embedding Jetty was quite simple, tuning Axis to work like we want it works in the JBI environment was not so simple. I will discuss about this later on this post.

Registering new services

To create and register the new service, follow the steps:
  1. Create a new AxisService (org.apache.axis2.description.AxisService)
  2. Add parameters such as document definition for example (not used like this in the BC)
  3. Register it into the axis configuration (org.apache.axis2.engine.AxisConfiguration)

The code snippet above is taken from the SUListener used in the Axis2BC:

AxisService axisService = new AxisService(endPointName);
axisService.setTargetNamespace(serviceQName.getNamespaceURI());
axisService.setEndpoint(consumedEndpoint);

axisService.addParameter(new Parameter(Constants.SERVICE_CLASS, "PetalsReceiver"));

// add parameter to handle ?wsdl requests
Parameter useOriginalwsdl = new Parameter("useOriginalwsdl", "true");
axisService.addParameter(useOriginalwsdl);

ServiceEndpoint endpoint = componentContext.getEndpoint(serviceQName, consumedEndpoint);
if (endpoint != null) {
Definition def = null;
Document document = componentContext.getEndpointDescriptor(endpoint);
if (document != null) {
try {
def = WSDLHelper.createDefinitionFromDocument(document);
} catch (WSDLException e) {
logger.log(Level.WARNING, "WSDL Definition has not been initialized");
}
}

Parameter defParam = new Parameter(WSDLConstants.WSDL_4_J_DEFINITION, def);
axisService.addParameter(defParam);

} else {
logger.log(Level.WARNING, "Enpoint " + consumedEndpoint
+ " has not been found, service "
+ axisService.getName() + " registered");
}

// add service
axisConfig.addService(axisService);

Handling incoming calls

As mentioned above, handling incoming SOAP calls is done with the Axis servlet deployed on the Jetty server. When the servlet handle the HTTP request, lot of work processing and mapping is done by the Axis engine. To be able to transform and send the data from Axis to JBI, we have developed and added a special Axis Dispatcher (org.objectweb.petals.binding.axis2.listener.soap.PetalsDispatcher).
This is possible since Axis is an extensible messaging engine. Simply by adding our dispatcher to the axis2.xml configuration file (and configuring it during the BC initialization), the SOAP message will be transformed into a JBI one and then sent to the linked JBI endpoint.

To create a dispatcher, simply extends the abstract dispatcher class:
org.apache.axis2.engine.AbstractDispatcher

Modify the axis2 configuration file by adding you dispatcher (from axis2.xml) :

...


class="org.objectweb.petals.binding.axis2.listener.soap.PetalsDispatcher">


...

...


Handling outgoing calls

This operation was very simple. Since the BC uses the CDK, this CDK provides abstract class to extend to handle incoming JBI message.
In the PEtALS CDK, we use the JBIListener (org.objectweb.petals.component.common.bc.JBIListener). The method to implement is:

boolean onJBIMessage(String address, MessageExchangeWrapper exchange,
Extensions extensions) throws HandlingException;

The only thing to do in the implementation is to create a SOAP message from the JBI one and then to send it to the external web service using the Axis2 API.

SOAP with attachments

One cool feature that is provided by Axis is the capability to handle SOAP attachments with two methods:
  1. MTOM : Message Transmission Optimization Mechanism

  2. SWA : SOAP with attachments

To use the SOAP attachments, you need to enable one of the previous mode (if both are enabled, MTOM will get priority over SwA).
To enable MTOM, you can:

The SwA will be enabled like this:

SOAP with attachments will be provided soon in the Axis2BC probably with the MTOM method.

Getting the service description

After all the previous modifications on the Axis behaviour, and in addition of the JBI container, getting the WSDL description of a provided service was not so simple. After investigations I discovered that the mechanism is very different from the one that we was using with Axis1.
To be able to provide the WSDL description that is stored in the JBI container the simplest solution was to extends the AxisService class and to override the printWSDL methods. In the overridden methods, we get the WSDL description from the JBI container through the component context. In this case, the WSDL description is always up to date when a component is removed from the container and installed again with a brand new description.

Proxy enabled

The Axis2BC is proxy compliant. It just have to be configured with the service unit. To do so, simply add proxy settings in the service unit like this:




...

?
hostname
port
user
password
domain
?





January 27, 2008 11:50 PM

January 25, 2008

Ludovic Dubost

Rapport Attali

Avant-hier, j’ai passé un peu de temps à lire le rapport Attali.

Un débat est en cours au sujet des propositions sur l’Open-Source. L’AFDEL a réagit violement dans un ...

January 25, 2008 04:40 PM

January 21, 2008

Pierre-Yves Gibello

Default face

La Foulée Blanche en caméra embarquée !

Fervent adepte du ski de fond, j'ai eu récemment l'idée saugrenue de filmer de l'intérieur un départ de course longue distance. Evidemment, pas question de s'encombrer d'un matériel lourd, ni d'ajouter aux contraintes de la course celles de la prise de vue...
J'ai donc choisi de "scotcher" (velcro, en fait) une mini-caméra derrière ma ceinture porte-bidon : en l'occurrence, il s'agit d'une "FlyCam One V2", petit appareil de 40 grammes équipé d'une SD Card et destiné à l'origine au modélisme aérien.
Premier test - peu concluant- au marathon de Bessans : je n'ai filmé que le ciel ! J'ai également découvert que ma caméra ne supportait guère le froid (je scotche donc une chaufferette à mains dessus), et que l'autonomie batterie était fort limitée (c'est le prix de la légèreté).

C'est donc fort de ces expériences que je me suis attelé à filmer le départ de la Foulée Blanche 2008 (42km, style libre), ce 20 Janvier à Autrans : résultat, 7 minutes de vidéo brouillonne et aux couleurs fantaisistes, mais quand même, on y est... sur une fantastique "neige à chrono", l'ambiance des 3 dernières minutes de film est même assez électrique !

Mais trève de bavardages : allez donc voir le résultat sur DailyMotion (lien permanent : http://www.dailymotion.com/video/x44b76_foulee-blanche-2008_sport), en espérant que ce genre d'idée fasse des émules... et attire des skieurs vers nos belles pistes de fond !


Foulée Blanche 2008

January 21, 2008 02:15 PM

January 17, 2008

Orbeon

Default face

Bad forms, part II

Continental Logo

I recently booked a flight on the Continental web site. I knew approximately the flight I wanted to book, so dug right away into the search to select it. I encountered the following issues:

Now let’s say the developers of the Continental web site decide to switch to Orbeon Forms and XForms for the next version of the web site:

And this is all interactive too, meaning that the user doesn’t need to wait one minute to know that some fields are missing or incorrect.

January 17, 2008 02:24 AM

January 14, 2008

Valerio Schiavoni

Default face

www.macbookair.com redirects to apple.com

The url: http://www.macbookair.com now redirects to:

http://www.apple.com/?Will+We+see+a+MacBookAir+on+Tuesday?

The hype is mounting...

January 14, 2008 11:36 PM

MacBook Air leaked?

Let's face it yourself : http://images.worldofapple.com/87a7fr4.gif
 

January 14, 2008 10:58 PM

January 13, 2008

Jéremi Joslin

Anti portabilité des réseaux sociaux.

Quelques mois de ça, je parlais de la portabilité des réseaux sociaux. Je n’ai malheuresement pas continué ma suite d’article prévu. Depuis cet article, pas mal de choses se sont passé, en particulier les groupes de travail Data portability et Diso .

Après l’histoire de Robert Scoble se faisant fermer son compte pour avoir essayé d’exporter les emails de ses contacts dans Plaxo, la portabilité des réseaux sociaux a fait beaucoup de bruits. Bob Backley du Burton Group trouve cela normal:

"Even the fact of your relationship with Scoble is not Scoble’s property, it is common property, like the kids in a joint custody arrangement. Both you and Scoble are obligated by the laws of relation to treat the fact that you have a relationship, and also the details of the relationship, according to certain understandings and social conventions. If you don’t believe this, meditate on whether you think it would be OK for adultfriendfinder.com, match.com, and linkedin to share friend lists. The information Scoble tried to take out of Facebook is NOT Scoble’s property; it is relationship information. Scoble is not free to do whatever he pleases with relationship information; if he violates social understandings and conventions by disclosing the existence of or certain information about his relationship with you in the wrong context, he may embarrass or endanger you, and he will certainly endanger the relationship."

D’un côté je partage l’avis que la relation qui me lit à quelqu’un n’appartient pas qu’a moi, mais elle est partagé avec l’autre personne. Mais elle n’appartient pas à Facebook non plus. Facebook est en quelque sorte le tierce de confiance dans ma relation avec mes amis.

L’idée que je me fais de la portabilité des réseaux sociaux n’est pas de répliquer 1:1 ma liste d’amis sur Facebook et sur Linked’In et encore moins créer une relation bilatérale (à la différence de la relation de fan qui est unilatéral en général, et qui existe par exemple sur pownce) avec un ami de Linked’In sur facebook sans son autorisation. Le fait de rendre les réseaux portable ne veut pas dire non plus que je vais avoir les mêmes amis sur tous les réseaux, mais plutôt d’avoir la possibilité d’extraire ma liste d’amis d’un réseau social, de sélectionner ceux que je souhaite synchroniser avec mon autre réseau social. Il faut donc une application tierce dont le seul objectif est de gérer votre liste de contact et les relations avec les gens. C’est elle qui gère l’intermédiaire entre les différents « walled garden ».

Je pense qu’il ne serait pas très difficile de prototyper une application de ce style.

January 13, 2008 04:28 PM

January 10, 2008

Jéremi Joslin

video d’eXo Platform @ openCoffee

eXo @ openCoffee

Enregistrè à l’OpenCoffee Club de Paris, le 3 janvier 2008. Je parle des nouvelles applications qui vont arriver bientôt :)

merci à Stéphane Enilorac de moovement.fr pour la video.

January 10, 2008 01:30 PM

Christophe Hamerling

Default face

Too many open files IOException with large number of Axis2 Servic

This is a problem we met in the PEtALS SOAP Binding Component with large number of Axis2 Service Clients.
In this case, this error happens when too many sockets are open ant are waiting to be closed. Even if I have found some JIRAs about this problem and possible solutions, the only one which work for us is to cleanup the connection after each service call.
It is done like this :

...

ServiceClient client = new ServiceClient(null, service);

Options options = new Options();

...

options.setCallTransportCleanup(true);

client.setOptions(options);


OMElement outBodyElement = null;

try {

outBodyElement = serviceClient.sendReceive(soapAction, inBodyElement);

} catch (AxisFault e) {

throw e;

}



After 10 minutes test with 200 threads creating 'one shot ' ServiceClient and almost 275000 service calls, all worked fine.

January 10, 2008 09:00 AM

January 09, 2008

Valerio Schiavoni

Default face

Removing object methods in Ruby

Ruby provides a built-in mixin facility which turns out to be very useful for meta-programming issues. As you might know, having an object extending a module results in the original object to provide all methods of the module.

Something like:

class Server
end
module Print
  def print
    puts 'hello'
  end
end
s = Server.new
#mixing in printing capabilities
s.extend(Print)
s.print

will safely result in printing 'hello'. But how can we remove it back again, so that the print method is no longer availble? Well, here's the trick:

Print.send :remove_method, :print
s.print

if you run the code above, you should see something like :

hello
misc.rb:19: private method `print' called for # (NoMethodError)

This has a drawback: creating a new instance of Server, and letting it extend the Print module won't be enough to have back a printer-aware server...I still have to find out how to remove the method from an instance object, and from it alone, without impacting on other (possibly not existent yet) instances.

January 09, 2008 10:02 PM

January 08, 2008

Orbeon

Default face

Yahoo! goes XForms

Yahoo! Blueprint

Yahoo! today announced a new mobile platform called “Mobile Widgets”. The amazing part is that the language used to describe widgets, called Blueprint, is based on XForms:

Much of Blueprint’s philosophy and syntax comes from XForms. We opted for a full declarative language because it was the only way we could effectively run on the wide range of devices out there, some of which have no scripting at all. By using declarative syntax, we can encapsulate and hide the scripting specifics. In some cases, the code could run on the phone, in other case, such as XHTML, we can put the logic on our servers. It’s the perfect way to deal with the various environments and their capabilities.

The Blueprint Philosophy and roadmap highlights the benefits of declarative vs. imperative, “because it was the only way we could effectively run on the wide range of devices out there, some of which have no scripting at all”. For now, only very basic XForms constructs are supported, but “In our second release of the Blueprint language you’ll be able to take full advantage of the power of XForms-style MVC programming”.

Although Orbeon does not particularly focuses on mobile devices, this philosophy is entirely in line with our transformations- and Ajax-based approach to deliver XForms everywhere (in our case to mainstream browsers). It is excellent news that a company like Yahoo! not only recognizes the benefits of the XForms approach, but also decides to leverage the standard instead of reinventing the wheel (like Google did with their Google Mashup Editor, which looks very much like an incompatible clone of XForms).

In short this is extremely positive for the XForms community. We can only hope that Blueprint lives up to its promises.

January 08, 2008 03:57 PM

Valerio Schiavoni

Default face

SCOrWare website public

In case you haven't noticed, the official website for the SCOrWare project went public some time ago now.

The SCOrWare project aims at providing an open source implementation of the recent Service Component Architecture (SCA) specifications

January 08, 2008 01:44 PM

January 07, 2008

Stéphane Traumat

Déménagement du blog de scub :)

Afin de faciliter la vie de nos lecteurs, nous avons décidé de faire un seul et unique blog pour tous les employés de Scub. Vous n'aurez donc plus qu'à vous connecter à cette adresse pour voir les posts de tous les gens qui font Scub !

Adresse du blog : http://www.scub.net/blog

January 07, 2008 05:20 PM

December 19, 2007

Valerio Schiavoni

Default face

Java 6 DP8 for Leopard: cool, but no Eclipse for now.

Ok, so Apple is still working on it. Nice to know.

Now, after the first 5 seconds of joy, let's calm down. Go and read the release note (you need to have an ADC free account,  sorry, i can't copy/paste it, it's under NDA).

But....well...it's a 64bit-only cpu enabled version ! This wouldn't bit a major problem, if not that Eclipse can't work ! At the moment, there's no SWT version compatible. Quoting an Apple engineer:

"The SWT is compiled for 32-bit Intel only, and even if you did try to rebuild it yourself, most of it won't build because the Carbon calls they use aren't available in 64-bit."

 

Volunteers go here: http://www.eclipse.org/swt


December 19, 2007 02:08 PM

December 17, 2007

JOnAS Team

JOnAS 5.0.0 Release Candidate

Hi JOnAS Enthusiasts !

All the JOnAS developers have spend a very long time (especially this week for the release) to offer to you this year‘s Xmas version of JOnAS !

We‘re very pleased to announce the availability of the new JOnAS release. This is the first Release Candidate (RC1) of the JOnAS 5.0 serie.

This version is special because it‘s our first OSGi release! It means that there was a lot of code refactoring in order to add dynamism at the heart of the application server.

If you want to see more about JOnAS 5.0.0 Release Candidate take a look at the New and noteworthy and check out the Getting Started (for JOnAS/OSGi).

Packages are downloadables from the OW2 forge.

JOnAS 5.0.0 is also available in its classic personnality (no OSGi, old style JONAS_ROOT).

Now, this release is in your hands: provide us some feedback through the mailing lists, fill the bug tracker with any issue you may find, …

Enjoy, and stay tunned for future announcements.

Guillaume
on behalf on the JOnAS team

December 17, 2007 10:40 PM

Valerio Schiavoni

Default face

Rails and iPhone: step 1

I finally decided to start working with Ruby on Rails. After the scaffolding examples and some experience with the whole ruby thing, things started to become interesting, and I start feeling good about ruby and bad about java alt=title=":-)" />

So, the first thing I decided to implement is a simple register/login system, quite common in nowadays web application. I used the restful_authentication plugin, which almost worked out of the box for me. Problems came from some changes between rails 1.2.3 and the latest 2.0.1, causing some apparent conflict in the routes.rb configuration file.

Then, I discovered a nice little application called iPhoney, to test the look&feel; of any web application as if the web client is the iphone one.

Here's the result:

iphoney
 

Now I'll go on with some more usefull business logic. 

December 17, 2007 12:26 PM

December 14, 2007

Valerio Schiavoni

Default face

how to add super-priviliged user to mysql

That's almost a note for my self:

GRANT ALL privileges ON . to 'username'@'localhost' identified by 'pwd' with grant option;

which will result in the user 'username' being able to perform full-privileged operations on the MySQL instance when connecting from localhost. Quick and dirty.

December 14, 2007 11:09 PM

December 12, 2007

Valerio Schiavoni

Default face

SoyLatte 1.0 is out (java6 freebsd for OSX)

Landon Fuller released SoyLatte 1.0!

I've been using the DeveloperPreview1~3 since day one, and it has demonstrated to be rock-solid.

This version (as the other released ones) still uses X11: sometime in the future this limitation should be removed. Anyway..go and get some latte!

December 12, 2007 10:05 PM

On (G)Rails

A while back I posted about a first pratical experience with RubyOnRails and Grails. At that time, I had no fully understand the key differences between the two's, although I faced them during the practical experience.

As alread stated, RoR builds up from the database schemas, while instaed Grails grounds up from the pojos being part of the model. RoR machinery is such as it can map a relational schema to a corresponding class, throught its builtin ORM, called ActiveRecord. The ActiveRecord pattern was previously described by Martin Fowler

Grails, on the other side, re-uses Hibernate to transparently map domain objects to corresponding relations. Hibernate strategy to map objects to relational tables is backed up by at least two other patterns, identity map and unit of work.

The two techniques, active records and identity/unit, have different advantages and disadvantages, of which I don't want to talk about.

Once again, however, I prefer to summarize the situation as a yet-another reincarnation of the dreaded object-relational impedence mismatch problem.

December 12, 2007 09:58 AM

December 11, 2007

Valerio Schiavoni

Default face

IBM released Harmony-based JDK 6.0

IBM has released an Harmony based JDK 6.0, for a bunch of platforms.

See more details: http://www-128.ibm.com/developerworks/java/jdk/ 

 

December 11, 2007 09:11 AM

December 09, 2007

Valerio Schiavoni

Default face

JUnit Introduction in 30 minutes: anyone?

I‘m searching for a 30-minutes long introduction to JUnit, for a public of CS students.

I still can‘t find a good one, so i‘m giving the blogosphere a chance: anyone has a nice and easy presentation that I can almost fully re-use ? 

December 09, 2007 04:34 PM

December 07, 2007

Orbeon

Default face

Orbeon Forms 3.6 Final Released

Orbeon Forms Logo

It is with great pleasure that we are announcing the final release of Orbeon Forms 3.6!

Orbeon Forms is an open source forms solution that handles the complexity of forms typical of the enterprise or government. It is delivered to standard web browsers thanks to XForms and Ajax technology, with no need for client-side software or plugins.

Orbeon Forms allows you to build fully interactive forms with features that include as-you-type validation, optional and repeated sections, always up-to-date error summaries, PDF output, full internationalization, and controls like auto-completion, tabs, dialogs, trees and menus.

Orbeon Forms 3.6 features over 170 improvements since Orbeon Forms 3.5.1, including major improvements in the areas of state handling, XML Schema validation, error handling, deployment within Java applications, and performance. The complete list of changes is available at:

http://www.orbeon.com/ops/doc/home-changes-36

The latest example applications are online at:

http://www.orbeon.com/ops/

You can get Orbeon Forms 3.6 from the download page:

http://www.orbeon.com/forms/download

The Orbeon team hopes you will enjoy this release!

December 07, 2007 05:10 PM

Christophe Hamerling

Default face

Going to JavaPolis 07

See you next week JavaPolis '07 on the OW2 Consortium booth to talk about and make some 'demos' of the PEtALS Enterprise Service Bus project.



December 07, 2007 09:50 AM

Valerio Schiavoni

Default face

Ruby Spin-up: Da dove viene quel metodo ?

This is an italian translation of the original Russ Olsen's article. You can read it from here: http://www.jroller.com/rolsen/entry/ruby_spin_up_where_did.

Russ is also the author of Design Patterns In Ruby.

I suspect this book will soon enter my xmas wish list alt=title=":-)" />


Come impariamo un un nuovo linguaggio di programmazione? Seguiamo un corso ? Compriamo un libro ? Semplicemente cominciando a scrivere qualche programma? Tutte queste cose aiuteranno  ( specialmente l'ultima ) ma se veramente vuoi sapere come gli esperti usano quel linguaggio, devi leggere un pò di codice. Non c'è niente di così utile come prendere un'applicazione ben scritta e cercare di capire come funziona per entrare nello spirito di un nuovo linguaggio.

Se state cercando di imparere Ruby leggendo un pò di codice, allora ho qualche buona e qualche cattiva notizia. La buona notizia è che Ruby è stato progettato per essere un linguaggio che sia facile per gli umani da leggere. Ruby è così flessibile che spesso puoi dire moltissimo in pochissimo codice, e questo generalmente rende programmi scritti in Ruby un piacere da leggere. La cattiva notizia è che Ruby è così flessibile che i principianti a volte lo trovano un pò difficoltoso per trovare la loro strada in applicazioni ragionevolmente complesse. In particolare, la natura flessibile di Ruby comporta che il codice che viene attualmente eseguito quando diciamo 'object.method' non è necessariamente dove vi aspettate di trovarlo.

Quindi, con lo spirito di aiutare i molti ad addentrarsi nel mio linguaggio favorito, vi mostrerò alcuni modi per capire come un certo nome di un metodo può essere 'agganciato' ad una specifica porzione di codice Ruby. Visto che si tratta di un argomento complesso, ho diviso il discorso in un paio di articoli: Questo coprirà le tecniche più basilari per collegare una porzione di codice Ruby ad una invocazione di metodo, mentre nel prossimo articolo ci addentreremo in tecniche più avanzate.

Partiamo ...

I SOLITI SOSPETTI: CLASSI E SUPER-CLASSI 

 Cominciamo dalla base delle basi: ogni oggetto Ruby ha una classe e una super-classe, e una super-duper-classe, e così via, vino ad arrivare ad Object, che sta da sola sulla testa dell'heap. Non sorprenderà nessuno sapere che quando Ruby cerca un metodo, comincia con la classe base, e risale la gerarchia dalla classe alla rispettiva classe padre, fino a quando non trova il metodo, o fino a quando sono finite le classi.

Ad esempio, per modellare una macchina:

 class Car
  def color
    "Boring blue"
  end

  def number_wheels
    4
  end
end

class SportsCar < Car
  def color
    "Sizzling red"
  end
end

my_car = SportsCar.new

 

Quello che vediamo nel codice qui sopra è una classe SportsCar, che è una sotto-classe di Car, che è by-default una sotto-classe di Object.

Invocate un metodo su un'istanza di SportsCar e otterrete ciò che vi aspettate: my_car.color restituirà un vivace color rosso. Dopo tutto, il metodo color è definito esattamente nella classe SportsCar. Allo stesso modo, se invocate my_car.number_weels, scoprirete che, per quanto strano sia il vostro giocattolo, avrà sempre quattro ruote.
Grazie alla magia dell'ereditarietà, Ruby scoprirà il metodo number_wheels nella classe Car dopo aver fallito nel cercarla direttamente su SportsCar.

Potete anche invocare to_s sull'istanza di SportsCar e Ruby vi restituirà qualcosa di questo tipo:
"#"
Il metodo to_s ci viene gentilmente dalla super-super classe, Object.

Infine, se invochiamo qualche metodo che non esiste, ad esempio my_car.foobar, vedremo un messaggio poco gentile che ci informa che non il metodo che cercavamo non esiste: Ruby ha risalito tutta la gerarchia di classi padri e si lamenta quando arriva fino alla cima senza trovare niente.

Quindi, se state leggendo del codice e vedete my_car.number_wheels, cominciate dall'ovvio: cercate il metodo number_wheels in SportsCar, poi in Car, e così via.

IL MODULE DIETRO LA CORTINA

Una volta capite le classi, le cose si fanno interessanti. Oltre alle classi standard e alle super classi, Ruby ha anche dei modules. Un module è un pò come una classe, e infatti possiamo definire le due cose con una sintassi praticamente identica:

module Convertible
  def top_down
    "Putting the top down"
  end

  def top_up
    "Putting the top up"
  end
end


ora, i modules possono sembrare come delle classi, ma non possono essere istanziati. Quello che possiamo fare con un modulo è includerlo in una classe:

class SportsCar < Car
  include Convertible

  def color
    "Sizzling red"
  end
end



L'effetto di includere un modulo in una classe è di inserire il modulo nella gerarchia di ereditarietà tra la classe e la sua classe padre. Quindi, se invochiamo top_down sull'istanza della nostra nuova classe SportsCar, Ruby cercherà prima tra i metodi della classe SportsCar (no, non c'è), e poi nel modulo Convertible (trovato!). Se invochiamo il metodo color, allora Ruby prima cerca in SportsCar (niente da fare), poi in Convertible (ritenta), e poi in Car (ah ha!).

La cosa bella dei moduli è che nonostante una classe possa avere solo una super classe, questa può includere un numero illimitato di moduli:

module NavigationSystem
  def location
    "39 53 N     75 15 W"
  end
end

class SportsCar < Car
  include Convertible
  include NavigationSystem

  def color
    "Sizzling red"
  end
end



La classe SportsCar ora include entrambi i moduli Convertible e NavigationSystem, così che sapremo esattamente dove saremo quando tireremo già la capotte della nostra macchina convertibile. Il fatto che i moduli vengano inseriti dentro la gerarchia delle classi giusto sopra la classe che li include ha alcune interessanti implicazioni. Primo, poichè un modulo agisce pià o meno come una super-classe, un modulo non può sovrascrivere (override) un metodo della classe che lo include. Ad esempio, immaginiamo di aver definito un metoodo location direttamente nella classe SportsCar, e che abbiamo anche incluso il modulo NavigationSystem:

class SportsCar < Car
  include Convertible
  include NavigationSystem

  # Stuff deleted ...

  def location
    "Right here"
  end
end


Con questo codice, se invochiamo location su un'istanza di Sportscar, ci troveremo sempre Right Here, il metodo definito nella classe vince sempre.

Secondo, non solo una classe può avere tanti moduli: anche la classe padre e i suoi parenti di livello superiore possono importare moduli. Ma tutto funziona come vi aspetterete: quando Ruby cerca un metodo, prima guarda nella classe, poi in tutti i moduli includi nella classe, poi nella sua super classe e poi in tutti i moduli della super-classe, e così via risalento la gerarchia di classi.

Terzo, se includiamo tanti moduli in una classe, i moduli vengono agganciati alla gerarchia delle classi in modo tale che l'ultimo ad essere incluso è il primo ad essere  usato durante la ricerca. Questo significa che quando invochiamo un metodo sull'oggetto sportscar, Ruby prima cerca in SporstCar, poi in NavigationSystem, e poi in Convertible, in quest'ordine. Generalmente l'ordine con cui vengono inseriti i moduli non è molto importante, ma se due moduli definiscono lo stesso metodo, solo quello definito nell'ultimo modulo incluso avrà la meglio.

Quindi se state cercando di capire come funziona una certa applicazione e non riuscite proprio a trovare il metodo location in nessuna delle classi, cominciate a guardare nei moduli includi dalle classi.

METODI SINGLETON: IL MISTERIOSO STRANIERO

E se il metodo non sta nemmeno in nessuno dei moduli ? Beh, potrebbe essere completamente solitario. Praticamente, Ruby permette di definire metodi singleton (ma non c'è alcun rapporto col design pattern omonimo). Un metodo singleton è un metodo che viene definito direttamente su un oggetto, indipendentemente dalla sua classe o moduli.

Ho insegnato Ruby ad un bel numero di programmatori Java con esperienza, e generalmente la loro reazione iniziale ai metodi singleton varia dal buon vecchio texano "That just ain't right" , fino ad arrivare alla nausea.
Ma dopo che le campane nelle orecchie smettono di suonare, si scopre che essere in grado di customizzare un singolo oggetto senza preoccuparsi di cosa faccia il resto della classe è qualcosa di estremamente utile. Pensate a tutti i casi che avete incontrato nella vostra vita di programmatori, quelli che quasi quasi rientrano in una certa classe, ma non proprio (insomma, il cane con 3 zampe o la macchina volante..). Ecco, i metodi singleton sono fatti per queste situazioni.

Ci sono un paio di modi per appiccicare un metodo singleton ad un oggetto. ad esempio, se volete installare un impianto audio, uno solo, specifico, sulla vostra macchina, si può usare questa notazione a livello di classe:

my_car = SportsCar.new

class << my_car
  def custom_sound_system
    "... BYYYYING A STAIIIIRWAY to heaVennnnnnn"
  end
end



In alternativa, possiamo sistemare il nostri impianto audio semplicemente definendo il metodo direttamente sull'oggetto:

my_car = SportsCar.new

def my_car.custom_sound_system
  "... BYYYYING A STAIIIIRWAY to heaVennnnnnn"
end


In entrambi i casi, finirete con l'oggetto my_car che sarà uguale in tutto e per tutto dalle altre sports car, se non per un metodo in più.

E come funziona tutto ciò ? Molto semplice: ogni oggetto ha una sorta di di classe di supporto (detta 'stealh' o singleton) che sta tra l'oggetto e la classe normale. Quando viene definito un metodo singleton sull'oggetto, il metodo va a finire direttamente nella classe fantasma. La classe fantasma è una vera e propria classe, e come tutte le altre classi può includere moduli. Quindi, un modo per personalizzare la macchina potrebbe essere :

CoolExhaust

module CoolExhaust
  def rev_engine
    "VAROOOOOOOOOOOOM"
  end

  def monthly_disturbing_the_peace_fines
    279
  end
end

my_car = SportsCar.new

class << my_car
  include CoolExhaust
end



In questo modo, my_car, e solo questa, avrà un nuovo impianto fiammante.
La classe singleton è un pò come un modulo: un modulo risiede tra una classe e la sua super classe, mentre la classe singleton risiede tra un istanza e la sua classe. Quando Ruby parte alla caccia di un metodo,prima di tutto consulta la classe singleton "prima" della classe base, prima dei moduli, e sicuramente prima di qualsiasi super-classe.

Quindi, per riassumere le nostre avventure fino ad ora, abbiamo scoperto che ogni oggetto istanza ha una classe singleton unica per quell'oggetto. Quando Ruby cerca un metodo su un oggetto, prima consulta la classe singleton (e i suoi moduli). Se il metodo non è presente sulla classe singleton, Ruby comincia a cercare sulla classe base e i suoi moduli. Se Ruby continua a non trovare niente, la ricerca continua sulla super-classe, ripetendo lo stesso procedimento di ricerca classe-e-poi-modulo.
Ovviamente, se il metodo proprio non viene trovato, Ruby tirerà un'eccezione......Beh, non proprio.
Ciò che succede quando viene invocato metodo  non esistente è di per se un argomento molto interessante, ma che verrà trattato nel prossimo articolo.
 


December 07, 2007 09:03 AM

December 05, 2007

Orbeon

Default face

Great success of the XForms Evening at the XML 2007 conference

John Boyer introducing the XForms Evening

We had great success with the XForms Evening a the XML 2007 conference on Monday. We were wondering if people would really want to attend sessions that late in the evening (from 7:30 to 9:00 PM), but the attendance beat our expectations, with easily over 60 people cramped in the allocated room and some actually standing.

The initial feedback we are getting is excellent. I believe that the format of the sessions was one of the reasons for this: it consisted in having a one and a half hour session on a specific topic (XForms) but split into a series of very short 15-minute presentations by different speakers. This made it almost impossible to bore the audience, and also constrained the speakers to be concise and to the point. So kudos to the organizers, in particular to our working group chair, John Boyer, for making this happen.

The main point of my presentation was that with XForms and eXist, you don’t need a middle tier for a wide category of applications: XForms can directly talk to the persistence layer, in this case eXist, with xforms:submission and REST, while providing all the CRUD and search operations (through XQuery). This point resonated with other speakers’ point of view as well.

Elliotte Rusty Harold ended the evening with an excellently delivered but provocative keynote about what XForms proponents need to do to ensure the sucess of XForms. At Orbeon, we disagree with Elliotte’s contention that it is necessary to bring XForms natively to the web browser:

You can read the Forms Working Group’s short debriefing in our meeting notes for today, and the slides of my talk are available on slideshare.

December 05, 2007 02:52 PM

Christophe Hamerling

Default face

PEtALS Standalone 1.4.3

PEtALS Standalone platform 1.4.3 is out. This is a maintenance release.
Look at the release notes for more details.

December 05, 2007 11:40 AM

December 04, 2007

Christophe Hamerling

Default face

CIMERO2 Editor for PEtALS ESB

The CIMERO2 editor is an Eclipse plugin originally developed by Bull. This plugin provides features to create a visual representation of your Enterprise Service Bus based architecture. After the design step, the plugin offers the possibility to generate the JBI artifacts (Service Assemblies), and the Ant deployment scripts which will be used to deploy the configuration on the ESB.

We, at eBM WebSourcing, are currently working on better integration of the PEtALS JBI components. You can find a Flash demonstration on how we you can use this plugin on the PEtALS project website demonstration page.

Finally, it is good to notice that this plugin is currently under integration into the Eclipse SOA Tools Platform project (Eclipse STP).



December 04, 2007 10:30 PM

December 03, 2007

Valerio Schiavoni

Default face

expected: < 1 > but was: < 1 >


Today I got confused when a test of mines failed with the following message:

junit.framework.AssertionFailedError: expected:<1> but was:<1>

Wait a minute…. 1…1…i don‘t see the difference ! The code is as simple as:

assertEquals(1, this.protocol.getProcId());

 
guess what, getProcId() returns a String: this was not the case after a refactoring, but the generic-unaware code of JUnit didn't help me discovering such problem. I'd like to see some improvements in JUnit: a clearer message error would already be a nice thing.

December 03, 2007 02:30 PM

December 01, 2007

Orbeon

Default face

Reminder: XForms Evening in Boston this Monday

XML 2007 logo

As a reminder, there will be a free XForms Evening this Monday at the XML 2007 conference in Boston, and I will be presenting a talk about XForms and eXist. There are several great speakers scheduled and this is a great opportunity to learn about XForms, so don’t miss it! I hope to see you there!

See also our previous blog entry on the topic for all the details.

December 01, 2007 03:10 PM

November 29, 2007

Orbeon

Default face

Bad form

E*TRADE Logo

Yesterday, I was filling-out an application form on the E*TRADE web site.

So here I go, entering my information in a traditional wizard-like workflow, with page reloads et al. When I get to the end of it (about six or seven pages total), I figure I would check if I could amend my mailing address on page two. So I carefully press the “Previous” button of the wizard, until I reach the page. So far so good, my information is still there (even though it turns out I can’t change this particular bit). This is the beginning of the trouble:

Now you can easily imagine how the software got to be so buggy: written with software tools not particularly designed to handle forms, developers had to write by hand things such as “when the user goes to page two from page three, restore such and such information from the session”. Somebody forgot to write the code that restores a particular piece of data, and lousy QA missed it. (Needless to say, there were not many usability tests on this wizard either.)

Now imagine the next version of this form if E*TRADE developers decide to use XForms and Orbeon Forms instead:

And of course, users are much happier because they enter their information once, not three times.

November 29, 2007 02:00 PM

Stéphane Traumat

Une super source d'informations sur Java

J'ai découvert il y a quelques jours ce site :
http://www.parleys.com/display/PARLEYS/Home
C'est un site est assez fantastique pour les passionnés de Java. A voir :)

November 29, 2007 10:30 AM

Christophe Hamerling

Default face

Installing SVN Client on Mac OSX

I am happy to see that Fink (http://finkproject.org/) is no more needed to easily install a Subversion client on Mac OSX. A client has been packaged by this guy Martin Ott (http://homepage.mac.com/martinott/).
Installation done by clicking on the package...

I am also happy to see that there is a Subversion GUI client for OSX. Working with terminal is cool but sometimes clicking on the mouse is not so bad...
You can found this client on 'La chose interactive' website (http://www.lachoseinteractive.net/fr/communaute/subversion/).

Configuration seems very intuitive... Going to test it for PEtALS project...

November 29, 2007 10:10 AM

November 27, 2007

Stéphane Traumat

Une petite introduction à Amazon S3

Amazon Simple Store Service (S3) est un service qui permet de stocker et de récupérer des fichiers sur les serveurs d'Amazon et d'être facturé à l'utilisation (facturation sur le stockage et le transfert). L'intérêt réside dans le fait d'avoir accès à une source illimité d'espace disque accessible depuis Internet.
Voici une petite introduction à son utilisation :
http://www.onjava.com/pub/a/onjava/2007/11/07/introduction-to-amazon-s3-with-java-and-rest.html
J'espère m'y pencher dans peu de temps ! Pour développer des applications "dans les nuages"

November 27, 2007 10:20 AM

November 26, 2007

Orbeon

Default face

Orbeon Forms 3.6.0 RC1

We have just posted a release candidate for Orbeon Forms 3.6. Orbeon Forms 3.6 now contains over 170 improvements over Orbeon Forms 3.5.1.

The idea behind the release candidate is to see if anything is obviously broken before we release 3.6 final. It does not mean that Orbeon Forms is bug-free, mind you there are lots of known issues and requests for enhancements in Orbeon Forms.

If you have a chance, please give this build a try and send feedback to the ops-users mailing-list!

November 26, 2007 11:39 PM

Stéphane Traumat

De retour du Vietnam

Me voila de retour du Vietnam où j'ai participé au programme Foss Bridge ( http://foss-bridge.org/ ) qui a pour but de faire collaborer ensemble des entreprises Européennes et Vietnamiennes. C'était très sympa, on a vraiment rencontré un tas de gens intéressants. Par contre, force est de constater que nos partenaires vietnamiens ont quand même du mal à croire que l'on puisse gagner de l'argent en "produisant" de l'Open Source.... mais bon, ça va venir :) En tout vas, on a rencontré un paquet de gens motivés
Les photos sont là :
http://www.flickr.com/search/?q=fossbridge2007&m;=text

November 26, 2007 04:40 PM

November 24, 2007

Pierre-Yves Gibello

Default face

La grève et le noeud coulant

Enseignant l'informatique à des élèves ingénieurs grenoblois, j'ai eu récemment l'occasion de m'entretenir avec le piquet de grève qui bloquait l'accès à mes salles de TP.

Je leur ai tenu le raisonnement suivant : face au blocage, nous réagissons en le contournant. Pour ma part, j'ai pu me procurer une autre salle, mais sans moyen informatique. Moindre mal : la plupart de mes étudiants étant équipés de portables, ils effectuent leur TP sur leur ordinateur personnel...

Mais certains étudiants ne disposent pas d'ordinateur portable : évidemment, ce sont les plus défavorisés !

La grève, lorsqu'elle s'éternise, tend alors à renforcer un système inégalitaire, une société à deux vitesses : parce qu'on ne va pas tous ralentir uniquement pour se plier au bon vouloir d'une minorité d'activistes, on laisse des gens au bord de la route !

Pour généraliser ce constat, prenons une image simple.
Imaginez que vous soyez entravé par un noeud coulant : en procédant avec clairvoyance, détermination et précision, vous vous libèrerez facilement. Mais si vous vous débattez, vous ne ferez que resserrer l'étreinte !

Cette image est transposable à la grève : une grève est efficace si elle est très suivie, ciblée, et courte.
A contrario, un mouvement long, sans revendication précise ni organisation efficace, produit des effets contraires au but recherché. Et c'est une spécialité française !

Ne pourrait-on trouver là une explication paradoxale au fait que notre économie soit l'une des plus productives au monde ?
Nous sommes un pays de grévistes, spécialistes du mouvement larvé et imprécis.
Conséquence, l'économie s'est adaptée : nous avons automatisé, décentralisé, développé des réseaux parallèles, et sacrifié les activités sensibles à la grève ou à faible valeur ajoutée... au point d'atteindre un degré de performance que même les américains nous envient !

Cette évolution s'est faite au prix d'un accroissement des inégalités - lorsqu'on s'adapte pour contourner, les moins flexibles ou les moins formés restent au bord de la route - et d'une réduction du nombre d'emplois disponibles (ceux-ci devenant, en même temps, plus qualifiés).

Comme dans l'image du noeud coulant, nos syndicats peu représentatifs et désorganisés qui se débattent au lieu d'agir de manière efficace contribuent à resserrer l'étreinte du système sur les travailleurs... au grand profit du patronat, qui crie au loup mais doit au fond se réjouir !

November 24, 2007 01:45 PM

November 23, 2007

Valerio Schiavoni

Default face

SoyLatte: BSD based Java6 Port RC2

It's now avaiable:

http://landonf.bikemonkey.org/code/macosx/MacOS_BSD_Java_Developer_Preview_2.20071122.html

read the official announcement and details to get a copy ! 

The name is very cool, I think! 

November 23, 2007 08:44 AM

November 20, 2007

Orbeon

Default face

Firefox doesn’t get events right, especially on the Mac

When a form field is loosing the focus, the browser is supposed to send two events: blur and change. The latter is only sent if the you have changed the value of the field. When you change the value of a first field and tab to a second field, all the browsers get the events right. But if you change the value of a first field, alt-tab to another application, alt-tab back to the browser, and tab to the second field, then different browsers implement different behaviors:

If you are using XForms to define your forms and running them through Orbeon Forms you won’t have to deal with any of this. Orbeon Forms will do the hard work for you. Lucky you! ;)

November 20, 2007 06:04 PM

Valerio Schiavoni

Default face

Open Source JDK 6.0 DP for Mac OSX

Read the  the official announcement: 

http://landonf.bikemonkey.org/code/macosx/MacOS_Java_16_Developer_Preview_1.20071120.html 

This work is based on the the BSD family working ports.

November 20, 2007 09:24 AM

November 19, 2007

Orbeon

Default face

Getting closer to Orbeon Forms 3.6

Over the last two weeks, we fixed a series of bugs that we considered blockers for Orbeon Forms 3.6:

We have one remaining JavaScript bug which we consider a blocker, and then we should be able to officially proceed to an RC build!

November 19, 2007 10:30 PM

Valerio Schiavoni

Default face

My first Android (dumb) application: Andropad

I've always been tempted by mobile development, but for a reason or another I was not really enough motivated to jump into it and give it a try. 

Now that Android is out, with a very nice Eclipse plugin that works like a charm out of the box, I couldn't resist any longer.

So, just after few clicks I was able to run my  very first application..which does nothing if not printing "Hello World".

This is how the emulator looks in Eclipse and Mac OSX.

That's NICE !

(see a bigger one here: http://farm3.static.flickr.com/2073/2048533008_107977debb_o.jpg)

Now..it's time to think about some nice application.

November 19, 2007 10:01 PM

November 16, 2007

Valerio Schiavoni

Default face

(Minor) Java update on Mac OSX 10.4 Tiger

Apple has released a minor update for Java on Mac OSX 10.4, distributed through http://connect.apple.com (you must have an Apple Developer ID to login).

The update updates Java 5.0 to internal versions 1.5.0_13 (from a previously released 1.5.0_07-87).
At the same time, Java 1.4 has being updated to internal version number 1.4.2_16.

Also note that if you've previously installed Java SE 6.0 Developer Preview, some problems might arise.


November 16, 2007 11:42 AM

Ludovic Dubost

Article sur XWiki aux US

Notre voyage aux USA nous a permit d’avoir un journaliste lors d’une de nos présentations. Cet article vient d’être publié.

Il y a une remarque intéressante de TerraCotta a la fin sur les investissements faits sur un logiciel concurrent qui rend difficile le switch.

Lors ...

November 16, 2007 07:52 AM

November 15, 2007

Valerio Schiavoni

Default face

Google Dalvik: origins ?

Google's mobile platform Android platform has been launched, and I got interested about the runtime environment. After Stefano's article,
i wanted to know more about the Dalvik virtual machine.

So, out of curiosity, I found that:

  1. Dalvik is a small town in Iceland, founded in 1998 (same as Google Inc.)
  2. the logo of the city shows mountains (Mountain View...)
Only coincidences..or not ? alt=title=":-)" />

November 15, 2007 06:24 PM

Jérome Molière

Default face

I love SWT!!!!!

Hi all,<br />this is a small comment about this wonderful technology : SWT. While working on a huge project in Switzerland using Eclipse/RCP as the basis for GUI building, it 's for me an opportunity to use SWT/JFace once again (did'nt play with them for 3 or 4 years).<br />In the same time, it's an opportunity to play with recent Eclipse versions (3.2.2).<br />My first feelings are not very positive:<br />* Eclipse is totally unstable, one small plugin can break your pretty configuration<br />* SWT has many limitations and many bugs<br /> we are still unable to open applets within a browser from an RCP application using the SWT browser widget<br /> playing with the sexy version of the old Runtime.exec() method called Program class in SWT, in found ridiculous behaviors:<br />don't handle arguments on the command line properly<br />can't find one binary Program.find("iexplore.exe") doesn't return on my machine (may be a little strange I agree)<br /><br />SWT basic widgets are still very low level while JFace (layer bringing a little bit of abstraction and a MVC based design) is still too small (not many widgets available).<br />SWt events are still mysterious for me andd the documentation is still too weak...-(<br /><br />I 'm still disapointed with this project so sexy but which doesn't work at the end...<br />I'm using netbeans or vi depending from the amount of code to be done and I'm still convinced that they are far more efficient tools than Eclipse...<br />(netBeans 6.0 is quite ready and it's full of nice features)<br /><br />See you soon on the JavaSphere

November 15, 2007 12:12 PM

November 14, 2007

Valerio Schiavoni

Default face

Remote multi-touch screen (Minority Report style)

This guy is a genious:

http://www.youtube.com/watch?v=0awjPUkBXOU

November 14, 2007 02:28 PM

Rome JavaDay 2007

The Rome JavaDay 2007, 2nd Edition is only 3 weeks far, and the official website is up and running.

You can reach at : 

 http://roma.javaday.it/roma/

 
If you're in Rome the 1st of December, consider attending one or more presentations. Partecipation is Free!

javaday 2007 logo 

November 14, 2007 11:36 AM

My Grails Swiss Knife

I finally have  my Grails swiss knife ready:

The rest is already bundled with Grails itself, in all its groovy fashion.

Now I can definetly forget about Ant, which is a good thing, IMHO.

November 14, 2007 12:29 AM

November 12, 2007

Valerio Schiavoni

Default face

The KISS principle

Today, Alessio tought me a nice new acronym: the KISS principle:

Keep It Simple, Stupid !

a good reminder for anyone in the coding jungle :-)

November 12, 2007 09:21 AM

November 05, 2007

Stéphane Traumat

Une super idée d'entreprise !

Et voilà une super idée : https://www.microplace.com
Le concept est vraiment simple, il part du principe qu'avec 100 €, on fait pas grand chose en occident mais qu'on fait beaucoup dans d'autres parties du monde. C'est le micro crédit, on prête un tout petit peu d'argent à des gens qui vont monter des petites sociétés et à qui on ne prête pas d'argent normalement. Avec moins de 100 €, ils vont pouvoir se batir une vie et rembourser ce prêt (avec des intérêts).
Avec microplace, vous pouvez prêter votre argent et on vous rembourse cet argent avec des intérêts ! Il s'agit donc plus d'un placement (3% de rendement je crois) que de charité. Avec ce genre de principe, tout le monde gagne, les prêteurs et les acheteurs et tout cela se passe avec une facilité déconcertante.
C'est juste dommage que microplace ne soit pour l'instant ouvert qu'aux personnes rédisantes aux états unis.

November 05, 2007 10:34 AM

November 04, 2007

Valerio Schiavoni

Default face

Leopard and 13949712720901ForOSX initiative

The debate around Java6 support in Leopard is really hot these days. A nice initiative I want to support is being promoted by  Henry Story (read this if you want to know more).

So, for every javaDev-onMac out there: put the string:

13949712720901ForOSX

on any of your blogs, homepage, IM, twitter, and so on..that's an easy way to let our voices reach Cupertino's puppet masters.


November 04, 2007 05:36 PM

November 02, 2007

Valerio Schiavoni

Default face

Google OpenSocial API

Here is the Google Code page for the OpenSocial APIs:

http://code.google.com/apis/opensocial

November 02, 2007 10:32 AM

Orbeon

Default face

Browser back button handling improvements

Navigation Buttons

A really cool thing about Orbeon Forms is that it automatically handles your browser’s back and forward buttons.

What are we talking about here? Browser back and forward buttons should just work, right? Well, not quite, at least not with web applications that dynamically modify the HTML page.

What happens when you navigate back and forth in your browser history (typically with back and forward buttons) is that the browser attempts to reload the page (if possible from a local cache, following the usual HTTP caching mechanisms). It also restores form field values. But one thing it doesn’t do all the time is restore the DOM as it was when you left the page. Opera, Firefox and Safari attempt to handle this in some cases, but not all. IE doesn’t even try. This means you can’t trust browsers to do the right thing.

Changes to the DOM happen very often with Orbeon Forms: when you make a field invalid, hide or show parts of the page, insert new rows of data, show a dialog, etc.

So Orbeon Forms tries to be smart: when you navigate the browser history to an Orbeon Forms page, if the browser doesn’t restore the DOM itself, Orbeon Forms discretely talks to the Ajax server to ask it to send back a list of changes which, when applied to the page, would restore its appearance as you last saw it.

A nice thing is that we can do this at little cost because, as part of the regular XForms processing, we already:

The news is that we made some enhancements to this feature:

As a side note, this should finally allow us to implement <xforms:reset> correctly.

November 02, 2007 01:00 AM

November 01, 2007

Jean-Pierre Lorré

Default face

I am very please that a new project call SEMEUSE (SEMantiquE pour BUS de sErvice) has been selected by the French ANR/RNTL research body for funding. This project deals mainly with study and development of a Semantic Entreprise Service Bus. EBM WebSourcing is one of the consortium's members among others big names which are: Thales, France Telecom, Lip6, INSA Lyon, INRIA (Arles and ObjectWeb) and INT.

The SEMEUSE project specifically aims to provide a context-aware semantic service architecture addressing both the design phase, thanks to theoretical context-aware semantic service models and policy-oriented design patterns, and the runtime phase, thanks to a Dynamic Semantic Service Bus (see below figure). This extended service bus is based on a static and dynamic service composition engine so that the current execution context and particular requirements (related for example to nomadic constraints) can be continuously taken into account. A dynamic monitoring system, using CompositeProbes, will also be connected to the orchestration process so that QoS aware late binding can be implemented.

The main objectives of SEMEUSE are then to:


To meet the target objectives in the project timeframe of 30 months, the SEMEUSE consortium groups complementary competencies, from both academia and industry, bringing together experts in all the areas of relevance, namely middleware development, SOA, ESB, semantic service technologies, SLA management, security policies organisation…

The open-source oriented implementation strategy is further reinforced by the expertise of most of the members of the consortium acting as leaders in the field in particular inside the OW2 (http://www.ow2.org) open-source consortium dedicated to middleware.

Organised in an iterative way (first specifications phase, validation phase, final specification) the work will be organised as follows:

  • A reference architecture (including both the theoretical design level and the operational ESB platform) provides the necessary integration dimension.
  • A semantic description work-package support the “static” semantic context-aware service description (including functional and non functional requirements) and the way service are stored, discovered and selected.
  • A monitoring and orchestration work-package support the dynamic part of the system, i.e. the way monitoring functions are added in a classical ESB to capture the current execution context, the way this execution context is used to select and orchestrate services…
  • The necessary tooling functions (design and monitoring tools as well as design by community tools) are developed in a separate work package

  • Use cases are used to improve requirements definition and to validate the global architecture.

This project will use the OW2 PEtALS (http://petals.objectweb.org) Enterprise Service Bus and contribute to pave the way for next generation ESB.




November 01, 2007 10:23 PM

October 30, 2007

Stéphane Traumat

Une solution pour calendrier partagé & mobiles

Dans la société, nous avons des téléphones portables / PDA (Treo 680) sur lesquels nous rentrons nos agendas. Le problème, c'est qu'on avait besoin de les partager pour savoir ce que chacun faisait et pour faire des invitations à des réunions. Partir sur une solution de type exchange nous paraissait un peu débile et très honéreux. Alors on a trouvé une solution super simple et qui coûté 0 € :)
Il s'agit de Goosync ( http://www.goosync.com/ ) qui permet de sychroniser directement son PDA avec Google Calendar et en plus, c'est gratuit !
Donc nous avons toutes les fonctionnalités des agendas partagés (invitation, visualisation des autres...) et une synchronisation simple via internet entre le PDA et Google Calendar. C'est vraiment un service extraordinaire :)

October 30, 2007 09:11 AM

October 29, 2007

Orbeon

Default face

A disk-based XForms state store for Orbeon Forms

Rotor

We just committed changes in Orbeon Forms to handle a disk-based XForms state store. What is this about? As discussed recently, Orbeon Forms needs to store XForms state information somewhere. One option is client-side, but this has drawbacks in terms of bandwidth and latency. So the default since the beginning has been to store state on the server.

Until this last round of changes, Orbeon Forms would keep some of the information in a session LRU memory store and then discard it completely. You had to discard information, because RAM is limited. But this approach has proven problematic because, however good the expiration heuristic, in many cases the state information would be lost completely, leaving the user in the dust. This includes cases such as the user going back to a page after a while, or accessing multiple large pages within a same session.

So we had to fix this, and you can say welcome to the brand new disk-based session store! With this mechanism, state information which expires from RAM is instead migrated to a disk store. Since disk is cheaper than RAM (you can maybe allocate a few tens of MB of state store in RAM, but probably several GB of state store on disk, at least two orders of magnitude more), memory is no longer really a constraint. (This can work because disk access is expected to be rare, following the principle of locality of access, which is central to all caching systems.)

Besides making the user experience better, we hope that this larger and more reliable store will enable Orbeon forms to support very cool features soon, including built-in undo and history checkpoints in forms. This should take Orbeon Forms where few Ajax platforms have already been.

Even with a disk-based store, you need to expire data otherwise it will grow indefinitely. In this first iteration of the store, we implement a fairly simple expiration stategy: stuff expires from the database when the user session is terminated. This is not perfect, but will cover a large number of uses cases.

Technically, we have made a fairly bold step and decided to use the embedded eXist database, included with Orbeon Forms, as the persistence layer for XForms state information. One reason is that we did not want to deal with writing our own persistence layer. Another reason is that this will give us the power of XQuery to implement expiration strategies in the future.

This feature is now available in the Orbeon 3.6 beta nightly builds, and will be enabled by default in Orbeon Forms 3.6.

October 29, 2007 02:26 PM

October 28, 2007

Valerio Schiavoni

Default face

How to load all classes in a Jar file ?

I've been searching for quite sometime now an easy mean to have access to all .class in a specified JAR file. This problem, despite simple to state, is anything but easy to solve cleanly and simply.

I've found an old article about this subject, back from '99 on JavaWorld (you can see it there:  http://www.javaworld.com/javaworld/javatips/jw-javatip70.html ).

Despite the fact that I had to change some piece of that code (because of some naming issue when defining the the class in the current class loader), this solution presents a further problem I still had no time to investigate (a LinkageError  which looks really bad).

So, before losing my time with that JW code, I wonder the community: are you aware of any open-source library which basically exposes a method that looks like (or that can be adapted to):

public Class[] loadAllClassesIn(String jarFileName);

 Any pointer is very appreciated.

October 28, 2007 10:50 PM

October 26, 2007

Valerio Schiavoni

Default face

Leopard..without Mustang

Leopard is out, and quite sadly it's been confirmed that Java6 is not part of it. 

It's really a shame, as this is a blocking factor for me to think about an OS upgrade. Being a java developer and not having the chance to use the latest and finest java technology is really a shame.

So, for now 129$ stay in my pocket...let's see if Uncle Steve finally will unleash the Mustang..They did so for Tiger (mac osx 10.4), after approximately one week after the release date of the operative system.

October 26, 2007 11:31 PM

Ludovic Dubost

XWiki Tech Talk a Google

En Californie, ou nous étions avec Vincent, nous avons eu l’occasion de faire un Tech Talk sur XWiki chez Google.

Au passage ce tech talk est une très bonne présentation d’XWiki et de ce qu’on peut faire avec.

October 26, 2007 08:30 PM

October 25, 2007

Valerio Schiavoni

Default face

Q for Maven

A new eclipse maven plugin is under development, apparently since some time now. 

You can see it here http://code.google.com/p/q4e/ 

The good news is that it is being sponsored by DevZuz, the company also behind Maven. Also, among the other goals, is a complete integration in Eclipse, and a future release might actually being shipped togheter with the IDE.

Fingers crossed.

October 25, 2007 12:27 PM

Mac OSX & Java6 Developer Preview

From this link  it is possible to download a DMG installation file for Java6SE Developer Preview.

Get it until the server is up...

For official news..let's wait more or less 24 hours, maybe Leopard will drink some coffee as well. 

October 25, 2007 12:11 PM

October 20, 2007

Valerio Schiavoni

Default face

GMail grows to 4 GB

In case you haven't noticed (I had not until now..), GMail is now offering 4 GB of emails :-)

That's good, and just in time !

October 20, 2007 08:50 PM

October 17, 2007

Orbeon

Default face

XForms evening at XML 2007

XML 2007 logo

We will speak at the XForms evening that will take place alongside the XML 2007 Conference in Boston (3-5 December 2007). The XForms evening will take place on Monday, December 3 and will feature seven 15-minute talks (we want to make sure you won’t get bored). Our talk will be about XForms and eXist:

XForms and the eXist XML database: a perfect couple

XForms speaks XML natively, and so does the open source eXist XML database. In this talk, we show how they form a particularly attractive combination.

In particular, we show how the XForms 1.1 submission module, which supports REST, can be used to perform CRUD operations in eXist. We also look at how XForms can directly submit XML database queries using the powerful XQuery 1.0 language implemented by eXist. The result is an architecture where complete applications can be developed with an XForms processor and the eXist database, while relying entirely on open standards.

We conclude the presentation with live demonstrations of the XForms + eXist combination built using open source software.

We hope to see your there!

October 17, 2007 03:49 PM

October 16, 2007

Stéphane Traumat

Tester la visibilité de son site

Voici un site pour tester rapidement si son site est bien référencé et s'il est bien référençable : http://www.websitegrader.com/#ReportTop
Bon, on obtient un score pas trop mauvais mais pas super non plus... il y a encore du travail

October 16, 2007 09:18 AM

October 13, 2007

Valerio Schiavoni

Default face

Fork/Join framework, java7.0, seminal paper

The next release of Java (codename Dolphine) should include a brand new fork/join framework for highly parallel software.


This paper presents the design and shows further details of it. The author, Prof. Doug Lea, is also the one behind the design and implementation of the java.util.concurrent package.


 

October 13, 2007 04:46 PM

Ludovic Dubost

Dernier jour en Californie

Quelques heures avant le retour en France, je suis en train de configurer mon nouveau Mac !! Et oui je suis enfin passe sur Mac !

Voici quelques photos de notre voyage en Californie:

http://www.facebook.com/album.php?aid=25531&id;=707151351

Vous ...

October 13, 2007 08:10 AM

October 11, 2007

Ludovic Dubost

Articles sur notre XWiki Meetup en Californie

Voici deux articles sympas sur notre XWiki Meetup en Californie:

October 11, 2007 05:20 PM

Orbeon

Default face

Professional XML, The Book

I had a chance to work with a great team on the new edition of Professional XML. This is a completely new edition; everything is fresh and has be written from the ground up. The book covers almost all the XML-related technologies you can think of: XSLT, XPath, XML Schema, Relax NG, XSL-FO, XHTML, XQuery, Ajax, RSS, Atom, Web services, and many others.

For the XPath chapter, instead of writing a 30-page overview of XPath, I decided to take a different approach: looking at a number of specific features of XPath that are both very useful in practice, and somehow lesser known or not obvious. I have already alluded to some in this very blog:

Grab a copy of the book, and you will find more about XPath, and of course much more about a number of other XML technologies. I hope you will enjoy it!

October 11, 2007 04:52 PM

Stéphane Traumat

L'outsourcing est mort ?

Voici un article intéressant sur l'offshoring où la personne explique qu'aller chercher les coûts les plus faibles dans des pays plus pauvre n'est plus une bonne stratégie. Il a quelques bons arguments qui font que cet article vaut la peine d'être lu :
http://blog.assembla.com/assemblablog/tabid/12618/bid/2453/Offshoring-Is-Dead-How-to-Thrive-in-the-New-World-Order.aspx
Il a raison sur beaucoup de points comme l'inflation dans ces pays, les coûts cachés, la modération des salaires dans nos économies, le turn over.... par contre, nous on a un euro fort :) Je me pose de plus en plus la question de l'outsourcing et c'est normal quand on gère une société de se pencher sur la réduction des coûts. Cet article va m'aider un peu plus à prendre certaines décisions...

October 11, 2007 08:33 AM

October 10, 2007

Valerio Schiavoni

Default face

Access a WebService in Groovy

Accessing a web service with some very neat and simple groovy code is a as simple as the following:

import groovy.net.soap.SoapClient

def proxy = new SoapClient(wsdl
proxy.print()

I find this amazing :-) 

October 10, 2007 07:57 PM

Code Expressiveness

When it comes to code-expressiveness, that is the ability to communicate with code your intent, I'm usually fooled about exotic choices. 

 For instance, consider the following, code, used  to obtain a Factory object:

Factory factory = FactoryFactory.getFactory();


I really believe that a much clear way is the following:

Factory factory = Get.factory();

What do you think ?


 

October 10, 2007 07:51 PM

Fractal, Ohloh, and the badge

A nice badge to be included in the blog pages of every Fractal developer : 

<script type="text/javascript" src="http://www.ohloh.net/projects/8043/widgets/project_partner_badge"></script>

 

 

October 10, 2007 05:08 PM

Ludovic Dubost

IPod Touchchche

Pas d’iPod chez Apple, mais on a pu se rattraper chez Fry’s. Me voici maintenant propriétaire d’un iPod Touch 16Go.

L’iPod Touch est presque un iPhone sans le téléphone et malheureusement sans la Caméra. C’est la caméra qui me manque le plus. L’iPod Touch a aussi quelques applications en moins.

J’hésite pour l’iPhone mais sa non-hackabilité actuelle en fait ...

October 10, 2007 03:50 AM

Google Summer of Code Mentor Summit

Super journée chez Google pour le Mentor Summit. Plus de 100 personnes étaient présentes pour échanger sur le Google Summer of Code.

Nous avons pu rencontrer d’autres membres de projets Open Source et échanger. Nous avons pu aussi rencontrer quelques Neo-Zelandais (ha ha) !

October 10, 2007 03:50 AM

October 09, 2007

Ludovic Dubost

Une présentation XWiki avec Google Present

Voici une petite présentation XWiki avec Google Present

Je n’ai pas J’ai trouvé le moyen ...

October 09, 2007 01:50 AM

October 06, 2007

Jeff Mesnil

Default face

Adam Bosworth is back on the web

Cool: Adam Bosworth is blogging again.
I thought it was a shame he stopped talking when he was hired by Google because a few people could not make the difference between his own opinion and the company he was working for.

Now that he has left Google and created a new startup, I’m looking forward to reading what he is up to….

October 06, 2007 06:30 PM

October 05, 2007

Ludovic Dubost

Silicon Valley day 1: Apple out of stock

Le séjour commence bien. Pas de machine a films dans l’avion d’Air France (mais à la place une top super mega navet - Fantastic Four numéro 2, pire que le premier), plus d’iPod Touch à l’Apple Store de Palo Alto et tous les iPhones sont en firmware 1.1.1 non activables..

Snif...

Sinon on se rattrape sur les glaces avec le Wifi de l’Apple Store sur University ...

October 05, 2007 11:51 PM

XWiki Meetup in San Francisco on Tuesday 9th 6.30pm

We are with Vincent Massol in California for the Google Summer of Code Mentor Summit.

Terracotta has kindly offered us a space to hold an XWiki/Maven Meetup (Jason Van Zyl from Maven/Sonatype will also be in San Francisco ...

October 05, 2007 11:51 PM

Stéphane Traumat

Un Microsoft Access en ligne !

Si il y a bien un soft que je déteste, c'est Access ! C'est une vrai saloperie avec des performances minables et surtout un paquet de spécificités horribles (style les date qu'il faut entourer de # dans les requêtes). Alors quel ne fut pas mon bonheur lorsque j'ai découvert http://db.zoho.com/ ! En gros, il s'agit d'un access complètement en ligne avec base de données, formulaires, requêtes, reporting... Je vous conseille vivement de vous inscrire et d'essayer toutes leurs applications (ils ont aussi un traitement de texte, un tableau, un planner...). Les gens de Zoho font vraiment un travail impressionnant, du vrai web 2.0, du vrai changement. bref, ils vont pas tarder à se faire racheter pour un bon paquet d'argent :D

October 05, 2007 09:32 AM

October 04, 2007

Ludovic Dubost

Who’s hot

Alenty une startup au nom qui veut rien dire mais qui veut dire quelque chose quand même (une bière pour le premier qui trouve la source du nom) se prépare à lancer "Who’s hot", un outil pour les blogs et les outils communautaires ...

October 04, 2007 09:30 PM

Jour (presque) calme avant 1 semaine aux USA

Nous venons passer 2 jours de conférence (IP Convergence + Rencontres ICC), ou nous avons pu présenter nos derniers produits XWiki Watch, Nearbee et Chronopolys.

...

October 04, 2007 10:20 AM

Video Blogged

Rodrigo de vpod.tv m’a video-bloggé lors d’un panel sur la communication des startup à la conférence IP Convergence..

C’était très intéressant d’entendre le parcours de communication d’une ...

October 04, 2007 10:20 AM

October 03, 2007

Stéphane Traumat

Quelques polices libres

Voilà un très bon article http://ifacethoughts.net/2007/10/02/open-source-fonts/ qui indique où trouvez des polices libres.. ça peut toujours être pratique !

October 03, 2007 09:32 AM

October 02, 2007

Stéphane Traumat

GWT pour l'IPhone

Décidément, je regrette pas du tout de mettre lancer dans GWT si tôt :) On peut même utiliser GWT pour développement des applications IPhone :
http://googlewebtoolkit.blogspot.com/2007/09/gwt-application-development-for-iphone.html

October 02, 2007 09:23 AM

October 01, 2007

Ludovic Dubost

iPhone or not iPhone ?

La semaine prochaine je suis aux USA, occasion intéressante pour acheter un iPhone, le dernier jouet à la mode de toute l’industrie.

Mais bien qu’il y ait de très bonnes raisons d’acheter un iPhone, j’hésite fortement à en acheter un.

Les bonnes raisons d’acheter un iPhone sont: