Mostrando las entradas con la etiqueta java. Mostrar todas las entradas
Mostrando las entradas con la etiqueta java. Mostrar todas las entradas

Cómo manejar el error en tiempo de ejecución UnsatisfiedLinkError en Java

 

Introducción: Uso de bibliotecas nativas en Java

Una librería nativa es una librería que contiene código compilado para una arquitectura (nativa) específica. Hay ciertos escenarios, como las integraciones hardware-software y las optimizaciones de procesos, en los que el uso de bibliotecas escritas para diferentes plataformas puede ser muy útil o incluso necesario. Para ello, Java ofrece la Interfaz Nativa Java (JNI), que permite al código Java que se ejecuta dentro de una Máquina Virtual Java (JVM) interoperar con aplicaciones y bibliotecas escritas en otros lenguajes de programación, como C, C++ y ensamblador. La JNI permite al código Java llamar y ser llamado por aplicaciones y bibliotecas nativas escritas en otros lenguajes y permite a los programadores escribir métodos nativos para manejar situaciones en las que una aplicación no puede escribirse completamente en Java.

Los formatos habituales de las bibliotecas nativas son los archivos .dll en Windows, .so en Linux y .dylib en plataformas macOS. El lenguaje convencional para cargar estas bibliotecas en Java se presenta en el siguiente ejemplo de código.

package rollbar;

public class ClassWithNativeMethod {

    static {
    System.loadLibrary("someLibFile");
    }

    native void someNativeMethod(String arg);
    /*...*/
}

Java carga las bibliotecas nativas en tiempo de ejecución invocando el método System.load() o System.loadLibrary(). La principal diferencia entre ambos es que el último no requiere que se especifique la ruta absoluta y la extensión de archivo de la biblioteca, sino que se basa en la propiedad del sistema java.library.path. Para acceder a los métodos nativos de las bibliotecas cargadas, se utilizan stubs de métodos declarados con la palabra clave native.

Error UnsatisfiedLinkError: ¿Qué es y cuándo se produce?

Si un programa Java está utilizando una librería nativa pero es incapaz de encontrarla en tiempo de ejecución por alguna razón, lanza el error en tiempo de ejecución java.lang.UnsatisfiedLinkError. Más concretamente, este error se lanza siempre que la JVM es incapaz de encontrar una definición apropiada en lenguaje nativo de un método declarado nativo, mientras intenta resolver las bibliotecas nativas en tiempo de ejecución [2]. El error UnsatisfiedLinkError es una subclase de la clase java.lang.LinkageError lo que significa que este error es capturado al inicio del programa, durante el proceso de carga y enlace de clases de la JVM.

Algunas situaciones habituales en las que se produce este error incluyen una referencia a las bibliotecas ocijdbc10.dll y ocijdbc11.dll al intentar conectarse a una base de datos Oracle 10g u 11g con el controlador OCI JDBC [3], así como la dependencia de la biblioteca lwjgl.dll utilizada en el desarrollo de juegos y aplicaciones Java que dependen de algunas bibliotecas C/C++ heredadas.

Update the PATH environment variable

Cómo solucionar el error UnsatisfiedLinkError

Para averiguar el culpable exacto y solucionar el error UnsatisfiedLinkError, hay que tener en cuenta un par de cosas:

  • Asegúrese de que el nombre de la biblioteca y / o la ruta se especifican correctamente.
  • Llame siempre a System.load() con una ruta absoluta como argumento.
  • Asegúrese de que la extensión de la biblioteca está incluida en la llamada a System.load().
  • Compruebe que la propiedad java.library.path contiene la ubicación de la biblioteca.
  • Compruebe que la variable de entorno PATH contiene la ruta a la biblioteca.
  • Ejecute el programa Java desde un terminal con el siguiente comando: java -Djava.library.path=«<LIBRARY_FILE_PATH>» -jar <JAR_FILE_NAME.jar>

Una cosa importante a tener en cuenta es que System.loadLibrary() resuelve los nombres de archivos de biblioteca de una manera dependiente de la plataforma, por ejemplo, el fragmento de código en el ejemplo en la Introducción esperaría un archivo llamado someLibFile.dll en Windows, someLibFile.so en Linux, etc.

Además, el método System.loadLibrary() busca primero en las rutas especificadas por la propiedad java.library.path, y luego por defecto en la variable de entorno PATH.

Ejemplo de Error UnsatisfiedLinkError

El código siguiente es un ejemplo de intento de cargar una biblioteca nativa llamada libraryFile.dll con el método System.loadLibrary() en una plataforma Windows OS. La ejecución de este código arroja el error en tiempo de ejecución UnsatisfiedLinkError con un mensaje que dice «no libraryFile in java.library.path» sugiriendo que no se pudo encontrar la ruta a la biblioteca .dll.

package rollbar;

public class JNIExample {

 static {
   System.loadLibrary("libraryFile");
 }

 native void libraryMethod(String arg);

 public static void main(String... args) {
   final JNIExample jniExample = new JNIExample();
   jniExample.libraryMethod("Hello");
 }
}
Exception in thread "main" java.lang.UnsatisfiedLinkError: 
no libraryFile in java.library.path: 
C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;
C:\Program Files (x86)\Common Files\Intel\Shared Files\cpp\bin\Intel64;
C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;
C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;
C:\Program Files\MySQL\MySQL Utilities 1.6\;
C:\Program Files\Git\cmd;C:\Program Files (x86)\PuTTY\;
C:\WINDOWS\System32\OpenSSH\;...
    at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2447)
    at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:809)
    at java.base/java.lang.System.loadLibrary(System.java:1893)
    at rollbar.JNIExample.<clinit>(JNIExample.java:6) 
Hay un par de enfoques para solucionar este error.

Enfoque #1: Actualizar la variable de entorno PATH

Uno es asegurarse de que la variable de entorno PATH contiene la ruta al archivo libraryFile.dll. En Windows, esto se puede hacer navegando a Panel de control → Propiedades del sistema → Avanzadas → Variables de entorno, encontrando la variable PATH (sin distinguir mayúsculas de minúsculas) en Variables del sistema, y editando su valor para incluir la ruta a la biblioteca .dll en cuestión. Para obtener instrucciones sobre cómo hacer esto en diferentes sistemas operativos, consulte.

Método 2: Comprobación de la propiedad java.library.path

Otro método consiste en comprobar si la propiedad del sistema java.library.path está establecida y si contiene la ruta a la biblioteca. Esto se puede hacer llamando a System.getProperty(«java.library.path») y verificando el contenido de la propiedad, como se muestra en el siguiente código.

package rollbar;

public class JNIExample {

 static {
   var path = System.getProperty("java.library.path");

   if (path == null) {
     throw new RuntimeException("Path isn't set.");
   }

   var paths = java.util.List.of(path.split(";"));
   //paths.forEach(System.out::println);

   if (!paths.contains("C:/Users/Rollbar/lib")) {
     throw new RuntimeException("Path to library is missing.");
   }

   System.loadLibrary("libraryFile");
 }

 native void libraryMethod(String arg);

 public static void main(String... args) {
   final JNIExample jniExample = new JNIExample();
   jniExample.libraryMethod("Hello");
 }
}
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.RuntimeException: Path to library is missing.
    at rollbar.JNIExample.<clinit>(JNIExample.java:16)

Técnicamente, la propiedad java.library.path puede ser actualizada llamando a System.setProperty(«java.library.path», «./lib»), pero como las propiedades del sistema son cargadas por la JVM antes de la fase de carga de la clase, esto no tendrá efecto en la llamada System.loadLibrary(«libraryFile») que intenta cargar la biblioteca en el ejemplo anterior. Por lo tanto, la mejor manera de resolver el problema es seguir los pasos descritos en el enfoque anterior.

Método #3: Sobreescribiendo la propiedad java.library.path

Como complemento al enfoque anterior, la única forma efectiva de establecer explícitamente la propiedad java.library.path es ejecutando el programa Java con el argumento de línea de comandos -Dproperty=value, como se muestra a continuación:

java -Djava.library.path=«C:\Users\Rollbar\lib» -jar JNIEjemplo

Y puesto que esto anularía la propiedad system si ya está presente, cualquier otra librería requerida por el programa para ejecutarse también debería incluirse aquí.

Método #4: Usar System.load() en lugar de System.loadLibrary()

Por último, sustituir System.loadLibrary() por una llamada a System.load() que tome la ruta completa de la biblioteca como argumento es una solución que evita la búsqueda en java.library.path y soluciona el problema independientemente de cuál fuera la causa inicial del error UnsatisfiedLinkError.

package rollbar;

public class JNIExample {

 static {
   System.load("C:/Users/Rollbar/lib/libraryFile.dll");
 }

 native void libraryMethod(String arg);

 public static void main(String... args) {
   final JNIExample jniExample = new JNIExample();
   jniExample.libraryMethod("Hello");
   System.out.println("Library method was executed successfully.");
 }
}
Library method was executed successfully.

Sin embargo, no siempre es deseable codificar la ruta a la biblioteca, por lo que en esos casos es preferible recurrir a otros métodos.

Resumen

El uso de librerías nativas compiladas para diferentes plataformas es una práctica común en Java, especialmente cuando se trabaja con sistemas grandes y de características o rendimiento críticos. El marco de trabajo JNI permite a Java hacer esto actuando como puente entre el código Java y las bibliotecas nativas escritas en otros lenguajes. Uno de los problemas con los que se encuentran los programadores es la imposibilidad de cargar correctamente estas bibliotecas nativas en su código Java, momento en el que la JVM desencadena el error en tiempo de ejecución UnsatisfiedLinkError. Este artículo proporciona una visión de los orígenes de este error y explica los enfoques pertinentes para tratar con él.

Seguimiento, análisis y gestión de errores con Rollbar

Gestionar errores y excepciones en el código es todo un reto. Puede hacer que el despliegue de código de producción sea una experiencia desconcertante. Ser capaz de rastrear, analizar y gestionar errores en tiempo real puede ayudarle a proceder con más confianza. Rollbar automatiza la supervisión y clasificación de errores, lo que hace que corregir errores de Java sea más fácil que nunca. Inscríbase hoy mismo

Referencias

[1] Oracle, 2021. Java Native Interface Specification Contents, Introduction. Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/intro.html. [Accessed Jan. 11, 2022]

[2] Oracle, 2021. UnsatisfiedLinkError (Java SE 17 & JDK 17). Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/UnsatisfiedLinkError.html. [Accessed Jan. 11, 2022]

[3] User 3194339, 2016. UnsatisfiedLinkError: no ocijdbc11 in java.library.path. Oracle and/or its affiliates. [Online]. Available: https://community.oracle.com/tech/developers/discussion/3907068/unsatisfiedlinkerror-no-ocijdbc11-in-java-library-path. [Accessed Jan. 11, 2022]

[4] User GustavXIII, 2012. UnsatisfiedLinkError: no lwjgl in java.library.path. JVM Gaming. [Online]. Available: https://jvm-gaming.org/t/unsatisfiedlinkerror-no-lwjgl-in-java-library-path/37908. [Accessed Jan. 11, 2022]

[5] Oracle, 2021. How do I set or change the PATH system variable?. Oracle and/or its affiliates. [Online]. Available: https://www.java.com/en/download/help/path.html. [Accessed Jan. 11, 2022]

Artículo traducido para el blog de n4p5t3r

Orginal: https://rollbar.com/blog/java-unsatisfiedlinkerror-runtime-error/#

 

Quantum – Servidor Web

 

El  proyecto se encuentra desarrollado en lenguaje Java y cuenta con soporte para ejecutar contenido html5, css3, js, php, flask (python) y además cuenta con soporte para certificados ssl.

Instalación

Puedes iniciar clonando el proyecto Quantum desde el respositorio oficial en Github.

El proceso de instalación inicialmente es ejecutar el archivo JAR (Quantum-1.0), ubicado en la ruta «/target» dentro de la carpeta del proyecto.

Puertos habilitados

Puerto en el que desea que escuche su servidor (por ejemplo: 80, 8080, 8000, u otro).

El servidor utiliza los siguientes puertos para su funcionamiento:

  • PORT = 1980
  • SSLPORT = 2016

Almacenamiento de LOGs

Los archivos de log se almacenan en ubicaciones predefinidas dependiendo del sistema operativo. Se crean dos tipos de log: uno para errores y otro para accesos.

Las rutas definidas para los log son las siguientes:

  • LOG_WINDOWS = «C:\www\log\»
  • LOG_LINUX = «/var/log/»

Los archivos parametrizados son los siguientes:

  • log_quantum_error.log
  • log_quantum_acceso.log

Ruta raíz del directorio web

Este atributo define la ruta raíz del directorio web que contendrá los archivos HTML, PHP y otros recursos servidos por el servidor en sistemas Windows y Linux. Se utiliza para construir las rutas de los archivos solicitados por los clientes.

  • WEB_ROOT_WINDOWS = «C:\\quantum\\www»
  • WEB_ROOT_LINUX = «/mnt/quantum/www»

Tamaño del buffer

Determina la cantidad de datos que se pueden leer o escribir en un archivo o socket a la vez. Se expresa en bytes. Puedes dejarlo como está, o reducirlo a 1024.

  • bufferSize = 8192

Recomendación

Mantener revisando el repositorio de github para validar las actualizaciones que estaré cargando, al menos una vez a la semana.

Proyecto: Web Report ML

 

WEBREPORT-ML es la continuación del proyecto REPORT-ML para la generación de reportes para la web en diversos formatos, como HTML, PDF, DocBook.

Este proyecto fue diseñado y desarrollado a finales del año 2003 como resultado de mi proyecto de grado en la facultad de Ingeniería de Sistemas.

CARACTERISTICAS DE WEBREPORT-ML

WEBREPORT-ML está conformado básicamente por dos componentes:

  • Elementos
  • Atributos

Elementos

Cada elemento de WEBREPORT-ML consta de una marca de comienzo, el contenido y una marca de fin.  Por ejemplo:

<titulo>Aquí se imprime el título del reporte</titulo>

Atributos

Un atributo es un mecanismo para agregar información descriptiva a un elemento. Por ejemplo:

<titulo  tipo-titulo=»texto» fuente-titulo=»Comic Sans MS» estilo-fuente-titulo=» » color-texto=»blue» alineacion-titulo=»center» decoracion-texto-titulo=» » ancho-titulo=» » saturacion-color-titulo=» »  color-borde=»blue» estilo-borde=» » tamaño-titulo=»18″>

    Reporte de Productos

  </titulo>

Es muy importante colocar los valores de los atributos entre comillas dobles.  En caso de no colocar las comillas dobles, el procesador le indicará que hubo un error.

ESTRUCTURA DE WEBREPORT-ML

Un reporte escrito en WEBREPORT-ML comienza y termina con la marca reporte, indicando que se trata de un reporte a realizar en el lenguaje.

<reporte>

Cuerpo del documento

</reporte>

Dentro del elemento reporte se encentran varios elementos primarios, tales como: 

  • descripcion
  • salida
  • conexion
  • consulta
  • titulo
  • cabecera
  • detalles
  • pie-de-pagina

Ejemplo:

<?xml version=»1.0″ encoding =»iso-8859-1″?>

<reporte>

  <conexion/>

  <consulta>

    Contenido de la consulta SQL

  </consulta>

  <margenes />

  <salida/>

  <titulo>

    Reporte de Productos

  </titulo>

  <descripcion>

    Contenido de la descripcion

  </descripcion>

  <cabecera>

    <fila>

      <campo> </campo>

    </fila>  

  </cabecera>

  <detalles>

    <fila>

      <campo/>

    </fila> 

  </detalles>

  <pie-de-pagina>

     <fila>

      <campo> </campo>

     </fila>

  </pie-de-pagina>

</reporte>

DESCRIPCIÓN DE LOS ELEMENTOS DEL LENGUAJE REPORT-ML

Elemento descripcion

El elemento descripcion  se utiliza para colocar una información descriptiva acerca de los que se trata el reporte.  Ejemplo:

<descripcion>

   Este es un reporte para los empleados de la compañía

</descripcion>

Elemento margenes

El elemento margenes se utiliza para especificar cada uno de los márgenes para el documento del reporte y consta de los siguientes atributos:

  • Atributo margen-superior
  • Atributo margen-inferior
  • Atributo margen-izquierdo
  • Atributo margen-derecho

Elemento salida

El elemento salida se utiliza para especificar el formato en el que se desea que se muestre el reporte, así como la ruta en donde se guardará el reporte.  Contiene los siguientes atributos:

  • Atributo formato
  • Atributo archivo

*Atributo formato

El atributo formato especifica el formato en el que se desea que se imprima el reporte.  Los tipos de formatos disponibles en WEBREPORT-ML son:

  • Html
  • PDF
  • DocBook

*Atributo archivo

El atributo archivo especifica la ruta en donde se desea guardar el reporte.  Es importante que el usuario especifique una ruta en donde se guardará su reporte para que al momento de terminar de exportar los datos al formato requerido, sabrá que el reporte se alojará precisamente en el lugar que él indicó.

Elemento conexion

El elemento conexion se utiliza para especificar los esquemas de conexión con la base de datos.  Contiene los siguientes atributos:

*Atributo conector

El atributo conector especifica el motor de la base de datos a utilizar.

Ejemplo:

conector=»sun.jdbc.odbc.JdbcOdbcDriver»

*Atributo url

El atributo url la ruta de la base de datos de la siguiente manera:

jdbc:odbc:Base_de_Datos

Elemento consulta

El elemento consulta  especifica el contenido de la consulta SQLque se va a utilizar para generar nuestro reporte.

Ejemplo:

<consulta>

            select * from tabla

</consulta>

Elemento titulo

El elemento titulo se utiliza para el título del reporte.

Elemento cabecera

El elemento cabecera se utiliza para los títulos de cada campo del reporte.  Contiene un elemento anidado fila el cual hace referencia a las filas deseadas por el usuario; ésta a su vez contiene un elemento anidado campo, que especifica el número de campos (columnas) que el usuario desea para esa fila. 

Ejemplo:

<cabecera>

 <fila>

  <campo tipo=”texto”>

    Nombre

  </campo>

  <campo tipo=”texto”>

    Apellido

  </campo>

  </fila>   

</cabecera>

Para el ejemplo anterior se mostrará, en una misma fila, varios campos con los títulos para el reporte y quedaría de la siguiente forma:

NombreApellido

Elemento detalles

El elemento detalles constituye uno de los elemento más importantes del reporte, pues es ahí en donde se especifican cada uno de los campos de la base de datos que se mostraran  en el reporte, así como también se realizan las fórmulas que se desean hacer para el reporte.  Las fórmulas deben codificarse en el lenguaje Java Script. Existen dos tipos de campos diferentes a los anteriormente descritos, que se utilizan en el detalle:

  • El tipo de campo bd
  • El tipo de campo formula

El tipo de campo bd, se utiliza para especificar cada uno de los campos de la base de datos que el usuario desea mostrar en el reporte.  Para este tipo de campo, existe un atributo llamado nombre, el cual especifica el nombre del campo de la base de datos a extraer para el reporte. Cada vez que el usuario especifique el tipo de campo bd debe especificar en el atributo nombre el nombre del campo de la base de datos.

Ejemplo:

<detalles>

 <fila>

  <campo tipo=”bd” nombre=”cedula”/>

  <campo tipo=”bd” nombre=”nombre”/>

  <campo tipo=”bd” nombre=”apellido”/>

 </fila>

</detalles>

El tipo de campo formula,se utiliza para las distintas fórmulas que se desean hacer para el reporte.

Ejemplo:

<detalles>

 <fila>

  <campo tipo=”formula”>

value = parseInt(query.get(«CANTIDAD»)) * parseInt(query.get(«PRECIO»));

  </campo>

 </fila>

</detalles>

*Atributo formato

El atributo formato especifica el formato numérico a utilizarse.  Este atributo hace parte del elemento anidado campo y se utiliza en caso de que se utilicen números y se les quiera aplicar algún tipo de formato.

Ejemplos de tipos de formato

  • $ #.##0,00
  • 00
  • 0000
  • ##0.0# %

Ejemplo:

<detalles>

 <fila>

<campo tipo=”bd” nombre=”Valor” formato=”$#.##0,00” />

 </fila>

</detalles>

Para el ejemplo anterior, se mostrarán todos los registros del campo Valor, correspondiente al valor unitario de X producto y se le aplica el tipo de formato $#.##0,00 así como el estilo de letra negrita.  El resultado de uno de los registros del campo valor, quedaría de la siguiente forma:  $ 2,052,000.00

Elemento pie-de-pagina

El elemento pie-de-pagina se utiliza para colocar algún contenido al final del reporte, como funciones para hallar el total de un determinado campo de la base de datos, ó el gran total de algún total hallado por medio de las fórmulas descritas en el detalles. Contiene un elemento anidado fila el cual hace referencia a las filas deseadas por el usuario; ésta a su vez contiene un elemento anidado campo, que especifica el número de campos (columnas) que el usuario desea para esa fila. 

Los tipos de campo utilizados en el pie-de-pagina son:

  • text
  • total

El campo total se utiliza única y exclusivamente en el elemento pie-de-pagina. Este tipo de campo especifica la función a llevar a cabo para hallar el total de un determinado campo de la base de datos ó para hallar un resultado total de cada uno de los resultados hallados en la fórmula escrita en el detalle. 

También existe un atributo que va de la mano con el tipo de campo total y es el atributo funcion, el cual se explica a continuación.

*Atributo funcion

El atributo funcion especifica la función a utilizarse en el pie-de-pagina y depende del tipo de campo total.  Los tipos de funciones disponibles para la el atributo funcion del pie-de-pagina son las siguientes:

  • suma, para hallar la suma
  • promedio, para hallar el promedio
  • mult, para hallar el producto
  • mayor, para hallar el máximo valor
  • menor, para hallar el mínimo valor
  • contar, para contar

Ejemplo :

<pie-de-pagina>

 <fila>

    <campo tipo=”total” funcion=”suma” nombre=”Cantidad” />

    <campo tipo=”total” funcion=”mayor” />

 </fila>

</pie-de-pagina>

Codificación

Si el usuario va a utilizar en el reporte caracteres propios del alfabeto español, tales como la letra ñ, tildes, etc, deberá incluir el siguiente atributo al principio de la creación del reporte:

encoding=»iso-8859-1″

Ejemplo:

<?xml version=»1.0″ encoding=»iso-8859-1″?>

<reporte>

Cuerpo del reporte

</reporte>

EJEMPLOS DE UTILIZACIÓN DE WEBREPORT-ML

Ejemplo 1:

<?xml version=»1.0″ encoding=»iso-8859-1″?>

<reporte>

  <conexion conector=»sun.jdbc.odbc.JdbcOdbcDriver» url=»jdbc:odbc:bd2″/>

  <consulta>

    select *

    from producto

  </consulta>

  <margenes margen-superior=»1.0″ margen-inferior=»1.0″ margen-derecho=»1.0″ margen-izquierdo=»1.0″ />

  <salida formato=»pdf» archivo=»c:\mireporte» />

  <titulo  tipo-titulo=»texto» fuente-titulo=»Comic Sans MS» estilo-fuente-titulo=» » color-texto=»blue» alineacion-titulo=»center» decoracion-texto-titulo=» » ancho-titulo=» » saturacion-color-titulo=» »  color-borde=»blue» estilo-borde=» » tamaño-titulo=»18″>

    Reporte de Productos

  </titulo>

  <descripcion>Este es mi primer reporte </descripcion>

  <cabecera>

    <fila>

      <campo color=»blue» alineacion=»center» tipo=»texto»>Identificador</campo>

      <campo color=»blue» alineacion=»center» tipo=»texto»>Nombre</campo>

      <campo color=»blue» alineacion=»center» tipo=»texto»>Unidades En Existencia</campo>

      <campo color=»blue» alineacion=»center» tipo=»texto»>Precio Unidad</campo>

      <campo color=»blue» alineacion=»center» tipo=»texto»>Formula</campo>

    </fila>  

  </cabecera>

  <detalles>

    <fila>

      <campo tipo=»bd» formato=»0000″ nombre=»CODP»/>

      <campo tipo=»bd» formato=» » nombre=»NOMP»/>

      <campo tipo=»bd» formato=»0000″ nombre=»CANTIDAD»/>

      <campo tipo=»bd» formato=»$#,##0.00″ nombre=»PRECIO»/>

      <campo tipo=»formula»>

        value = parseInt(query.get(«CANTIDAD»)) * parseInt(query.get(«PRECIO»));

      </campo> 

    </fila> 

  </detalles>

  <pie-de-pagina>

     <fila>

      <campo color=»blue» alineacion=»center» tipo=»texto»>Fin del Reporte</campo>

     </fila>

  </pie-de-pagina>

</reporte>

Ejemplo 2:

<?xml version=»1.0″ encoding=»iso-8859-1″?>

<reporte>

  <conexion conector=»sun.jdbc.odbc.JdbcOdbcDriver» url=»jdbc:odbc:bd2″  />

  <consulta>

    select CODP, NOMP, NOMBRE, PRECIO, CANTIDAD

    from PRODUCTO inner join CATEGORIA

    on PRODUCTO.CODIGOC = CATEGORIA.CODIGOC

    order by CODP

  </consulta>

  <margenes margen-superior=»1.0″ margen-inferior=»1.0″ margen-derecho=»1.0″ margen-izquierdo=»1.0″ />

    <salida formato=»docbook» archivo=»c:\productos» />

    <titulo  tipo-titulo=»texto» fuente-titulo=»Comic Sans MS» estilo-fuente-titulo=» » color-texto=»green» alineacion-titulo=»center» decoracion-texto-titulo=» » ancho-titulo=» » saturacion-color-titulo=» »  color-borde=»blue» estilo-borde=»double» tamaño-titulo=»18″>

      Reporte de Productos

    </titulo>

    <descripcion>Este es mi primer reporte </descripcion>

    <cabecera>

      <fila>

        <campo color=»red» alineacion=»center» tipo=»texto»>Identificador</campo>

        <campo color=»blue» alineacion=»center» tipo=»texto»>Nombre</campo>

        <campo color=»pink» alineacion=»center» tipo=»texto»>Unidades En Existencia</campo>

        <campo color=»yellow» alineacion=»center» tipo=»texto»>Precio Unidad</campo>

        <campo color=»black» alineacion=»center» tipo=»texto»>Categoria</campo>

        <campo color=»orange» alineacion=»center» tipo=»texto»>Formula</campo>

      </fila>  

    </cabecera>

    <detalles>

      <fila>

        <campo color-relleno=»ffffcc» color=»red» estilo=»italic» tipo=»bd» formato=»0000″ nombre=»CODP»/>

        <campo tipo=»bd» formato=» » nombre=»NOMP»/>

        <campo tipo=»bd» formato=»000″ nombre=»CANTIDAD»/>

        <campo tipo=»bd» formato=»$#,##0.00″ nombre=»PRECIO»/>

        <campo tipo=»bd» formato=» » nombre=»NOMBRE»/>

        <campo tipo=»formula» color-relleno=»yellow» color=»blue»>

          value = parseInt(query.get(«CANTIDAD»)) * parseInt(query.get(«PRECIO»));

        </campo> 

      </fila> 

    </detalles>

    <pie-de-pagina>

      <fila>

        <campo color=»blue» alineacion=»center» tipo=»texto»>Inventario Total</campo>

        <campo tipo=»total» funcion=»suma» nombre=»CANTIDAD»/>

      </fila>

      <fila>

        <campo color=»blue» alineacion=»center» tipo=»texto»>Precio Mayor</campo>

        <campo tipo=»total» formato=»$#,##0.00″ funcion=»mayor» nombre=»PRECIO»/>

      </fila>

    </pie-de-pagina>

</reporte>

Ejemplo 3:

<?xml version=»1.0″ encoding=»iso-8859-1″?>

<reporte>

  <conexion conector=»sun.jdbc.odbc.JdbcOdbcDriver» url=»jdbc:odbc:bd2″  />

  <consulta>

    select CODP, NOMP, NOMBRE, PRECIO, CANTIDAD

    from PRODUCTO inner join CATEGORIA

    on PRODUCTO.CODIGOC = CATEGORIA.CODIGOC

    order by CODP

  </consulta>

  <margenes margen-superior=»1.0″ margen-inferior=»1.0″ margen-derecho=»1.0″ margen-izquierdo=»1.0″ />

    <salida formato=»html» archivo=»c:\productos» />

    <titulo  tipo-titulo=»texto» fuente-titulo=»Comic Sans MS» estilo-fuente-titulo=» » color-texto=»green» alineacion-titulo=»center» decoracion-texto-titulo=» » ancho-titulo=» » saturacion-color-titulo=» »  color-borde=»blue» estilo-borde=»double» tamaño-titulo=»18″>

      Reporte de Productos

    </titulo>

    <descripcion>Este es mi primer reporte </descripcion>

    <cabecera>

      <fila>

        <campo color=»red» alineacion=»center» tipo=»texto»>Identificador</campo>

        <campo color=»blue» alineacion=»center» tipo=»texto»>Nombre</campo>

        <campo color=»pink» alineacion=»center» tipo=»texto»>Unidades En Existencia</campo>

        <campo color=»yellow» alineacion=»center» tipo=»texto»>Precio Unidad</campo>

        <campo color=»black» alineacion=»center» tipo=»texto»>Categoria</campo>

        <campo color=»orange» alineacion=»center» tipo=»texto»>Formula</campo>

      </fila>  

    </cabecera>

    <detalles>

      <fila>

        <campo color-relleno=»ffffcc» color=»red» estilo=»italic» tipo=»bd» formato=»0000″ nombre=»CODP»/>

        <campo tipo=»bd» formato=» » nombre=»NOMP»/>

        <campo tipo=»bd» formato=»000″ nombre=»CANTIDAD»/>

        <campo tipo=»bd» formato=»$#,##0.00″ nombre=»PRECIO»/>

        <campo tipo=»bd» formato=» » nombre=»NOMBRE»/>

        <campo tipo=»formula» color-relleno=»yellow» color=»blue»>

          value = parseInt(query.get(«CANTIDAD»)) * parseInt(query.get(«PRECIO»));

        </campo> 

      </fila> 

    </detalles>

    <pie-de-pagina>

      <fila>

        <campo color=»blue» alineacion=»center» tipo=»texto»>Inventario Total</campo>

        <campo tipo=»total» funcion=»suma» nombre=»CANTIDAD»/>

      </fila>

      <fila>

        <campo color=»blue» alineacion=»center» tipo=»texto»>Precio Mayor</campo>

        <campo tipo=»total» formato=»$#,##0.00″ funcion=»mayor» nombre=»PRECIO»/>

      </fila>

    </pie-de-pagina>

</reporte>

MODO DE INSTALACION

Para la instalar WEBREPORT-ML, el usuario deberá copiar la carpeta reportml que se encuentra el CD de instalación en el directorio Coligo Fuente, al disco duro y después crear un nuevo Context en el servidor de Apache TOMCAT, el alias debe ser /reportml y el documento base debe ser c:/reportml.

Para desinstalarlo, solo se elimina el Context del servidor y se borra el directorio de la raíz de C: .

Cabe recordar que dentro del directorio reportml  se encuentra el directorio waren el cual se encuentra el archivo WebReport.war. Para instalar este archivo, hay dos opciones:

OPCION 1:

1) Copiar el fichero war a TOMCAT / webapps

2) Arrancar el servidor

3) La instalación es automática y crea un nuevo directorio con los contenidos del war.

OPCION 2:

1) Crear la aplicación Web descomprimida en webapps siguiendo el formato estándar.

2) Añadir en TOMCAT / conf / server.xml un nuevo contexto que apunte a nuestro directorio:

<Context path=»/sob» docBase=»peter» debug=»0″ privileged=»true»>

</Context>

NOTA: En su momento este proyecto fue diseñado y desarrollado bajo windows, sin embargo, puede funcionar con sistemas operativos linux y macOs. Puedes acceder a todo el proyecto a través de su repositorio oficial en github: https://github.com/rrcyber/WebReportML/

Proyecto: Biometría en Java, mySQL y el SDK de DigitalPersona

 

Hace un tiempo desarrollé un proyecto con Java y mySQL, el cual se basa en el registro y autenticación de usuarios a través del lector de huellas DigitalPersona 4500.

El proyecto está diseñado y desarrollado con Java, puede ser abierto a través de netbeans o eclipse. Funciona tanto en Windows como en Linux. El motor de base de datos es mySQL y utiliza el SDK de DigitalPersona.

Todo el proyecto está cargado en su repositorio oficial en github: https://github.com/rrcyber/Biometria

Proyecto: Jarvis

 

Qué es Jarvis? Es un sistema de información, diseñado para automatizar procesos de consolidación de información, recorriendo la cuenta de correo electrónico autorizada para envío y recibo de notificaciones, consumir los servicios web del sistema Andess y procesar los datos a través del motor de base de datos postgreSQL.

Tenemos dos versiones de esta solución:

Versión en Java: https://github.com/rrcyber/Jarvis-1

Versión en Python: https://github.com/rrcyber/Jarvis-2