Instalando y usando JRebel en Eclipse IDE & Tomcat

PASO 1: Instalando JRebel en Eclipse

Eclipse 3.6 Helios (y posteriores) – Instalación a través de Eclipse Marketplace

Para instalar JRebel en Eclipse, abriremos Eclipse Marketplace (Help » Eclipse Marketplace…) y buscaremos “jrebel”. Haremos click en el botón “Install” que aparecerá al lado.

1-market place

Eclipse 3.3, 3.4 & 3.5 – Instalación a través del Update Manager

La instalación a través del Update Manager es similar a la descrita anteriormente. Abriremos “Help » Install New Software… y pegaremos la siguiente URL: http://zeroturnaround.com/update-site/

2-update manager

Para que el proceso de instalación vaya más rápido, podemos deseleccionar la opción “Contact all update sites…” si ya tenemos todos los prerequisitos. Por ejemplo, el paquete “Eclipse IDE for Java EE Developers” ya contiene todo lo necesario, incluyendo WTP.

PASO 2: Seleccionando opciones y acabando el proceso de instalación

Seleccionaremos las opciones que queramos instalar. El plugin JRebel es requerido y deberá ser instalado por todo el mundo. Esto es lo que incluye:

  • El plugin contiene una instalación completa de JRebel, la última versión, para que no tengamos que bajarlo por separado – sólo necesitaremos una licencia después de la instalación.
  • El plugin también incluye el Eclipse Debugger Integration que ayuda al debugger del IDE para reconocer nuevo código y poder establecer breakpoints.

El plugin JRebel for Java EE es opcional pero seguramente también lo queramos instalar. El plugin es recomendado si queremos utilizar WTP (Web Tools Platform) en proyectos con JRebel.

JRebel m2eclipse está disponible si instalamos a través del update site. Este plugin permite generar el archivo de configuración jrebel.xml en builds con m2eclipse y jrebel-maven-plugin.

PASO 3: Configurar JRebel y añadir licencia

Después de reiniciar Eclipse, si no tenemos una licencia de JRebel instalada, el plugin mostrará una notificación para que procedamos al registro. Haremos click en el enlace del pop-up para proceder a la configuración de la licencia.

3-notification

El enlace nos va a llevar a la ventana de activación de JRebel donde tendremos que seleccionar la licencia que queremos: licencia de evaluación de 14 días, licencia OSS/Scala/Social o comprar una nueva licencia.

4-jrebel config centre

Si ya disponemos de una licencia, la podemos copiar directamente en el área de texto que nos aparece. En caso contrario, podemos seleccionar la opción de evaluación que nos direccionará a la página de JRebel para rellenar el formulario de registro. Una vez enviado el formulario, nos proporcionará la licencia que deberemos copiar. La licencia se verificará y se guardará en un archivo jrebel.lic en el directorio {user.home}./jrebel.

PASO 4: Usando JRebel en Eclipse

Paso 4.1: Habilitar el modo “Build Automatically”

Comprueba que Project » Build automatically está habilitado:

5-build automatically

Paso 4.2: Añadir la naturaleza JRebel al proyecto

Para que JRebel pueda hacer su trabajo, tiene que saber donde están las clases y los recursos. Añadiremos un archivo de configuración jrebel.xml para especificarlo. Esto es necesario para desplegar la aplicación en un WAR/EAR. Deberemos tener un jrebel.xml en cada módulo, esto incluye módulos web y EJB. El archivo de configuración jrebel.xml se deberá poner en el directorio WEB-INF/classes en caso de los módulos web y en la raíz del jar en módulos EJB. El archivo jrebel.xml se genera automáticamente cuando activamos JRebel Nature.

6-JRebel Nature

Si usamos Maven podemos utilizar el plugin JRebel Maven que generará el jrebel.xml según el módulo pom.xml tal y como se describe en el manual de configuración del plugin para Maven.

En el 99% de los casos, probablemente tengamos un solo módulo. Es estos casos, el archivo jrebel.xml generado automáticamente debería ser suficiente. Si el proyecto es una de las excepciones, podremos editar manualmente el archivo tal y como describe el manual de instalación.

Si queremos utilizar la configuración en jrebel.xml para todo el equipo, empezaremos con el jrebel.xml generado, y seguidamente reemplazaremos todas las rutas absolutas a nuestro workspace por una propiedad del sistema. JRebel reemplazará expresiones como “${myProject.root}” en jrebel.xml por una propiedad del sistema que podemos pasar al contenedor de aplicaciones de la siguiente manera: -DmyProject.root=/Users/salmar/myProject. Esto permite usar una única configuración para todo el mundo y personalizarla cuando iniciamos el servidor.

Si todos los componentes del equipo usa Eclipse con un workspace similar, podemos incluso evitar utilizar una propiedad propia ya que todas las aplicaciones arrancadas con JRebel en Eclipse tienen una propiedad rebel.workspace.path definida en el workspace  y se puede usar como “${rebel.workspace.path}” directamente en el jrebel.xml.

Paso 4.3: Arrancar la aplicación con JRebel

Cuando arrancamos una aplicación podemos habilitar JRebel para esa configuración específica de arranque. Esto quiere decir que cuando lo habilitamos, -javaagent:your_location/jrebel.jar se añadirá automáticamente a los flags de arranque. Si seleccionamos la casilla de debug, se generará un fichero jrebel.log en el directorio de metadatos en el workspace de Eclipse o en la ubicación del fichero jrebel.jar

Para habilitar / deshabilitar JRebel navegaremos a la pestaña JRebel en la configuración de ejecución y marcaremos las casillas.

7- Run Configuration

Paso 4.4: Configurar WTP

La publicación automática deberá ser deshabilitada en la configuración del servidor. Haciendo doble click en el nombre del servidor se mostrará la página de configuración. En la sección Publishing seleccionaremos la opción Never publish automatically tal y como se muestra en la siguiente imagen.

8-Tomcat publishing

Paso 4.5: Éxito!

Para comprobar que la instalación se ha llevado a cabo con éxito, accederemos a una página que use alguna clase, cambiamos la clase en el IDE y la guardamos. Cuando accedamos a la página nuevamente, deberíamos ver los siguientes mensajes en consola:

9-Tomcat console
Ahora que ya lo tenemos todo configurado, podemos programar sin necesidad de hacer redeploy. Si tienes cualquier duda específica de JRebel, el foro es el mejor sitio para preguntar, así otras personas podrán ver la respuesta también.

Spring Puzzlers #02: The Happy Traveler

I really love traveling, and even more when I don’t know what my next destination will be. That’s one of my biggest passions, I have to admit it. If you also love traveling, you should consider using my TravelService for your next trip. Let me introduce you the second Spring Puzzler:

The TravelService will be our entry point. It has a method to print a destination picked by a DestinationPicker (shown below). Notice that the method is annotated with @Async to run it asynchronously in another thread:

public class TravelServiceImpl implements TravelService {
	private Logger logger = Logger.getLogger(TravelServiceImpl.class);
	
	private DestinationPicker destinationPicker;
	
	@Async
	public void printNextDestination() {
		logger.info("Running from thread: " + Thread.currentThread().getId());
		
		System.out.println("Your next holiday destination: " + 
							destinationPicker.getDestination());
	}

	public void setDestinationPicker(DestinationPicker destinationPicker) {
		this.destinationPicker = destinationPicker;
	}
}

This is the RandomDestinationPicker, which uses a really complex algorithm to choose the destination from a list of available destinations :). It uses the id field (increased in every object creation) to determine the location:

public class RandomDestinationPicker implements DestinationPicker {
	
	private static int instances = 0;
	
	private int id;
	private List<String> availableDestinations;	
	
	public RandomDestinationPicker(List<String> availableDestinations) {
		this.availableDestinations = availableDestinations;
		id = instances++;
	}
	
	public String getDestination() {
		return availableDestinations.get(id % availableDestinations.size());
	}
}

The next XML file has the configuration for our Application Context:
- It defines a list of destinations (a list of strings)
- It defines the DestinationPicker injecting the list of available destination and setting the scope of the bean to ‘puzzle’.
- It defines the TravelService injecting the DestinationPicker.
- It enables the @Async annotation (task:annotation-driven)
- It defines a new scope called ‘puzzle’ which is a thread scope

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:task="http://www.springframework.org/schema/task"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">


	<bean id="travelService" class="com.sergialmar.springpuzzlers.sp02.TravelServiceImpl" 
							 p:destinationPicker-ref="destinationPicker"/>

	<bean id="destinationPicker" class="com.sergialmar.springpuzzlers.sp02.RandomDestinationPicker" 
								  scope="puzzle">
		<constructor-arg ref="destinationList"/>
	</bean>
								  
	<util:list id="destinationList">
		<value>San Francisco</value>
		<value>Kuala Lumpur</value>
		<value>Barcelona</value>
		<value>Mexico City</value>
		<value>Cape Town</value>
	</util:list>
	
	<task:annotation-driven/>

	<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
      <property name="scopes">
          <map>
              <entry key="puzzle">
                  <bean class="org.springframework.context.support.SimpleThreadScope"/>
              </entry>
          </map>
      </property>
  	</bean>
</beans>

The bootstrap class creates the application context and gets the TravelService bean, calling the printNextDestination method 4 times.

public class TravelBootstrap {

	public static void main(String... args) {
		ApplicationContext applicationContext = 
			new ClassPathXmlApplicationContext("com/sergialmar/springpuzzlers/sp02/app-context.xml");
		
		TravelService travelService = 
			applicationContext.getBean(TravelService.class);
		
		travelService.printNextDestination();
		travelService.printNextDestination();
		travelService.printNextDestination();
		travelService.printNextDestination();
	}
}

Time to vote! Which of the following statements is right:

Spring Puzzler #01 Solution

I guess it’s time for the solution of the first Spring Puzzler. I’ve received a total of 79 votes, 35% got it right.

The solution was: Bienvenido a Spring Puzzlers Sergi.

In case you want to download the code, you can find it here: https://github.com/salmar/SpringPuzzlers

Explanation

The first thing to notice is that SpanishWelcomePrinter was not annotated, that means the component scan will never pick it up and there won’t be any SpanishWelcomePrinter in the Application Context. Only one implementation of LocalizedWelcomePrinter will exist, the EnglishWelcomePrinter.

We can now safely discard the NoSuchBeanDefinitionException. But this was not the trap…even if we had the @Named in the SpanishWelcomePrinter, we would have gotten the same output.

The catch was in the ConsoleWelcomeService where we try to inject a static field. Static fields are omitted for dependency injection, in our case we are going to stick with SpanishWelcomePrinter, instantiated with the new operator and no DI will happen. We can discard the possibility to get the message in English now. NullPointerException cannot happen at any point…

The next Spring Puzzler will be published the 13th Oct.

Happy hacking!

Spring Puzzler #01: Welcome

I’ve spent the last two years and a half delivering the official SpringSource courses all over the world and during this time I’ve seen a lot of students coming across unexpected behaviors and wondering why. Based on Josh Bloch’s Java Puzzlers, I’m going to introduce you the Spring Puzzlers, a bunch of puzzlers ranging from Spring configuration gotchas to AOP and dynamic proxy voodoo, transactional enigmas…

So here’s the first one :)

Our entry point will be a WelcomeService, a really simple interface with a single method welcome:

public interface WelcomeService {
	void welcome(String name);
}

The implementation uses a LocalizedWelcomePrinter to print the localized message to the console. I’ll be using JSR-330 annotations for the DI :

import javax.inject.Inject;
import javax.inject.Named;

@Named
public class ConsoleWelcomeService implements WelcomeService {

	@Inject
	private static LocalizedWelcomePrinter printer = new SpanishWelcomePrinter();

	public void welcome(String name) {
		printer.printWelcome(name);
	}

}

There are 2 implementations of the LocalizedWelcomePrinter (a custom interface), one for Spanish:

public class SpanishWelcomePrinter implements LocalizedWelcomePrinter {

	public void printWelcome(String name) {
		System.out.println("Bienvenido a Spring Puzzlers " + name);
	}

}

And one for English. Notice I’m using @Named here to autoregister the component in the application context:

@Named
public class EnglishWelcomePrinter implements LocalizedWelcomePrinter {

	public void printWelcome(String name) {
		System.out.println("Welcome to Spring Puzzlers " + name);
	}
}

So the configuration is quite straightforward, a single line enabling the component scanning:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
		
	<context:component-scan base-package="com.sergialmar.springpuzzlers" />

</beans>

And this is the class that bootstraps the system:

public class WelcomeBootstrap {

	public static void main(String... args) {
		ApplicationContext applicationContext =
			new ClassPathXmlApplicationContext("app-context.xml");

		WelcomeService welcomeService =
			applicationContext.getBean(WelcomeService.class);

		welcomeService.welcome("Sergi");
	}
}

So…what will be the output after running this class? Choose the right answer from the below poll!

Extending handler method argument resolution in Spring MVC

Spring MVC data binding is really flexible and powerful, it can bind request parameters, URI templates variables, cookie values, HTTP headers… directly into your domain objects, but what if you want a custom resolution mechanism?

I will show you how to do it with a simple example. Imagine you want to get the user country name directly in you controller. The handler method I want to have looks like the following:

@RequestMapping(value="/", method=RequestMethod.GET)
public String home(@Country String userCountry, Model model) {
    ...
}

Notice that we have a new annotation called @Country, this is our custom annotation that we are gonna use to know where to inject the country name. Let’s create the annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Country {
}

Don’t forget to set the retention to runtime, otherwise the annotation won’t be available. Now it’s time to define how we want to resolve the argument annotated with @Country. The HandlerAdapter takes care of this resolution but it delegates to the WebArgumentResolvers for this task. We’ll implement our custom WebArgumentResolver:

public class CountryWebArgumentResolver implements WebArgumentResolver {

    private static final String WS_URL = 
        "http://api.ipinfodb.com/v3/ip-city/?key={apiKey}&ip={userIp}&format=xml";
    private static final String API_KEY = "yourKey";
	
    private RestTemplate restTemplate = new RestTemplate();
	
    public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest nativeWebRequest) throws Exception {
        // Get the annotation		
        Country countryAnnotation = 
            methodParameter.getParameterAnnotation(Country.class);

        if(countryAnnotation != null) {
            HttpServletRequest request = 
                (HttpServletRequest) nativeWebRequest.getNativeRequest();
			
            // Get user IP
            String userIp = request.getRemoteAddr();
			
            // Call geolocalization web service
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.set("Accept", "text/xml");

            HttpEntity<UserInfo> userInfo = restTemplate.exchange(WS_URL, HttpMethod.GET, new HttpEntity<UserInfo>(requestHeaders), UserInfo.class, API_KEY, userIp);

            return userInfo.getBody().getCountryName();
        }
		
        return UNRESOLVED;
    }
}

As you can see, it’s quite straightforward, we just need to implement a single method. What this resolver is doing, is basically checking if the parameter is annotated with @Country, getting the user IP and calling a web service to get geolocalization data of the user IP (notice that an extra class has been created, UserInfo, in order to bind the web service parameters). I’ll be using IPInfoDB as the geolocalization service.

We just have one step left: define our new resolver in the handler adapter. Our custom web argument resolver will kick in before any Spring MVC default resolver.

	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
		<property name="customArgumentResolver">
			<bean class="com.sergialmar.customresolver.web.support.CustomWebArgumentResolver"/>
		</property>
	</bean>

Note: if you are using the Spring 3 MVC namespace (

<mvc:annotation-driven/>

), remember to place your handler adapter definition on top of it.

In Spring 3.1, you can user the mvc namespace to register the argument resolver:

	<mvc:annotation-driven>
		<mvc:argument-resolvers>
			<bean class="com.sergialmar.customresolver.web.support.CustomWebArgumentResolver"/>
		</mvc:argument-resolvers>
	</mvc:annotation-driven>

We are now ready to use the @Country annotation in our controller :)

	@RequestMapping(value="/", method=RequestMethod.GET)
	public String home(@Country String userCountry, Model model) {
		
		String message = null;
		
		if(userCountry.equals("SPAIN")) {
			message = "It seems you are in the same country as I am, up for a beer?";
		} else {
			message = "It seems we are not close to each other, will let you know when I am in " + userCountry;
		}
		
		model.addAttribute("message", message);
		
		return "home";
	}

Configuración basada en anotaciones y el Spring Explorer

Uno de los “problemas” que tiene asociada la configuración basada en anotaciones en Spring es que tenemos nuestra configuración distribuida en nuestros componentes (tenemos disponibles anotaciones como @Controller, @Service, @Repository, @Component, @Autowired…) cuando con XML podemos tenerla centralizada y puede ser más fácil tener la visión a primera vista.

Si nos centramos en la capa web, si configuramos nuestros controladores con la anotación @Controller y los mappings de las URLs con la anotación @RequestMapping, vamos a tener todas nuestras URLs a procesar repartidas en todos nuestros controladores, con lo que será más difícil saber quien es el responsable de procesar una cierta URL.

Para ello, os recomiendo usar la vista Spring Explorer de SpringSource Tool Suite, que nos dará la información que necesitamos, en este caso respeto a los mapeos y las clases configuradas con anotaciones.

Monitorizando aplicaciones y sistemas con Hyperic HQ

Después de un largo silencio, os voy a dar a conocer a Hyperic HQ para el monitoreo de vuestras aplicaciones y sistemas. Una de las características más interesantes de éste, es el autodescrubrimiento de los servicios y recursos con soporte para más de 75 tecnologías diferentes. Tenemos disponible la versión Open Source y la versión Enterprise, así que vamos a utilizar la versión open source en este artículo y veremos lo simple que es.

Vamos a monitorizar un servidor A con un Tomcat y un PostgreSQL desde un servidor B. En el servidor B vamos a instalar el servidor HQ y en el servidor A instalaremos el agente HQ. Todas las descargas para todos los sistemas operativos las vais a poder encontrar en la siguiente dirección: http://www.hyperic.com/downloads/hyperic-hq-open-source-downloads.html.

Instalando el servidor HQ

Bajamos el instalador para el servidor, en mi caso la versión Linux:

wget http://downloads.sourceforge.net/hyperic-hq/hyperic-hq-installer-4.2.0-1260-x86-linux.tgz

Descomprimimos y ejecutamos el instalador. Seguir los pasos que se indican:

tar xvzf hyperic-hq-installer-4.2.0-1260-x86-linux.tgz
cd hyperic-hq-installer/
./setup.sh

Arrancamos el servidor:

/home/hyperic/server-4.2.0/bin/hq-server.sh start

A partir de ahora tendremos instalado el servidor que se encontrará accesible en http://nombredelserver:7080 con las credenciales por defecto, usuario: hqadmin y password: hqadmin. Deberíamos ver un dashboard como el siguiente:

Instalando el agente HQ

Para cada sistema que queramos monitorizar, deberemos instalar el agente. Vamos a bajar el agente en el servidor A (tiene instalado un Tomcat y un Postgres), en mi caso la versión para Linux:

wget http://downloads.sourceforge.net/hyperic-hq/hyperic-hq-agent-4.2.0-1260-x86-linux.tgz

Descomprimimos:

tar xvzf hyperic-hq-agent-4.2.0-1260-x86-linux.tgz
mv hyperic-hq-agent-4.2.0 /home/hyperic/

Arrancamos el agente para que puede enviar los datos al servidor. La primer vez que lo arranquemos no pedirá la configuración:

cd /home/hyperic/hyperic-hq-agent-4.2.0/bin/
./hq-agent.sh start

Starting HQ Agent...
[ Running agent setup ]
What is the HQ server IP address: 192.168.0.192 // Cambiar por la ip del servidor donde habéis instalado el servidor
Should Agent communications to HQ always be secure [default=no]:
What is the HQ server port     [default=7080]: 
- Testing insecure connection ... Success
What is your HQ login [default=hqadmin]: 
What is your HQ password: 
What IP should HQ use to contact the agent [default=192.168.0.193]: 
What port should HQ use to contact the agent [default=2144]: 
- Received temporary auth token from agent
- Registering agent with HQ
- HQ gave us the following agent token
    1263142571701-3269978360446657677-1867024831687386027
- Informing agent of new HQ server
- Validating
- Successfully setup agent

Configurando los recursos

Teniendo el agente corriendo, vamos a echarle un vistazo al dashboard de nuestro servidor. Nos daremos cuenta, que en el portlet de autodescubrimiento, aparecen todos los recursos que se han podido encontrar. En nuestro caso, se han encontrado el Tomcat, el Postgres y el agente HQ. Voy a descartar el agente HQ y monitorizar los otros dos recursos.
Nota: Si intentáis descubrir un PostgreSQL 8.4 no os lo descubrirá, pero lo podréis añadir de forma manual.

Si pasamos a la opción “Resources” del menú, veremos todo lo que tenemos monitorizado. Tendremos los recursos categorizados (Plataformas, Servidores, Servicios…) y para cada uno de ellos la configuración de métricas y alertas. Aquí un ejemplo de los servidores y servicios que tenemos hasta ahora:

Si os fijáis, en el Tomcat y Postgres, nos aparece un icono de interrogación de color gris en la parte derecha. Vamos a tener que hacer alguna tarea adicional, para tener el completo monitorio de estos recursos.

Configurando Tomcat para monitoreo

Para poder monitorizar nuestro Tomcat, deberemos habilitar JMX. Modificaremos el archivo catalina.sh para añadir estos parámetros en la variable CATALINA_OPTS (en el ejemplo no se utiliza autenticación, pero lo podéis añadir en la configuración):

vim /usr/local/tomcat/bin/catalina.sh
export CATALINA_OPTS="-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=6969 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false"

Reiniciamos el tomcat:

/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh

Una vez hecho esto, nos picharemos a nuestro recurso monintorizado Tomcat de la lista y configuraremos las propiedades(en caso de hacerlo de la manera detallada, sólo tendréis que pinchar OK) :

En breve se mostrará el icono verde junto al Tomcat en la lista. A continuación podéis ver algunas estadísticas de nuestro Tomcat:

Sólo nos falta añadir alguna alerta, así que vamos añadir una alerta simple de notificación cuando nuestro Tomcat no esté disponible. Si pincháis en la pestaña “Alerts”, os va a aparecer un botón en forma de submenu “Configure” que una vez pinchado nos dará la opción de crear una nueva alerta, así que vamos a ello.

Simplemente se generará una alerta cuando la métrica “Availability” sea igual a 0. Podéis probarlo parando el Tomcat y viendo que la alerta os aparece en el dashboard inicial.

Configurando PostgreSQL para monitoreo

Para el monitoreo del Postgres voy a crear un nuevo usuario llamado hyperic:

postgres@salmar-server:/home/sergi$ psql
psql (8.3.8)
Type "help" for help.

postgres=# CREATE USER hyperic WITH PASSWORD 'postgresHQ';
CREATE ROLE

A continuación, pinchando el Postgres en la lista de servidores, vamos a añadir la configuración de acceso:

Ahora si que en nuestra lista tenemos nuestros servidores accesibles como muestra el icono verde:

Happy monitoring!

Hands-on Spring 3: The next generation (SOCF)

Dejo aquí mi presentación del taller “Hands-on Spring 3: The next generation” impartido en el Sun Open Communities Forum (18 de Junio 2009):

Los proyectos de ejemplo de SpringSource Tool Suite los podeis encontrar aquí.

Update 25/06/09:

Poco tiempo para postear durante el evento, así que sólo me dio tiempo para colgar la presentación y el ejemplo.El evento fue otra excusa para retomar contacto con gente como Abraham Otero, Alfredo Casado, Nacho Brito, Nacho Coloma, Dani López, Dani Latorre, Álvaro Sanchez-Mariscal, Peyrona…De hecho mi impresión es que en España, en general, hay poca filosofía de asistir a eventos como este, los asistentes totales fueron 164, que si comparamos con otros eventos como Devoxx (otra índole está claro) que hacen lleno con 3200 asistentes, queda com un poco ridículo. Aunque la magnitud del evento no es comparable, a lo que me refiero, es que aún siendo eventos gratuitos (Devoxx requiere entrada), no veo una gran aceptación a este tipo de iniciativas como la tienen en otros sitios fuera de España. Me pregunto porqué…

Por otra parte, os dejo arriba, el ejemplo que hice para el taller de Spring 3.0. Encontrareis la versión acabada y la versión por acabar. Consiste en un javaHispano REST, donde se debe completar algunas partes de soporte para peticiones REST (GET y DELETE), negociación de contenido (MarshallingView para mostrar noticias en XML) y consumo de servicios REST (parte cliente), en este caso consumo de los servicios REST de Flickr.

Sun Open Communities Forum 09 (Taller Sergi)

Grails y novedades en el grupo de usuarios de Spring en UK

Aprovechando mi estancia en Londres, ayer asistí al encuentro del grupo de usuarios de Spring de UK. En toda Gran Bretaña, el grupo de usuarios cuenta con unos 600 miembros, pero la verdad es que ayer, coincidiendo con la huelga de metro, poca gente se acercó (unas 30 personas).

El meeting fue bastante interesante, más por la gente que asistió. Retomé contacto con gente de SpringSource con la que que hacia tiempo que no coincidía (digamos ex-SpringSource), la cuestión es que a principio de año, debido a diferentes situaciones, algunos integrantes de SpringSource salieron de la empresa y  se juntaron para empezar una nueva aventura empresarial: Open Credo. Vale la pena seguir la pista a estos chicos, básicamente se dedican a consultoría, publicaciones y formación (están en negociaciones para ser partners de SpringSource, situación un poco rara pero tiene todo el sentido), pero presentaron en primicia su proyecto Open Source Central (aún en construcción, en producción a partir de la semana que viene).

Open Source Central

Open Source Central pretende ser el centro de los proyectos con éxito open source, promoviendo buenas prácticas y ofreciendo conocimiento experto. Pretende ser el punto central para recomendaciones de uso de proyectos Open Source en el desarrollo de software. Tenemos diferentes partes en el proyecto:

  • Open Source Central community: foros para el intercambio de buenas prácticas, evaluación de tecnologías emergentes, últimos vídeos y podcasts con contenidos de calidad…
  • Open Source Central Extras: los contribuidores a los proyectos open source van a tener un ranking según lo que contribuyan, de esta manera se tiene un reconocimiento y popularidad dentro del proyecto.
  • Open Source Central for Business: dedicado a las empresas que quieran dar a la comunidad código y que sea ésta la que haga el mantenimiento. Opción muy interesante, vamos a ver que aceptación tiene…

A parte de esto, el motivo principal, fue la charla que se dio fue sobre Grails (Grails eye for the Spring guy), a cargo de Russ Miles.

Grails

La charla era de nivel introductorio, pero a modo de resumen:

  • Grails para ser más productivo, con el añadido que todo es familiar a al nuevo desarrollador y está basado en tecnologías ya maduras (Spring, Hibernate..)
  • Basado en convenciones: básicamente las decisiones las hace Grails, no tenemos que elegir nosotros porque ya hay una manera correcta de hacerlo
  • Es un framework full stack (Groovy, ORM, transacciones, templating para la IU…)
  • Grails es una aplicación Spring: utiliza Spring por debajo, utiliza Groovy, introduce convenciones, elimina la complejidad.
  • Tendremos código más limpio: podremos utilizar Java cuando queramos, dinámico cuando queramos que lo sea.
  • Añade: closures, propiedades, sobrecarga de operadores, sintaxis nativa para listas y otras colecciones, utiliza MOP.
  • Tenemos un abanico de plugins listos para utilizar
  • Grails UI: componentes basados en YUI.

Al finalizar, como de costumbre, vinieron las cervezas ;)

Grails eye for the Spring guy

Claves del éxito en el proceso emprendedor

Ayer estuve en un charla de Antonio González-Barro, socio-fundador y presidente del grupo Intercom, llamada “Claves de éxito en el proceso emprendedor”. El grupo Intercom tiene proyectos como: infojobs.net, softonic.com, emagister.com… entre los más conocidos. La charla fue muy dinámica y consistió básicamente en en resolución de dudas que los asistentes tenían con una definición de emprendedor para acabar. A breve modo se trataron lo siguientes temas:

Éxito empresarial¿Cómo empezó Intercom?

Intercom empezó con la idea de dar conectividad a Internet o sea como ISP. Todo empezó (en el año ’95) poniendo un anuncio en prensa que decía: “si tienes una idea y necesitas ayuda, tenemos el tiempo y el dinero”, a ese anuncio no llamó nadie…Hasta que una persona se interesó y se tiró adelanta su proyecto. En sus inicios, la empresa la formaron 23 personas con un capital de 60k€, pero pronto necesitaron ampliar en 400k€ que gracias a ser ese número de personas, lo pudieron absorber. Ahora son más de 350.

¿Cómo monetizar un proyecto en internet?

Básicamente hay cuatro formas:

1) Por servicio: tu ofreces un servicio y los clientes pagan por él
2) Publicidad: El ejemplo que puso es el de Softonic, que actualmente factura unos $500.000 / mes de anuncios de Google.
3) Intermediación: Intermediación de servicios tipo algunas páginas de vuelos.
4) Rentabilización de la información: a medida que vas evolucionando, vas recogiendo información que puede ser muy valiosa y susceptible para su explotación. ¿Quién sabe más del empleo en españa, infojobs o el INEM?

¡Ya no quedan ideas, todo está inventado!

Siempre hay cosas para hacer. El problema es que siempre cuesta un riñón: En el caso que no haya competencia, te cuesta introducir el producto/servicio ya que todo el mundo es reacio; en el caso que haya competencia, tienes que competir con todos los otros. Entonces, ¿te la juegas a sacar la maquinilla de afeitar desechable (evidentemente cuando no había!) o te esperas 20 años y compites con todos los otros?

Hay cosas que al no haber existido antes en papel, es difícil visualizar en internet, pero pueden tener un gran valor. Este es el caso de emagister, antes no habían clasificados de formación, pero tiene todo el sentido del mundo. Tenemos que hacer ejercicios de pensamiento lateral para intentar identificar estas oportunidades.

Sea lo que sea, aún falta mucho por inventar!

¿Cómo ha gestionado el crecimiento Intercom?

En el grupo Intercom todo el mundo tiene mucha capacidad de autonomía. No existen las jerarquías y cuando se dan alas a la gente vuelan muy alto! Esta es la principal clave de su crecimiento, a parte hay una importante transferencia de know-how dentro de las empresas del grupo.

¿Cómo romper el hielo con los clientes en proyectos nuevos?

Se debe dejar en manos de vendedores expertos conocedores del mercado del que queremos introducirnos y crear cosas originales. Una técnica que se utiliza mucho es empezar de forma gratuita y empezar a cobrar tiempo después.
También está lo que se conoce como “la técnica abrelatas” consistente en convencer a un conocido que esté dentro de una empresa grande para que su empresa utilice nuestro producto y así poder hacer referencia a la misma: “La empresa X utiliza nuestros servicios”…

¿Cuántas visitas mensuales se necesitan para la publicidad?

Normalmente se está pagando unos $0.15 por usuario único y mes, con lo que si tienes 500k usuarios te podría reportar unos 75k€. En Intercom gastan mucho dinero en google adwords, no hacen publicidad en otros medios prácticamente.

¿Cuánto tiempo tarda un proyecto en tener éxito?

Depende…Hay los de corto plazo y los de largo plazo. En Intercom no buscan proyectos que den dinero rápido, tienen paciencia pero buscan proyectos que den mucho dinero. La media viene a ser unos 3 años.

Para terminar Antonio hizo su definición de emprendedor bastante extensa y concisa, que se puede resumir en todos los siguientes puntos:

Motivación, capacidad de arriesgar, capacidad de superar fracasos, autonomía, responsabilidad, confianza, honestidad, humildad, tenacidad, paciencia, optimismo, generosidad, sobriedad, sinceridad, sentido común, capacidad de acción, capacidad de aprender, creatividad, pasión y muy importante, disfrutar en el trabajo que trabajar sin amor es esclavitud.