Cliente EJB 3.0 con Spring

1. Configuramos el proyecto, pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.wordpress.modprobe</groupId>
  <artifactId>hello-client</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>hello-client</name>
  <description>Hello client, hello world using spring and ejb 3.0</description>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  	<dependency>
	   <groupId>org.springframework</groupId>
	   <artifactId>spring</artifactId>
	   <version>2.5.6</version>
	</dependency>	
	<dependency>
	   	<groupId>org.apache.openejb</groupId>
	   	<artifactId>openejb-client</artifactId>
	   	<version>3.0</version>	   	
	</dependency> 
	<dependency>
		 <groupId>com.wordpress.modprobe</groupId>
		 <artifactId>hello-ejb</artifactId>
		 <version>0.0.1-SNAPSHOT</version>
	</dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <mainClass>com.wordpress.modprobe.Main</mainClass>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>com.wordpress.modprobe.Main</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>

    </plugins>

  </build>

</project>

 

2. Escribimos el cliente

package com.wordpress.modprobe.client;

import com.wordpress.modprobe.ejb.HelloService;

public class HelloSpringClient {

	public HelloSpringClient(){}

	private HelloService service;

	public void setService(HelloService service) {
		this.service = service;
	}

	public String sayHello(String name){
		String retVal = service.hello(name);
		return retVal;
	}

}

3. Creamos el archivo de configuración para Spring

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
         http://www.springframework.org/schema/jee
         http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">

    <jee:jndi-lookup id="helloService" jndi-name="HelloServiceBeanRemote">
         <jee:environment>
             java.naming.factory.initial=org.apache.openejb.client.RemoteInitialContextFactory
             java.naming.provider.url=ejbd://localhost:4201
         </jee:environment>
    </jee:jndi-lookup>

    <bean id="client" class="com.wordpress.modprobe.client.HelloSpringClient" scope="singleton">
    	<property name="service" ref="helloService" />        		
    </bean>

</beans>

4. Crear la clase main

package com.wordpress.modprobe;

import java.io.Console;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

import com.wordpress.modprobe.client.HelloSpringClient;

public class Main {

	public static void main(String[] args){										
		BeanFactory springFactory = new XmlBeanFactory(new ClassPathResource("application-Context.xml"));
		HelloSpringClient client = (HelloSpringClient)springFactory.getBean("client");

		System.out.println();
		System.out.print("Pon tu nombre: ");
		Console console = System.console();
		String readLine = console.readLine();

		String response = client.sayHello(readLine);

		System.out.println("EJB dice: "+response);

	}

}

5. Correr el ejecutable mvn exec:java
https://modprobe.files.wordpress.com/2010/11/hello_ejb3-0_spring_openrjb-zip.docx

Advertisements

Hello – world EJB 3.0

Ejemplo muy sencillo de EJB 3.0 usando un bean de sesión stateless

 1. Bajamos OpenEJB 3.0 

 2. Escribimos la interfaz remota.

package info.modprobe.ejb;

import javax.ejb.Remote;

@Remote
public interface HelloService{

	String hello(String arg);
}

 3. Escibimos el bean

package info.modprobe.ejb;

import javax.ejb.Stateless;

@Stateless
public class HelloServiceBean implements HelloService {

	public String hello(String arg) {
		return "hola "+arg;
	}

}

 4. Creamos un jar, bueno, que lo haga maven…mvn package….veamos el pom.xml

  4.0.0

  info.modprobe
  hello-ejb
  0.0.1-SNAPSHOT
  ejb

  hello-ejb JEE5 EJB
  http://modprobe.info/2010/11/28/hello-world-ejb-3-0

      javaee
      javaee-api
      5
      provided

      junit
      junit
      3.8.1
      test

     <!-- for javaee:javaee-api -->
      java.net
      java.net
      http://download.java.net/maven/2/

        org.apache.maven.plugins
        maven-compiler-plugin
        2.0.2

          1.5
          1.5

        org.apache.maven.plugins
        maven-ejb-plugin
        2.1

          3.0

    hello-ejb

 5. Deployamos el jar, agregando lo siguiente casi al final del archivo openejb.xml

/home/fal/Desktop/openejb/workspace/hello-ejb/target/hello-ejb.jar

 6.Verificamos el log…….se deb ver algo como en openejb.log

2010-01-14 19:05:15,249 - INFO  - Deployed Application(path=/home/fal/Desktop/openejb/workspace/hello-ejb/target/hello-ejb.jar)



https://modprobe.files.wordpress.com/2010/11/hello_ejb3-0_spring_openrjb-zip.docx

Singletons que no son single

Desde hace un buen rato he sabido que los singletons pueden no ser tan singles usando reflection.

pero ¿cómo es que esto puede suceder?


package single;

import java.lang.reflect.Constructor;

public class Main {

public static void main(String[] args) throws Exception {

Single sin = Single.getInstance();
Single sin2 = Single.getInstance();

if(sin ==sin2){
  System.out.println(" - TEST from singleton equals- ");
}else{
  System.out.println(" - Ouch1  - ");
}

Class<?> forName = Class.forName("single.Single"); //get the class
Constructor<?>[] declaredConstructors = forName.getDeclaredConstructors(); //get constructors fr4om Class
Constructor<?> constructor = declaredConstructors[0]; //get the first constructor (the only one)
constructor.setAccessible(true);//set accesible
Single newInstance = (Single)constructor.newInstance(null);//here we go

if(newInstance == sin){
  System.out.println(" - newInstace and singleton equals - ");
}else{
  System.out.println(" - Singleton is not so single  1 - ");
}

if(newInstance == sin2){
  System.out.println(" - newInstace and singleton2 aARE equals - ");
}else{
  System.out.println(" - Singleton is not so single  22 - ");
}

}

}
package single;

public class Single {

private static final Single instance = new Single();

private Single(){}

public static Single getInstance(){return instance;}

}

El resultado es:

- TEST from singleton equals-
- Singleton is not so single  1 -
- Singleton is not so single  22 -

Una forma más segura de que un singleton sea singleton es usando el approach de enum, Joshua Bloch lo describe en el Item 3 de Effective Java (2nd Edition), el mismo Bloch menciona otro punto en el que hay que tener cuidado: a la hora de deserializar.

Tambien vale la pena revisar revisar el tutorial sobre reflection, viene muy sencillo y preciso:

http://java.sun.com/docs/books/tutorial/reflect/member/index.html

Patrones de diseño: Observer

Con este patrón de diseño se puede implementar vista-controlador.

Este patrón de diseño resuelve el problema de actualizar un objeto cuando otro cambie de estado, estos objetos pueden ser componentes dentro de un frame o incluso otros frames.

Existe un observado (extends Observable) y un observador (implements Observer), el observado notifica al observador cuando cambia de estado, y el observador hace lo que crea conveninte con update(Observable obs, Object o).
Hay formas mucho más sencillas de hacer esto, pero aquí hay un ejemplo, el concepto es sencillo.

package voyerismo;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import javax.swing.JComboBox;

/**
 *
 * @author fal
 *
 * Esta clase hereda de Observable, servirá para el primer combobox.
 * Es como un exhibicionista
 *
 */
public class Observado extends Observable{

	private JComboBox jcombobox = null;

	public Observado(){
		String numeros[] = {"-","UNO", "DOS", "TRES","CUATRO"};
		jcombobox = new JComboBox(numeros);

		jcombobox.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				switch(jcombobox.getSelectedIndex() ){
				//En cada case se cambia el estado, y se notifica a los observadores
				case 1:
					setChanged();
					notifyObservers(jcombobox.getSelectedItem() );
					break;
				case 2:
					setChanged();
					notifyObservers(jcombobox.getSelectedItem() );
					break;
				case 3:
					setChanged();
					notifyObservers(jcombobox.getSelectedItem() );
					break;
				case 4:
					setChanged();
					notifyObservers(jcombobox.getSelectedItem() );
					break;
				default:
					setChanged();
					notifyObservers("");
				}

			}

		});

	}

	/**
	 *  Para obtener el combobox
	 * @return combobox El combobox que será espiado
	 */
	public JComboBox getCombobox(){
		return this.jcombobox;
	}

}

package voyerismo;

import java.util.Observable;
import java.util.Observer;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;

/**
 *
 * @author fal
 *
 * Esta clase es la que observa al observado, es como el que estará espiando
 * al combobox de la clase &amp;amp;amp;lt;code&amp;amp;amp;gt;Observado&amp;amp;amp;lt;/code&amp;amp;amp;gt;
 *
 */

public class Observador implements Observer{

	private JComboBox combo = null;
	private DefaultComboBoxModel modeloLight = null;
	private String[] unos = { "Uno", "1", "i", "a", "I" };
	private String[] doses = { "Dos", "2", "ii", "b", "II" };
	private String[] treses = { "Tres", "3", "iii", "c", "III" };
	private String[] cuatros = { "Cuatro", "4", "iv", "d", "IV" };

	public Observador(){
		modeloLight = new DefaultComboBoxModel();
		combo = new JComboBox(modeloLight);
		combo.setEnabled(false);

	}

	/**
	 * Aqui se implementa el método de la interfaz &amp;amp;amp;lt;code&amp;amp;amp;gt;Observer&amp;amp;amp;lt;/code&amp;amp;amp;gt;
	 * el observado le notifica a éste para que éste haga lo tenga que hacer.
	 *
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
	 *
	 */
	public void update(Observable observado, Object selectedItem) {
		if(observado != null &amp;amp;amp;amp;&amp;amp;amp;amp; (observado instanceof Observado) ){
			if(selectedItem != null){
			String str = selectedItem.toString();
			if(str.equals("UNO") ){
				enfria(unos);
				combo.setEnabled(true);
			}else if(str.equals("DOS") ){
				enfria(doses);
				combo.setEnabled(true);
			}else if(str.equals("TRES") ){
				enfria(treses);
				combo.setEnabled(true);
			}else if(str.equals("CUATRO") ){
				enfria(cuatros);
				combo.setEnabled(true);
			}else{
				enfria(new String[] {});
				combo.setEnabled(false);
			}		
		}

	}

	public JComboBox getCombobox(){
		return this.combo;
	}

	/**
	 * Cambia el modelo(le hace un update)
	 * @param strings
	 */
	private void enfria(String[] strings){
		modeloLight.removeAllElements();
		for (String string : strings) {
			modeloLight.addElement(string);
		}
	}	

}
package voyerismo;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main {

	public static void main(String args[]) {
		JFrame frame = new JFrame();
		JPanel panel = new JPanel();
		Observado observado = new Observado();
		Observador observador = new Observador();

		//Se agregan los observadores al observado
		observado.addObserver(observador);

		JComboBox combo1 = observado.getCombobox();
		JComboBox combo2 = observador.getCombobox();

		panel.add(new JLabel("Observado") );
		panel.add(combo1);
		panel.add(new JLabel("ObservadoR") );
		panel.add(combo2);

		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.add(panel);
		frame.setTitle("Observado y observador");
		frame.setSize(400, 100);
		frame.setVisible(true);

	}

}

Véase también:

http://en.wikipedia.org/wiki/Observer_pattern
http://www.lcc.uma.es/~pacog/apuntes/poo/Tema4-2.pdf
http://www.patterndepot.com/put/8/observer.pdf
http://java.sun.com/j2se/1.5.0/docs/api/java/util/class-use/Observable.html

Equals method

As you may know overriding the equals method could be very important when writing java classes, consider the following:

Always check the implemetation to be:

  • Reflexive: For any x != null x.equals(x) must be true.
  • Symetric: For any x,y != null : x.equals(y) must be equals to y.equals(x).
  • Transitive: For any x,y,z != null : if x.equals(y) is true and y.equals(z) is true, x.equals(z) must be true.
  • Consistent: For any x,y != null : x.equals(y) must returns the same result across invocations unless, the state of of x or y changes.
  • Implement hashcode: If you are overriding equals also override  hashCode()

Also would be good to check:

  • Override equals(Object obj): Using @Override
  • Use instanceof inside the equals method.

A tool that simplify this is:

References:

  • Bloch Joshua, 2008.  Item 8 “Obey the general contract when overriding equals”  Effective Java Second Edition,pp.33.