Muchos sistemas que actúan como servidores necesitan mantener una gran escalabilidad y
por lo tanto no pueden arriesgarse a que se agoten las conexiones. ¿Qué se puede hacer?
En un pool de conexiones cada una de éstas es utilizada por múltiples clientes diferentes. Los
clientes abren la conexión, acceden al servicio a través de ella y por último cierran dicha
conexión. Es importante que el cliente abra y cierre la conexión en cada acceso al servicio ya
que si no la cerrase no la estaría devolviendo al pool y por lo tanto correríamos el riesgo de
agotar los recursos del servidor.
Normalmente, en estos casos, es preferible utilizar streams para generar la salida. De este
modo se realiza un transferencia directa de bytes a bytes sin realizar ninguna
transformación.
Jason Hunter, en el libreo Java Enterprise Best Practices de O'Reilly expone el ejemplo
siguiente:
import java.io.*;
import java.util.prefs.*;
import javax.servlet.*;
import javax.servlet.http.*;
returnFile(file, out);
}
Internamente esto se consigue de dos modos: creando una cola de peticiones para entrar a
cada Servlet y JSP que implementen el modelo SingleThreadModel o creando un pool de
instancias del Servlet de modo que se garantice que a cada instancia accede únicamente una
petición.
La primera de las opciones supone una degradación importante de rendimiento por lo que
normalmente se implementa la segunda. El problema surge en que con este segundo modelo
múltiples peticiones accederan al mismo Servlet simultáneamente ( ojo, no a la misma
instancia del Servlet ).
Esto es un problema muy grave ya que los desarrolladores pueden creer que no necesitan
sincronizar los elementos compartidos a los que acceden ( por ejemplo bases de datos,
variables críticas, etc. ) y sin embargo la realidad es que se está accediendo
simultánemanete a dichos elementos desde diferentes instancias del Servlet.
Actualmente, esta definición resulta bastante limitada. Los motores de persistencia no sólo
nos permiten hacer persistentes nuestros objetos, sino que también nos permiten realizar
consultas complejas que nos ofrezcan jerarquías completas de objetos, realizan
optimizaciones automáticamente, resuelven asociaciones y dependencias, etc.
Por ejemplo. Con el motor de persistencia Hibernate guardar en base de datos una instancia
de una clase Gato con sus n crías se reduciría a :
Gato gato = new GatoDomestico();
Gato cria = new GatoDomestico();
...
Set crias = new HashSet();
crias.add(cria);
gato.setCrias(crias);
session.save(gato);
Casi todos los motores de persistencia utilizan ficheros de configuración (normalmente en
XML) para definir la asociación entre las diferentes clases y almacenamiento secundario. Por
otra parte, normalmente estas clases son generadas automáticamente a partir de estos
ficheros de configuración por loq ue el desarrollador tampoco tiene que perder el tiempo
creándolas.
¿Sabes por qué en los EJB cuando accedemos a una referencia remota desde un EJB
o desde un cliente tenemos que utilizar PortableRemoteReference.
narrow(..)? (javaHispano)
EJB utiliza como protocolo de comunicación remoto RMI-IIOP. Este protocolo permite unir los
mundos de Java (RMI) y CORBA (IIOP) de modo que un cliente en cualquier lenguaje pueda
comunicarse con un Enterprise Java Bean escrito en Java.
Como CORBA es una plataforma que soporta múltiples lenguajes se nos presenta un
problema. No todos los lenguajes de programación soportan el concepto de cast por lo que
es imposible realizar automáticamente casts de objetos que provengan de RMI-IIOP a
objetos Java. Con el método PortableObjectReference.narrow(objeto, clase) explicitamos que
queremos transformar ese objeto a una instancia de la clase que le pasamos como
parámetro.
Esto no deja de ser bastante molesto cuando estamos trabajando únicamente en entornos
basados en Java pero es el precio de la interoperabilidad.
Un EIS ha de ofrecer una serie de servicios a sus clientes, exponiendose éstos a través de
una serie de interfaces locales o remotas, es decir, el cliente normalmente puede trabajar
localmente al EIS o desde un puesto de su intranet o incluso desde fuera de ésta.
• Sistemas ERP
• Sistemas de procesamiento de transacciones en mainframes
• Bases de datos heredadas
Normalmente los EIS ofrecen una API para el acceso externo desde otras aplicaciones. Esta
API suele exponer los servicios más importantes de un EIS. Cada sistema y cada fabricante
tiene sus propias APIs y estas son muy diferentes entre si por lo que la integración con
múltiples sistemas EIS suele ser compleja.
Java tiene un magnifico soporte de este tipo de sistemas gracias a la especificación JCA
( Java Connector Architecture ) que especifica un conjunto de interfaces estándar para
acceder a cualquier tipo de sistemas EIS.