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:
Filed under: puzzlers, spring | 1 Comentario
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!
Filed under: Uncategorized | Deja un comentario
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!
Filed under: puzzlers, spring | 2 Comentarios
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";
}
Filed under: Uncategorized | Deja un comentario
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.
Filed under: spring | Deja un comentario
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!
Filed under: Uncategorized | 3 Comentarios
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):
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.

Filed under: eventos, spring | 1 Comentario
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 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.

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
Filed under: emprendedores, grails | 1 Comentario
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:
¿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.
Filed under: emprendedores | 1 Comentario
Este año me fue imposible asistir a SpringOne debido a la coincidencia de fechas con el curso de Spring impartido en Madrid, pero sin duda uno de los términos que más corrían esos días por Twitter era Spring Roo.
Spring Framework, por si solo, aumenta la productividad del desarrollador encargándose de todo ese “boilerplate code”, como lo llaman en la lengua de Shakespeare, pero si a esto le añadimos generación de código y configuración, la productividad se puede ver incrementada sustancialmente. Aquí es donde entra Spring Roo, aún en fase alpha (versión en el momento de escribir este artículo 1.0.0A2), por lo que no vamos a ser demasiado críticos.
Aprovechando el anuncio que SpringSource Tool Suite pasa a ser gratuito, me he bajado la nueva milestone 2.1.0.M1 que incluye integración con la consola de Spring Roo.
Creando un proyecto Roo
Para crear un proyecto con Spring Roo, deberéis seleccionar File > New > Other y escoger Template Project dentro de SpringSource Tool Suite:

En la siguiente pantalla simplemente escoger el template Roo Simple y a continuación deberéis introducir el nombre del proyecto y el paquete para finalizar el proceso.

Con esto, vamos a tener una estructura de proyecto basado en maven, con 3 archivos de configuración básicamente:
- applicationContext.xml: Un aplication context básico que da soporte para el uso de anotaciones y escaneado de componentes.
- web.xml:Configuración para Log4j, registro de un DispatcherServlet, registro de un ResourceServlet (Spring JS, para servir el contenido estático) y un OpenEntityManagerInViewFilter para JPA.
- {nombreDelProyecto}-servlet.xml: Un aplication context para el contexto del DispatcherServlet configurado en el web.xml con escaneo de componentes(@Controller), un ExceptionResolver y un ViewResolver(para JSPs).
Añadiendo clases persistentes
Una vez tenemos la estructura del proyecto, nos interesará añadir algunas clases de nuestro dominio. Para ello vamos a habilitar primero JPA en nuestra aplicación. Esto lo vamos a hacer utilizando la consola de Roo que la podemos habilitar con un simple CTRL + R:

En nuestro caso vamos a suponer que utilizamos PostgreSQL y Hibernate para JPA. El comando a utilizar es tan simple como:
install jpa -database POSTGRESQL -provider HIBERNATE
¿Que nos va a generar esto?
- persistence.xml: Creación de la persistence unit con una configuración básica
- database.properties: Creación de un archivo properties con la información de conexión a la BD (driver, url, usuario y password), el cual deberemos rellenar con la información adecuada.
- En el applicationContext.xml: creación de un Data Source con la configuración del archivo database.properties accedido por un PropertyPlaceHolder, un Transaction Manager y finalmente una factoría de EntityManager.
- Actualización de las dependencias Maven.
Bien, ya estamos preparados para usar JPA, vamos a por las clases de nuestro dominio. Usaremos para ello la siguiente instrucción (la ~ sirve para asignar el paquete que le hemos especificado al proyecto):
new persistent class jpa -name ~.Persona
Y para los atributos de la clase:
add field number -fieldName id -type java.lang.Integer
add field string -fieldName nombre
En este punto es cuando ha venido mi sorpresa: Spring Roo genera 5 archivos!
Created SRC_MAIN_JAVA/Persona.java
Created SRC_MAIN_JAVA/Persona_Roo_Plural.aj
Created SRC_MAIN_JAVA/Persona_Roo_Entity.aj
Created SRC_MAIN_JAVA/Persona_Roo_ToString.aj
Created SRC_MAIN_JAVA/Persona_Roo_Configurable.aj
La clase java que genera es simple, sólo contiene los atributos sin ningún método, pero podemos ver que Spring Roo ha añadido 3 anotaciones a nivel de clase. Esto le va a servir para coger la información de los archivos que ha generado adicionalmente:
@Entity
@RooEntity
@RooJavaBean
@RooToString
public class Persona {
private Integer id;
private String nombre;
}
Pero, ¿dónde está todo lo otro? En los archivos adicionales .aj que ha creado. ¡Ahí está la magia! Cada vez que añadimos un atributo, Spring Roo actualiza esos archivos con la información adicional. Pero no sólo añade getters y setters, sino que también crear un archivo para acceder automáticamente a métodos transaccionales de persistencia como persist(), findPersona(id), y más cosas…Para que os hagáis una idea, veamos la pinta tiene el Persona_Roo_ToString.aj (como su propio nombre indica, va a contener el método toString de la clase):
privileged aspect Persona_Roo_ToString {
public java.lang.String Persona.toString() {
StringBuilder sb = new StringBuilder();
sb.append("id: ").append(getId()).append(", ");
sb.append("version: ").append(getVersion()).append(", ");
sb.append("id: ").append(getId()).append(", ");
sb.append("nombre: ").append(getNombre());
return sb.toString();
}
}
Más en la segunda parte, hasta aquí por ahora
Filed under: Uncategorized | 2 Comentarios
Entradas Recientes
- Spring Puzzlers #02: The Happy Traveler
- Spring Puzzler #01 Solution
- Spring Puzzler #01: Welcome
- Extending handler method argument resolution in Spring MVC
- Configuración basada en anotaciones y el Spring Explorer
- Monitorizando aplicaciones y sistemas con Hyperic HQ
- Hands-on Spring 3: The next generation (SOCF)
- Grails y novedades en el grupo de usuarios de Spring en UK
- Claves del éxito en el proceso emprendedor
- Probando Spring Roo: Primera parte
- Libro de Spring Web Flow 2
Categorías
- emprendedores (2)
- eventos (1)
- formación (1)
- grails (1)
- puzzlers (2)
- spring (7)
- Uncategorized (5)









