Master J2EE de Oracle: Paso 1 de 12: Trocear y Rebanar J2EE

Puede encontrar la versión original de este artículo en Inglés en:

http://www.oracle.com/technology/pub/articles/masterj2ee/index.html

Introducción

Entender las necesidades de su aplicación es un largo camino hacia la disminución de la complejidad de J2EE.

Hubo un tiempo, no hace mucho, en que un desarrollador Java podía ver un nuevo proyecto empresarial en Java y saber de un vistazo qué herramientas tenía que utilizar. Era todo tan simple entonces: J2EE era nuevo, el navegador HTML era la norma aceptada como interface de usuario, y la complejidad, al menos supuestamente, era cosa del pasado. Hoy en día, es tan... ¡complicado!

Los Desarrolladores Encaran un Complejo Conjunto de Elecciones

Los desarrolladores se enfrentan a un complejo conjunto de elecciones, que van desde los "contenedores de peso ligero", como Spring, NanoContainer, o HiveMind, a "marcos de trabajo" como WebWork, Tapestry, un UI basado con JSF como el nuevo Application Development Framework de Oracle (Oracle ADF), o Velocity. Si se le añade a esta selección un nuevo conjunto de especificaciones J2EE, o el nuevo énfasis en los "servicios Web" y el correspondiente crucigrama de la "Arquitectura Orientada al Servicio" mediante JAXM, SAAJ, JAX-RPC, o JAX, (sin mencionar las especificaciones, herramientas o librerías de "WS-*"), es un verdadero milagro que los desarrolladores Java puedan hacer algo.

Ben Galbraith, uno de los participantes en el Simposium sobre "No Fluff Just Stuff Software", llama a este fenómeno el 'Principio de Incertidumbre del Marco de Trabajo Java': "Tan pronto como decides utilizar un marco de trabajo, sale una nueva versión de otro marco de trabajo, así una y otra vez". Además no cuesta mucho complicarlo algo más, sólo hay que incluir en la mezcla las clases 'core' de J2EE y J2SE. Después de todo, ¿no fue ayer cuando se hablaba de que EJB era el corazón de J2EE y que sería impensable considerar un proyecto empresarial Java sin utilizarlos? Para ser exactos ¿qué ha experimentado su codificación tras los cambios genéricos en J2EE? Y, por supuesto, ¿quién deja en la puerta todas las Java Management Extensions?

¿Qué ha sucedido? ¿Por qué una industria que en origen estaba tan claramente enfocada en la creación de una plataforma formada por las herramientas y librerías mejores-de-cada-casa se ha visto fragmentada en un periodo de tiempo tan corto? ¿Cuándo debemos elegir entre las herramientas tradicionales de J2EE como EJB, en oposición a las nuevas generaciones de herramientas de "servicio Web" como JAXRPC y WS-Security? y lo que es más importante, ¿qué podemos hacer ahora para evitar el Principio de Incertidumbre del Marco de Trabajo Java de Ben Galbraith sin perder la fuerza de los principios de neutralidad ante el vendedor que expuso Java en un principio?

La mayor parte de problema viene de no conocer qué tecnología cubre mejor cada necesidad, y la mejor forma de hacer esto es imaginar en primer lugar cuáles son las necesidades de nuestra aplicación. Una vez hecho esto, la elección de la tecnología apropiada se ve más clarámente definida y más fácil de entender.

En esta página, se verá una ámplia introducción al estado de J2EE, las tecnologías que lo rodean, y algunos retos arquitecturales que encara un desarrollador Java hoy en dia.

¿A donde queremos llegar hoy?

Muchos tipos diferentes de programas codificados en Java tienden a juntarse bajo el término "Java empresarial" (enterprise Java), y quizás nos ayudará el poder distinguirlos de otros tipos de aplicaciones Java antes de ir demasiado lejos con esta discusión. Si empezamos desde la aproximación tradicional de "3 capas", donde separamos la Presentación, la Lógica de Negocio y el Acceso a Datos en tres estratos de diseño coherentes, entonces podemos identificar cinco tipos esenciales de aplicaciones empesariales Java: stovepipes (tubos de estufa), jewels joyas, aggregators (conjuntadores) , integrators (integradores), y enterprise apps (aplicaciones empresariales).

stovepipes

Stovepipes. Una aplicación stovepipe (también llamada un "silo") es probablemente la más fácil de reconocer por los desarrolladores, porque es una aplicación que hemos creado muchas veces: es la tradicional aplicación de una "sola base de datos y un sólo UI" que actualmente, en términos numéricos, es el tipo de aplicación IT más popular que se está construyendo. Normalmente empieza con el deseo de un manager de departamento o de un sub-manager que busca una herramienta o aplicación específica para obtener, manipular y mostrar algún tipo de datos que actualmente no se están teniendo en cuenta, por eso se forma un equipo (normalmente de un tamaño no mayor de tres o cuatro personas, y muy frecuentemente sólo de una) para obtener los requerimientos, formular los casos de uso, construir la base de datos, codificar la lógica de negocio, desplegarla en la máquina elegida para actúar como el servidor de producción para esta aplicación, y vigilarla de vez en cuando.

El nombre, por supuesto, deriva de la imagen que representa las capas lógicas del sistema (Presentación, Lógica de Negocio y Acceso a Datos) en una pizarra blanca, porque forman una línea vertical, reminiscencias de los viejos tubos de estufas de carbon (stovepipe) que llevaban el humo fuera de la habitación. (Y, por supuesto, para aquellos que usen este término en términos despectivos, recuerden que muchos de los sistemas más importantes que utilizarán en toda su vida ,como la máquina ATM, el localizador de paquetes de las principales compañías de paquetería, etc. son sistemas stovepipe).

Tan extraordinario como podría parecer, el conjunto de software J2EE no sirve para que los desarrolladores construyan el sencillo sistema stovepipe. Cuando sólo se requiere una capa de presentación, la complejidad de J2EE, particularmente EJB, sólo parece "estar en el camino". Se vuelve más tentador considerar los marcos de trabajo de peso ligero, porque no se enfoncan tanto en los descriptores de despliegue, y no hay tanta preocupación sobre JNDI, JMS, o cualquier otra materia. El implementar una comunicación básica, petición/respuesta desde el navegador web, normalmente construido en algo como Struts o un marco de trabajo similar del estilo MVC, para hablar con la lógica de negocio centralizada en un conjunto de Viejos Objetos Java, algunas veces con las capas de presentación y lógica de negocio (si no también la propia base de datos) ejecutándose en la misma máquina. (Se podría estar preguntando por qué no aparece aquí el término "base de datos". La sencilla razón es que aunque la mayoría de los proyectos utilizan una base de datos, más o menos relacional, para almacenar los datos, frecuentemente lo datos se almacenan en sistemas antiguos, paquetes de software comerciales, o tecnología "broker", un sistema CICS, SAP o BizTalk. Utilizar el término más genérico de "recursos" ayuda a reforzar la idea que la implementación final es realmente irrelevante en este nivel de discusión).

Los Stovepipes también tienen la ventaja de que tienden a ser "independientes": no hay más jugadores implicados. Hay poca necesidad de ajustarse a ningún estándar establecido de seguridad, eficiencia, o control, ya que lo que esta aplicación defina será el estándar (al menos para esta aplicación, y esto es todo lo que importa en este ámbito). Los desarrolladores se suelen aprovechar de este hecho para construir infraestructuras que son "suficientemente buenas" para esta aplicación, y así evitar la acusación más frecuente que se hace de las aplicaciones empresariales Java: son demasiado complejas de utilizar y de mantener.

A pesar del deseo de etiquetarlas como tal, el escenario de aplicaciones stovepipe no es lo único para lo que se diseñó J2EE - ciertamente una aplicación basada en J2EE puede construir este tipo de aplicación (y hay miles de ellas por ahí fuera), la verdad es que es como "utilizar granadas para pescar". Una aplicación basada en J2EE fuerza cierta separación de capas, y algunas veces esto sobrepasa el problema real, como es el caso de los sistemas de tubería de estufa de 10 usuarios. Por supuesto, el problema es que este tipo de sistemas, tiene la aburrida tendencia de convertirse en una de las otras cuatro versiones, y aquí es donde las cosas se empiezan a complicar. Como el filosofo que dijo "nadie es una isla", nosotros podemos asegurar que "ningún sistema es una isla". Al menos, no por mucho tiempo. (Por supuesto, si el sistema no consigue los resultados deseados, no se integrará con ningún otro sistema y probablemente no estará en producción durante mucho tiempo, pero asumiremos que este no es el resultado deseado).

Joyas

No, no en el sentido de que este tipo de aplicaciones sean las joyas de la corona del entorno IT o "lo mejor de lo mejor", el estilo de aplicaciones 'joya' es aquel que posee varias capas de presentación (de ahí su nombre -- una 'joya' tiene muchas caras por las que mirar). Observe, sin embargo, que una capa de presentación dada podría no ser alqo para que lo vieran los usuarios (en estos días hay muchas compañias que están discutiendo sobre una capa de servicio web para sus apliaciones) es decir, puede no estar pensada para el consumo humano. A pesar de este hecho, los servicios web aún representan una capa de presentación, ya que fundamentalmente hacen las mismas cosas: toman una entrada y proporcionan una salida,

Las aplicaciones joya presentan algunos giros interesantes al modelo de programación tradicional, porque algunas suposiciones que se daban por ciertas, ya no lo son. Por ejemplo, cuando se considera una servicio Web, de repente es necesario definir tipos para algún tipo de plataforma de una forma neutral al lenguaje (el esquema XML es la herramienta actual para este tipo de trabajo), e idealmente la regla 'una-y-solo-una-vez' (también conocida como 'no lo repita usted) nos ayudará a construir esto directamente desde los mismos tipos que usa la capa de presentación HTML para hablar con la capa de Lógica de Negocio. Aquí es donde entran en juego las especifiaciones JAX -- el API Java para Uniones XML, por ejemplo, ayuda a definir una forma estándar de hacer transformaciones objeto-a-XML y viceversa de una forma bastante opaca, y el API Java para XML RPC (JAX-RPC) define una forma de construir capas de comunicación remota del tipo petición-respuesta utilizando WSDL, SOAP y XML.

Aunque nada impide a un desarrollador utilizar las especificaciones JAX* de su contenedor de peso ligero favorito, la especificación 1.4 de J2EE incorpora JAX-RPC y JAXB directamente en su suite tecnológica, haciendo posible exponer un EJB de sesión sin estado como un servicio Web WSL 1.1/SOAP 1.1 RPC/encoded. (Observe que de acuerdo a la especificación WS-Interoperability Basic Profile, los servicios RPC/encoded se han quedado obsoletos oficialmente en favor de document/literal; esta diferencia se corregirá en la siguiente versión de las especificaciones JAX* y J2EE, y las implementaciones concretas deberían salir a la calle en el mismo momento en que los desarrolladores se den cuenta de las diferencias entre los servicios RPC/encoded y document/literal.) Además, los vendedores de aplicaciones comerciales están sufriendo para asegurarse de que sus ofrecimientos no sólo son totalmente compatibles con los estándars J2EE, sino también con los estándars de los servicios web.

Además, cuando se busca construir una capa de presentación de un servicio Web aparece la tentación de exponer los objetos del Modelo del sistema directamente como tipos XML, utilizando JAXB o el Kit de desarrollo XML de Oracle, y esencialmente generar el código de todo el servicio web como un enorme documento WSDL. Aunque esto podría parecer una buena validación para una de las capas de Lógica de Negocio a primera vista, después de todo, realmente no hay ninguna regla de negocio en la capa de presentación, por eso no debería ser difícil tomar esta aproximación, las limitaciones en la tecnología de servicios Web hace que esto sea difícil.

Considere, por ejemplo, la relación de objetos basados-en-referencia a XML: ¿cómo se representará mejor en XML una referencia java.util.Date cuyo valor es null? Particularmente cuando en .NET un Date no es un tipo referencia sino un "tipo valor", lo que significa que actúa igual que un int de Java. Las cosas se vuelven particularmente difíciles cuando se intentan representar complejos gráficos de objetos en XML, que es una de las razones por las que se ha quedado obsoleto RPC/encoded. Todo esto forma parte del trabajo actual que hay detrás de la suite WS-*, pero incluso si un equipo decide "ir por el camino" y construye su propio sistema XML-sobre-HTTP, van a encontrarse con el mismo problema. Hay algún esfuerzo para intentar incorporar mapeos de objeto-XML, como el Oracle Toplink, pero todavía están en sus estados iniciales.

Mientras tanto, no podemos ignorar la nueva tendencia en la aproximación de capas de Presentación (para el cliente "inteligente" o "rico") diseñado para cubrir el gran agujero en las aplicaciones tradicionales basadas en web, tiene algunos defectos fundamentales, dos de los cuales vienen en seguida a la mente:

  • Perspectiva del mínimo-denomidador-común:
    HTML fue pensado originalmente para diferir lo más posible las decisiones de presentación, por eso sólo unos pocos elementos del estándar HTML realmente ofrecen garantías sobre el modo de renderizado. Los intentos de dar un mayor control a los constructores de páginas, como CCS, han tenido distinto éxito, perticularmente entre diferente navegadores.
  • Se debe enviar el código de presentación junto con el contenido:
    Como el navegador no tiene conocimiento hereado de la aplicación, se debe enviar todo el cojunto de herramientas para la presentación junto con el contenido en cada conexión con el servidor. Esta aproximación tiene dos impactos negativos, uno es la reducción del ancho de banda (mayor consumo por cada cliente significa menos clientes para el mismo hardware) y el otro es la disponibilidad (si el servidor o algún elemento topológico se apaga, no hay más aplicación).

En estos momentos, los vendedores de aplicaciones empresariales están pensando en poner código de la capa de presentación en la máquina del usuario final, y así eliminar parte o todas las principales desventajas del HTML. Esto crea algunas implicaciones de despliegue interesantes, por eso muchos vendedores están buscando hacer un cliente rico y uno pobre simultáneamente en la capa de presentación. El cliente rico para usarlo dentro del firewall de la compañia, y el pobre para utilizarlo fuera de él (asumiendo otra vez que nunca se puede ser demasiado rico o demasiado pobre). Esta aproximación levanta el espectro de tener que tratar con dos marcos de trabajo diferentes, y al fnal nos gustará tener una forma unificada de enviar datos de las pulsaciones del usuario al repositorio del motor, y estaría bien que esto se pueda hacer de forma estándar en los dos tipos de clientes "rico" y "pobre", (de ahí ha salido el marco de trabajo para uniones de datos JSR 227).

Agregadores

Igual que un sistema puede ofrecer múltiples "puntos de entrada", si lo desea, un sistema también puede estar construido sobre múltiples motores, juntando datos de diferentes recursos y presentándolos de una forma coherente y amigable. (De ahí el término "agregador", ya que los datos presentados y manipulados son una suma de varios recursos/bases de datos). Y, unos 30 segundos después de empezar a crear los casos de uso para manipular y almacenar estos datos agregados, se ve claro que es necesario algún tipo de atomicidad para mantener sincronizadas las dos bases de datos con las modificaciones que se les están enviando. El API Java Transaction se creó para cubrir este espacio (y las especificaciones X/A antes de esto), y la intersección del porcesamiento transacional y la lógica de negocio fue para lo que se crearon los EJB.

Sin embargo, no es sólo transaciones. Múltiples recursos significa mucho más que sólo dos bases de datos diferentes; algunas veces un sistema necesita un mayor rendimiento que el que puede proporcionar una sóla máquina de base de datos. Después de todo, una sóla máquina en cualquier lugar del sistema representa un único punto de fallo, y normalmente todos los escenarios de fallos son en caliente, junto con los paros necesarios de la base de datos para realizar tareas de mantenimiento (que pueden incluir un cambio en el esquema para acomodar el código). Java Naming and Directory Interface (JNDI) sirve cómo un único API para todas las operación de "búsqueda", proporcionando una capa de indirección de la máquina física donde se encuentra la base de datos, lo que significa que si usted no cachea los resultados de la búsqueda JNDI, un administrador puede modificar la entrada JNDI para que apunte a otra máquina, y la aplicación J2EE simplemente seguirá el enlace, y así crear un interruptor sencillo y transparente hacia una nueva base de datos que no sería posible sin la capa de indirección.

Integradores

Cuando necesitamos conectar dos colecciones de lógica de negocio mantenidas de forma saparada, entra en juego un sistema integrador, y es necesario empezar a pensar en la interoperabilidad de una forma en que nunca lo haría un sistema de tubería de estufa. Por ejemplo, si es necesario hacer un servicio tradicional de petición-respuesta ¿cómo se llevarán a cabo la petición y la repuesta? Normalmente, los desarrolladores inmediatamente llegan al conjunto de servicios WS-*, pero como se mencionó mas arriba, algunas veces las especificaciones WS-* son demasiadas (y demasiado poco cocinadas en sus implementaciones actuales) para servir eficientemente en las necesidades de integración/interoperatibidad. De nuevo, la Especificación J2EE cubren esta base, requiriendo que todo contenedor EJB sea compatible con llamadas CORBA, lo que significa que un cliente CORBA puede interactuar con la Lógica de Negocio encapsulada en un contenedor EJB.

Sin embargo, no toda la integración ocurre en la forma de petición-respuesta. Para poder evitar los cuellos de botella implícitos en la naturaleza síncrona de RPC y las comunicaciones petición-respuesta, muchos sistemas eligen integrarse con otros usando una aproximación dirigida al mensaje, que es la base de la especificación Java Messaging Service (y sus implementaciones asociadas, como Advanced Queueing de Oracle), y/o el API Java para Mensajería XML (JAXM) y sus API SOAP for Attachments in Java (SAAJ), para hacer "mensajería con corchetes angulados".

La propia base de datos también sirve como una capa de integración, aunque no en el mismo sentido que los sistemas tradicionales de RPC o dirigidos a mensaje. En muchos casos, la integración y la interoperabilidad es sólo cuestión de obtener los datos desde un programa "A" al programa "B", y las bases de datos (junto con otros recursos) normalmente sirven como una útil (y bien entendida) lengua franca para diferentes plataformas, más notablemente J2EE y .NET. Aunque esto no corrige las necesidades de interoperabilidad, para muchos sistemas esta aproximación es "suficientemente buena" y comparten sus beneficios, particularmene cuando la Lógica de Negocio está embebida (mediante procedimientos almacenados). Además .NET no tiene necesidad de imaginarse cómo llamar a código Java residente en un servidor EJB, ni Java tiene que imaginarse como llamar a código .NET residente en un ServicedComponent COM+, o como compartir una única ID de transación distribuida, etc. Particularmente viendo el hecho de que Oracle ha facilitado la escritura de procedimientos almacenados permitiendo que se puedan escribir en Java en lugar de en PL/SQL.

Aplicaciones Empresariales

Finalmente hemos llegado a la "verdadera" aplicación empresarial, que se convierte en una amalgama de múltiples facetas de la tres capas, Presentación, Lógica, y Acceso a Datos. El sistema empresarial tradicional es aquel que necesita presentar datos de varios recursos en una variedad de formatos utilizando una colección de reglas de negocio que se expanden a través de múltiples aplicaciones, lenguajes o plataformas. Este espacio es donde encontramos la mayor complejidad, y es aquí donde realmente brilla J2EE. Una vez aquí, la aparente "sobre-complejidad" de la Especificación J2EE y sus tecnologías asociadas se vuelven más apropiadas porque con la complejidad viene el poder (y la flexibilidad).

Los Portales, por ejemplo, caen frecuentemente en esta categoría, ya que tienden a necesitar multiplicaciones de las tres capas. Presentación, en la que el portal ofrece diferentes aplicaciones web para toda la compañia (o departamentos, o diferentes compañias, incluso de diferentes familias). La Lógica de Negocio, en la que algunas veces un "portlet" dado querrá o necesitará llamara a las funcionalidades expuestas por un motor de portlet diferente. Y el Acceso A Datos, en la que mayoría de los portlets tienen sus propia base de datos (o conjunto de bases de datos, sólo para hacer las cosas más interesantes) contra las que necesitan interactuar, pero aún más interesante, frecuentemente una sesión de usuario dada necesita seguir el progreso de la información incluso cuando el usuario se mueve por los distintos portlets. De muchas maneras, el portal y sus portlets asociados son el ejemplo de una aplicación empresarial.

¿Dónde nos deja esto?

Este tipo de categorización es suficientemente bonito por si mismo, y ciertamente mantiene un poco más ocupados a los filósofos de la tecnología, pero precisamente, ¿qué tiene esto que ver con la construcción de aplicaciones empresariales Java hoy en día?

Primero y más importante, es necesario que los desarrolladores empresariales Java se imaginen, tan rápido como sea posible cuál de los cinco tipos de aplicaciones anteriores se les ha solicitado. Si es un sistema tradicional de tubos de estufa, la elección de la tecnología no es tan crucial como para cualquiera de las otras cuatro. Cuando llegue a la cuestión de los servicios Web, reconozcala como otra capa de Presentación (lo que significa que está buscando una aplicación 'joya') y no simplemente como una extensión de su modelo de objetos utilizado entre el código de Struts y la Lógica de negocio. De hecho, de muchas formas, el patrón Modelo-Vista-Controlador forma parte de la propia capa de presentación, y no es algo que se expanda dentro de la capa de Lógica de Negocio, porque hacer una capa de Presentación "diferente" normalmente requerirá que se hagan diferentes elecciones en el modo de interactuar con el motor, como (en el caso de los servicios Web) dejar detrás la naturaleza "orientada-a-objetos" del sistema.

Cuando alcance la cuestión de múltiples bases de datos u otros motores, piense en los fallos de atomicidad y la necesidad de las transaciones distribuidas para conseguir esta atomicidad, y las implicaciones de los fallos para tener una buena capa intercambiable en caliente de indirección para acceder a los recursos. Cuando la integración entre sistemas existentes se convierta en un problema, recuerde que hay más opciones además de los Servicios Web (aunque la aproximación de los servicios Web se está volviendo cada vez más viable y se asume como la norma), y tenga en cuenta los sistemas dirigidos-a-mensaje así como la posibilidad de poner la Lógica de Negocio dentro de la propia base de datos para hacerla más accesible a las otras plataformas que necesitan integrarse con el sistema.

Recuerde que J2EE es sólo un final, que ser demasiado dogmático con una tecnología hace que se pierda la globalidad de esta tecnología. No busque utilizar EJB en sistemas de tubos de chimenea, por ejemplo, ya que el foco principal de EJB está en el procesamiento transacional (y, en particlar, el procesamiento de envíos transacionales en dos fases, que es muy costoso pero necesario para obtener la atomicidad entre dos o más recursos que forman parte una misma transación), pero no rechace su utilización cuando se trate de aplicaciones agregadoras. No intente codificarlo todo dentro de un bean de sesión cuando la naturaleza asíncrona de JMS (y de los beans dirigidos-a-mensaje, cuando se requiere el procesamiento transacional) sirve mejor a este propósito.

Segundo, aségurese de tener siempre en cuenta cuáles son los requisitos de rendimiento y escabilidad de la aplicación. Aunque esto es siempre importante para cualquier aplicación escrita en cualquier lenguaje, es incluso más importante en el espacio empresarial Java, precisamente debido al amplio rango de tecnologías disponibles para el desarrollo empresarial en Java. ¿Su sistema necesita refrescar las respuestas cada segundo o menos, tras una acción del usuario? Este objetivo será difícil de conseguir en una aplicación basada en navegador, particularmente dentro de una WAN, porque normalmente un navegador HTML tarda alrededor de un segundo en procesar una página HTML moderamente complicada; quizás una mejor aproximación sería considerar un "cliente rico" entregado mediante JavaWebStart, para mantener la cantidad de datos enviados lo más pequeña posible, y consecuentemente reducir el tiempo de respuesta (evitando así la necesidad de analizar los elementos de presentación).

¿Necesita alcanzar una previsión de 10 millones de usuarios en Internet? Entonces, necesita modificar el interface de usuario. La falta de ubicuidad de Java en la mitad de los PCs de los consumidores hace que WebStart sea impracticable en dicha situación, y quizás un applet o un HTML tradicional sean más apropiados. Sin embargo, el escalado hasta este número de usuarios significa que los desarrolladores deben prestar una atención especial al tiempo de respuesta por cada petición a altas cargas, y quizás construir el interface de usuario de forma diferente para evitar retornos innecesarios al servidor.

Tercero, tenga en cuenta que el conjunto de herramientas del desarrollador de Java está en constante evolución, y la mayoría del trabajo de los últimos cinco años se ha realizado en el espacio de J2EE, busque formas más sencillas de definir componentes J2EE. En este área es donde los vendedores comerciales tienen ventaja sobre los proyectos open-source, ya que el vendedor puede crear un desarrollo de principio-a-fin sobre sus ofrecimientos comerciales, mientras que un proyecto open-source tiene la tendencia de expandirse sólo hasta alcanzar el límite de la experiencia del equipo de desarrollo, y luego se paran. Eche un vistazo a las nuevas caracteríticas que vienen con Oracle ADF en comparación a intentar construir una aplicación JSF en Eclipse, por ejemplo.

Conclusión

Aunque el mundo empresarial Java algunas veces puede parecer un embarullado bosque de especificaciones, implementaciones, estándars 'de facto' y marcos de trabajo que parecen seguir el favoritismo del 'sabor-del-mes'; respire profundamente y dese cuenta que para cualquiera de los cinco tipos de aplicaciones, se puede utilizar cualquier tecnología J2EE (y todas funcionarán bien).

Próximos Pasos

Descargas Necesarias:

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP