Bitsmi Blog

OCP7 02 – Diseño de una clase Java

01-07-2014 - Xavier Salvador

more…

OCP7 03 – Diseño de una clase Java

01-07-2014 - Antonio Archilla

En este apartado se introducen conceptos relacionados con el diseño de una clase.

more…

OCP7 05 – Herencia en las interfaces Java

01-07-2014 - Xavier Salvador

Uso de las interfaces Java

Una interfaz representa una alternativa a la herencia multiple de objetos. Son similares a las clases abstractas ya que contienen únicamente métodos públicos y abstractos. Ninguno de sus métodos pueden ser implementados (ni siquiera con un conjunto vacío de llaves). La declaración de una interfaz es similar a la declaración de una clase. Se usa la palabra reservada interface. Para la implementación de una interface se añade implements a la clase que implementa la interfaz. Una interfaz puede utilizarse como un tipo de referencia. Puede utilizarse el operador instanceof con las interfaces para detectar si un objeto es del tipo de referencia indicado por la interfície implementada. Interfaces de Marcador: definen un tipo concreto pero no describen los métodos que deben ser implementados por una clase, sólo sirven para la comprobación de tipos.

Existen dos tipos:

  • java.io.Serializable és una interfaz de marcador utilizado por la biblioteca de E/S de Java para determinar si un objeto puede tener su estado serializado.

Como convertir de un tipo de dato al tipo de la interfaz

Antes de generar una excepción en la conversión de tipos de unos objetos a otros objetos se comprueba que dicha conversión sea posible mediante la utilización del operador instanceof (ya comentado anteriormente).

En general, cuándo se utilicen referencias, éstas deben utilizar el tipo más genérico posible, es decir, que sirvan para cualquier tipo de interfaz o clase padre. Así la referencia no se vincula a una clase particular.

Una clase puede heredar de una clase padre e implementar una o varias interfaces pero siempre en este orden: primero hereda – extends – y después implementa – implements – separando las interfaces mediante comas.

Una interfaz puede heredar de otra interfaz. Java no permite la herencia múltiple de clases pero sí la herencia múltiple de interfaces:

Si escribimos una clase que hereda de una clase que implementa una interfaz, entonces la clase que estamos escribiendo hereda también de dicha interfaz. La refactorización consiste en realizar modificaciones en el código para mejorar su estructura interna sin alterar su comportamiento externo.

Composición

Este patrón de diseño permite la creación de objetos más complejos a partir de objetos más simples. Se crea una nueva clase con referencias a otras clases. A esta nueva clase le agregaremos los mismos métodos que tienen las demás clases.

public class ComplexClass {
    private Single1 c1 = new Single1();
    private Single2 c2 = new Single2();
    private Single3 c3 = new Single3();
}

Referencia al polimorfismo

Vamos a describir un ejemplo de polimorfismo. Si existe una clase nueva llamada Hombre que dispone de un método addCoche con la configuración de clases establecida en la siguiente imagen:

No se le puede pasar como argumento al método addCoche de Hombre cualquier tipo de coche. Solución: Para soportar el polimorfismo en las composiciones cada clase usada en la composición debe disponer de una interfaz definida y así se le podrá pasar cualquier tipo de coche al método en cuestión.

more…

OCP7 13 – Localización

01-07-2014 - Xavier Salvador

Localización

La localización o regionalización es el proceso mediante el cual un producto internacionalizado se configura para una determinada región, aprovechando las opciones que la internacionalización previa de este producto ha permitido (i18n). Por ejemplo, la internacionalización puede permitir utilizar distintos formatos de fecha, y la localización consiste en escoger el adecuado para una región específica.

more…

OCP7 11 – Hilos (01) – Introducción

20-06-2014 - Antonio Archilla

En este apartado se exponen los conceptos básicos referentes del diseño de programas concurrentes y paralelos y los mecanismos que la especificación estándar de Java pone a disposición del programador para conseguirlo.

Se tratarán los siguientes conceptos:

  • Cómo el sistema operativo gestiona los procesos e hilos.
  • Ciclo de vida de un hilo de ejecución.
  • Sincronización y comunicación de datos entre hilos de ejecución.

more…

OCP7 07 – Manejo de Cadenas

18-06-2014 - Xavier Salvador

Argumentos y formatos de cadenas

El método main contiene el parámetro String[] args. Puede recibir cero o más argumentos. La implementación de la clase es la siguiente.

public class Echo {
 public static void main(String[] args) {
  for (String s: args) {
   System.out.println(s);
  }
 }
}

La clase Echo puede recibir los siguientes parámetros por línea de consola de comandos.

java Echo Enero Febrero Marzo Abril

Pasándole como argumentos en la línea de comandos los cuatro primeros meses del año.

Cada uno de los meses separados por un salto de línea. Esto es así debido a que el carácter espacio se utiliza para separar los parámetros unos de otros mediante un salto de línea entre cada uno.

Si se quiere mostrar un frase o texto completo, por ejemplo

java Echo "Enero, Febrero, Marzo, Abril son los cuatro primeros meses..."

se debe indicar la apertura y el cierre del texto mediante comillas dobles "".

Debe tenerse en cuenta que los arrays SIEMPRE empiezan con el valor 0, nunca con el 1. Para recuperar los parámetros recibidos mediante el método main se utilizan los indices del vector. Así con el código args[0] se recupera el primer parámetro, con args[1] se recupera el segundo, etc.

Adicionalmente, si una aplicación necesita recibir argumentos de tipo numérico, debe convertirse el argumento de tipo String a un argumento que represente un número, como por ejemplo el 34, a su valor numérico equivalente, el 34.

Este snippet transforma un argumento de consola de comandos en un tipo entero:

int primerArg;
if (args.length > 0) {
    try {
        primerArg = Integer.parseInt(args[0]);
 
System.out.println("Se ha convertido la cadena "+args[0]+" en el número siguiente -> "+primerArg);
    } catch (NumberFormatException e) {
        System.err.println("Argumento " + args[0] + " debe ser un número entero.");
        System.exit(1);
    }
}

primerArg lanza una excepción del tipo NumberFormatException si el formato de args[0] no es valido. Todas las clases de tipo NumberInteger, Float, Double y demás — disponen de métodos de conversión que transforman un String representando un número en un objeto de su tipo específico.

Formatos de cadena

Los distintos argumentos de conversión que podemos utilizar para modificar el aspecto de una objeto String son los siguientes:

Cómo ejemplo inicial para limitar el número de caracteres que se visualizan por pantalla es suficiente con utilizar %2.2x dónde x corresponde al argumento de conversión que se haya pasado.

PrintWriter

PrintWriter es una nueva clase de impresión bastante similar a Printf perteneciente a la librería java.io. Puede encontrarse su Javadoc aquí.

PrintWriter pw = new PrintWriter(System.io, true);
 
pw.printf("Texto escrito mediante Pw");

Procesamiento de Cadenas

Dentro del JDK en su versión del Java 7 existen varias clases Java que permiten manipular y tratar los elementos de tipo cadena. Son clases ya existentes en versiones anteriores del JDK.

String

Representa una cadena de caracteres inalterable. Al modificar un objeto String lo que estamos haciendo en realidad es crear otro objeto String. No es la más eficiente ni la mejor. Ideal para tratar con cadenas de texto cuyo valor sabemos que no se modificará: mensajes de alerta, texto, informativo, etc.

StringBulider / StringBuffer

Debe utilizarse cuándo debamos trabajar con cadenas de texto que deban modificar su contenido en tiempo de ejecución. Ambas disponen del mismo API de desarrollo. Como norma general utilizaremos StringBuilder en lugar de StringBuffer.

Razón: Los métodos de StringBuffer son sincronizados por lo que pueden ser utilizados de forma segura en un ambiente multihilo. Los métodos de StringBuilder no son sincronizados por lo que su uso implica un mejor rendimiento cuándo se usan localmente.

En general, la concatenación de Strings ocurre con variables locales a un método por lo que es recomendable utilizar de forma general StringBuilder en lugar de StringBuffer.

Cuan rápido es StringBuilder sobre StringBuffer?

StringBuilder puede resultar un 50% más rápido para concatenar String.

Para esta implementación.

public class StringBuilder_vs_StringBuffer {
 
    public static void main(String[] args) {
        StringBuffer sbuffer = new StringBuffer();
        long inicio = System.currentTimeMillis();
 
        for (int n = 0; n < 1000000; n++) {
            sbuffer.append("zim");
        }
 
        long fin = System.currentTimeMillis();
        System.out.println("Time using StringBuffer: " + (fin - inicio));
 
        StringBuilder sbuilder = new StringBuilder();
 
        inicio = System.currentTimeMillis();
 
        for (int i = 0; i < 1000000; i++) {
            sbuilder.append("zim");
        }
 
        fin = System.currentTimeMillis();
        System.out.println("Time using StringBuilder: " + (fin - inicio));
 
 
    }
}

Obteniendo casi una mejora del 50% utilizando StringBuilder.

Clases Auxiliares en la Manipulación de cadenas

StringTokenizer

Extrae información (en forma de tokens) de una cadena de texto cuyos caracteres están separados por un carácter o símbolo especial o separador. Recorre la cadena de texto y obtiene las cadenas obtenidas (tokens) a partir del símbolo especial o separador indicado en la llamada al método.

// Inicialización
StringTokenizer  st = new StringTokenizer("this is a test");
 
// Utilización
while(st.hasMoreTokens())  {
      System.out.println(st.nextToken())
}

Puede encontrarse información más detallada dentro de la API de Java 7 en la siguiente dirección.

Scanner

Extrae información de una cadena o flujo de datos como StringTokenizer. Cambia el tipo de dato a las divisiones mientras se itera sobre ellas (StringTokenizer no puede), es decir, ante un flujo de datos podremos capturar enteros, decimales, etc en función de nuestro método de iteración utilizando Scanner.

more…

Error de codificación Unicode en un mensaje Javascript

16-06-2014 - Xavier Salvador

Descripción del Problema

Cuando se publica un mensaje que contiene un carácter en formato Unicode no muestra el texto correctamente. No se renderiza el carácter Unicode en Javascript sino que se muestra directamente la codificación

Análisia del Problema

En el fichero JSP contenedor se encuentra la siguiente llamada:

<a onclick="return(confirm('Mensaje de llamada previo al mu00E9todo?'));" 
	href="<ruta_web_navegacion>"
>

Cuando el navegador renderiza el botón y procesa la funcionalidad del atributo onclick no renderiza correctamente el texto contenido dentro de los confirm como carácter Unicode desde el Javascript, sino que lo interpreta como un string que forma parte de la cadena contenida dentro del confirm .

Solución

Hay que añadir en el JSP una sección Javascript donde se implementa la siguiente función:

<script>
function metodo() {
	return confirm("Mensaje de llamada previo al mu00E9todo?");
}
</script>

Esta nueva función renderiza directamente el texto contenido en el mensaje desde Javascript no desde HTML.

En el código HTML del enlace hay que indicar en el atributo onclick el siguiente código para ejecutar correctamente la ventana confirm y posteriormente el envío del resultado al onclick del botón:

<a onclick="return(metodo());" 
	href="<ruta_web_navegacion>"
>

Esto permite que la codificación Unicode sea interpretada correctamente y se obtiene el carácter é lugar de la codificación ue00E9 cuando se muestra el mensaje por pantalla.

Detalle

El método confirm devuelve el resultado de la opción elegida cuando se abre la ventana mediante Javascript.

Lo que se está haciendo se redirigir este regreso (sea true o false) hacia el botón onclick de manera que se ejecute directamente o no según la selección de las opciones del confirm Javascript que se haya efectuado.

more…

Error Adobe AcroExch. al insertar un PDF en un documento de Word

09-05-2014 - Xavier Salvador

Se dispone de un documento PDF de unos 2 Mb i es desea incrustar en un documento de Word estándar (independiente de versión de Office).

Al intentar realizar la incrustación se abre una ventana de alerta con el siguiente mensaje de error:

El programa usado para crear este objetivo es AcroExch. Dicho programa no está instalada en el equipo o no responde. Para editar este Objeto, Instale AcroExch o asegúrese de que todos los cuadros de diálogo de AcroExch están cerrados.

Es un problema relacionado con una opción de seguridad del Adobe Acrobat Reader. El programa por defecto dispuesta de la opción Activar modo protegido al iniciar. Así para solucionar el problema lo que hay que hacer es seguir los siguientes pasos:

  • Abrir la Adode PDF Reader (múltiples versiones)
  • Acceder a la opción Editar
  • Acceder a la opción Preferencias
  • Dependiendo de la versión del Acrobat puede ser la opción de General (Adobe Acrobat X) o la opción Seguridad (mejorada) (Adobe Acrobat XI). En otras versiones el nombre de la opción es el mismo, hay que buscarlo para encontrar el lugar donde aparezca.
  • Hay que desactivar la opción Activar modo protegido al iniciar.

Ahora si se realiza de nuevo la inserción del documento PDF dentro del documento de Word no se volverá a mostrar el error y finalizará la incrustación correctamente.

more…

Cálculo del tamaño de una BBDD Oracle

08-05-2014 - Xavier Salvador

Incluye el tamaño de los archivos de datos en la búsqueda

El tamaño total incluye tablas, campos, procedimientos almacenados y otros objetos de la base de datos.

Calcula el tamaño de la vista «dba_data_files»:

SELECT SUM(bytes)/1024/1024/1024 data_size FROM dba_data_files;

Calcula el tamaño de los archivos temporales

Estos conservan datos durante el proceso pero no es un almacenamiento permanente.

Calcula el tamaño del archivo temporal:

SELECT NVL(SUM(bytes),0)/1024/1024/1024 temp_size FROM dba_temp_files;

Obtener el tamaño del redo log

Esto almacena cualquier cambio en la base de datos antes de ser aplicado en los datos actuales de la base de datos.

Esto ofrece una manera de almacenar la base de datos en su estado orignal previo a una consulta diseñada para modificar cualquier información.

SELECT SUM(bytes)/1024/1024/1024 redo_size FROM sys.v_$log;

Tamaño del archivo de control usado por Oracle utilizando la vista V$CONTROLFILE

Esta vista se utiliza para obtener información del esquema de la base de datos i de los objetos contenidos en la misma.

Para obtener el tamaño del archivo de control hace falta ejecutar:

SELECT SUM(BLOCK_SIZE*FILE_SIZE_BLKS)/1024/1024/1024 controlfile_size 
FROM v$controlfile;

Combinar las anteriores consultas para obtener el tamaño de la base de datos

Resultado obtenido el tamaño total de la base de datos en gigabytes:

SELECT d.data_size, t.temp_size, r.redo_size
FROM  ( SELECT NVL(bytes)/1024/1024/1024 data_size FROM dba_data_files) d,
( SELECT NVL(sum(bytes),0)/1024/1024/1024 temp_size FROM dba_temp_files ) t,
( SELECT SUM(bytes)/1024/1024/1024 redo_size FROM sys.v_$log ) r;

more…

Errores comunes del servidor OC4J

08-05-2014 - Xavier Salvador

Errores JMS

A través de la consola de comandos se muestra un error como el siguiente:

2013-11-13 15:49:56.330 ERROR J2EE OJR-00011 Excepción al iniciar el servidor JMS: Error parsing jms-server config at file:/C:/PRO_MAVEN/OC4J_10g_TRUNK/j2ee/home/config/jms.xml: /C:/PRO_MAVEN/OC4J_10g_TRUNK/j2ee/home/config/jms.xml, Fatal error at line 27 offset 12 in file:/C:/PRO_MAVEN/OC4J_10g_TRUNK/j2ee/home/config/jms.xml: .<Line 27, Column 12>: XML-20211: (Error Fatal) No está permitido '--' en comments.

Solución

  • Parar el servidor de aplicaciones.
  • Acceder a la ruta <PATH>/j2ee/home/persistence/ de la instalación del servidor OC4J.
  • Borrar el fichero jms.state.
  • Reiniciar el servidor.

Error ParserConfigurationException

A través de la consola de comandos se muestra un error como el siguiente:

ERROR [2013-12-03 15:18:55,759] [Digester] Digester.getParser:
javax.xml.parsers.ParserConfigurationException: XML document validation is not s
upported
at com.bluecast.xml.JAXPSAXParserFactory.newSAXParser(JAXPSAXParserFacto
ry.java:105)
at org.apache.commons.digester.Digester.getParser(Digester.java:686)
at org.apache.commons.digester.Digester.getXMLReader(Digester.java:902)
at org.apache.commons.digester.Digester.parse(Digester.java:1548)
at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionServlet.java:1006)

Solución

No se está utilizando una JDK compatible con el servidor. OC4J es compatible solamente con la JDK 1.4 y este es un error correspondiente al uso del servidor con una JDK superior.

Error “Not in an application scope – start OC4J with the -userThreads switch if using user-created threads”

Este error se produce dentro de un proyecto J2EE que dispone de código fuente que genera hilos bajo demanda del programador. El servidor detecta dicha generación manual y muestra el mensaje de error dando una pista sobre cómo solucionar el problema de compatibilidad.

Solución

En el caso concreto comentado es obligatorio utilizar el atributo -userThreads (Enable context lookup support from user-created threads) del servidor OC4J. Esto permite que el servidor sea capaz de gestionar además de los hilos internos propios también los creados manualmente por el usuario desde la aplicación J2EE.

Este parámetro debe indicarse en el Script de arranque del servidor (en caso de ejecutarse des de consola también debe añadirse como parámetro):

java -jar oc4j.jar -userthreads

Referencias

more…

results matching ""

    No results matching ""