• Este debate está vacío.
Viendo 12 entradas - de la 1 a la 12 (de un total de 12)
  • Autor
    Entradas
  • #31379
    Luis Castelat
    Miembro

    Federico, te comento lo que hice con un informe de prueba, y me dio error,
    1) cree el informe jasper con dos parametros $P, llamados CLAVE y ARTICULO.

    2) compile el archivo jasper
    3) lo agregue a la tabla jasper en el system
    4) creee un proceso launcarticulo y le asocie el reporte jasper
    5) en la clase recupero el id de la tabla de articulos y el id del articulo y le paso de la misma forma que la factura a los dos parametros con el metodo articulo.getValue y getName

    y despues hago un showreport

    no hago nada con el ds, data source porque no quiero hacer ninguna consulta,
    6) agregue un campo en la tabla m_product, con el nombre de un boton
    7) agregue ese campo a la tabla en libertya y le dije que era de tipo boton y que ejecutara el proceso asociado al jasper

    cuando lo ejecute hizo todo bien pero llego al showreport y ahi fallo

    eclipse dijo esto

    ===========> Secure.decrypt: d504ada4fe01fe9b [241]
    java.lang.IllegalStateException: Cipher not initialized
    at javax.crypto.Cipher.c(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)
    at org.openXpertya.util.Secure.decrypt(Secure.java:173)
    at org.openXpertya.util.Ini.getProperty(Ini.java:687)
    at org.openXpertya.util.Ini.isServerObjects(Ini.java:811)
    at org.openXpertya.util.DB.isRemoteObjects(DB.java:1811)
    at org.openXpertya.util.CPreparedStatement.(CPreparedStatement.java:84)
    at org.openXpertya.util.CPreparedStatement.
    (CPreparedStatement.java:70)
    at org.openXpertya.util.DB.prepareStatement(DB.java:743)
    at org.openXpertya.util.DB.prepareStatement(DB.java:706)
    at org.openXpertya.model.MLookup$MLoader.run(MLookup.java:925)

    que podria estar haciendo mal?

    #34405
    Javier Ader
    Participante

    la verdad que es muy raro tu error, es muy poco probable que lo vuelvas a ver en bastante tiempo. De cualquier manera no te hagas problema que el error no lo estas produciendo vos y que ademas es casi seguro no tiene consecuencias (DB.isServerObjetcs te va responder lo que debe con error o sin error; salvo que hayas configurado el cliente para que use “objetos en el servidor”; pero no creo que hagas esto; en ese caso isServerObjects te va a retornar N ‘algunas’ veces y de manera casi aleatoria)
    La excepción se esta disparando a partir de DB.isServerObjetcs(), un método que es llamado todo el tiempo (cada vez que se ejecuta una sentencia sql contra el servidor…). E.d tu problema, si no fuera lo que explico más adelante, debería ocurrirte a cada rato y tendría el log de errores con miles de ocurrencias del mismo error.
    El problema subyacente es que el “chipher” (Secure.s_chipher) (algoritmo para encriptación y desencripción usando por ej, para buscar valores de libertya.properties ) parece no estar “inicializado”…. el tema es que el código justo antes de cada encriptación y desencriptación, lo inicializa!!! (Secure.decrypt(string) y Secure.encrypt(string)
    Entonces? Lo único posible que veo (y que si creo que es un bug en Libertya) es que los métodos Secure.decrypt y Secure.encrypt no son accedidos sin control de concurrencia y pueden dar lugar a errores similares a los que comentas (el tema es que los dos métodos usan el mismo objeto chyper, y por ej, lo inicializan de manera distinta). En cualquier caso este error debería ocurrirte de manera un poco aleatoria y no siempre (en el fondo es un error de falta de chequeo de concurrencia). Las probabilidades de ocurra aumentan un poco si por ej estas corriendo el cliente en un sistema multi-nucleo, lo cual es común en estos días (es tu caso?)

    Ahora, algo que no viene al tema exactamente, pero Ini creo que debería cachear la propiedad ServerObjects (la propiedad que es accedida todo el tiempo) y no simplemente ir a desencriptar un “N” anteriormente encriptado…. (no se que tan pesado sera el algoritmo de descripción, pero me parece que no son cosas simples).
    Para evitar problemas los problemas de concurrencia, se deberían poner locks en los accesos al cipher (se dan solo en Secure.decrypt y secure.encrypt), el tema es que esto puede llevar a cuellos de botellas si hay multiples threads concurrentes (lo cual es el caso cuando se cargan lo MLookups, como muestra la traza de sticuyo). Otro pequeña mejora para evitar esto último (que indirectamente solucionaría el tema de ServerObjecs) es que se Secure precalcule la encriptación de “Y” y “N”; asi por ej, decrypt antes de usar el chipher haria, sin usar ningun lock algo como
    if value.equals(YEncriptado) return “Y”
    if value.equals(NEcriptado) return “N”

    encrpyt por otra parte
    if (“Y”.equals (YEncriptado) return YEncriptado
    if (“N”.equals (NEncriptado) reutrn NEncriptado

    Esto evitaria cuellos de botellas en los locks para strings N e Y que son usadas todo el tiempo.

    Otra alternativa es que las strings Y y N nunca se encripten a partir de Ini (y en … no le veo mucho sentido desde el punto de vista de seguridad (uno fácilmente puede darse cuenta cual es valor encriptado para Y y para N)

    #34409
    Federico Cristina
    Superadministrador

    Luis,

    Tal como comenta Javier, dicho error no debería presentarse sistemáticamente, sino más bien sucede esporádicamente y muy probablemente por los motivos ya detallados. Particularmente yo lo veo de vez en cuando al iniciar la aplicación.

    Por otra parte, este error no debería ser motivo para que el informe no funcione. Probaste a poner un break al inicio de los métodos prepare() y doIt() de la clase que implementaste (la que extiende de SvrProcess) a fin de ver que está sucediendo?

    Saludos,
    Federico

    #34410
    Luis Castelat
    Miembro

    A continuacion les dejo la clase que cree del launchArticuloPrecio, que me base en launch invoice, debuggiando el codigo llega hasta showreport y ahi da error y dice que no se ha podido rellenar el informe y no sigue ahi queda.
    aqui se me para el codigo

    package org.openXpertya.JasperReport;

    //import org.openXpertya.model.MClient;
    import org.openXpertya.model.MProduct;
    import org.openXpertya.model.MProcess;
    import org.openXpertya.process.ProcessInfo;
    import org.openXpertya.process.ProcessInfoParameter;
    import org.openXpertya.process.SvrProcess;
    import org.openXpertya.util.Env;

    public class LaunchArticuloPrecio extends SvrProcess {
    /** Jasper Report */
    private int AD_JasperReport_ID;

    /** Table */
    private int AD_Table_ID;

    /** Record */
    private int AD_Record_ID;

    /** Tipo de impresion */
    private String printType;

    @Override
    protected void prepare() {

    // Determinar JasperReport para wrapper, tabla y registro actual
    ProcessInfo base_pi = getProcessInfo();
    int AD_Process_ID = base_pi.getAD_Process_ID();
    MProcess proceso = MProcess.get(Env.getCtx(), AD_Process_ID);
    if(proceso.isJasperReport() != true)
    return;

    AD_JasperReport_ID = proceso.getAD_JasperReport_ID();
    AD_Table_ID = getTable_ID();
    AD_Record_ID = getRecord_ID();

    ProcessInfoParameter[] para = getParameter();
    for( int i = 0;i < para.length;i++ ) {
    String name = para[ i ].getParameterName();
    if( para[ i ].getParameter() == null ) ;
    else
    if( name.equalsIgnoreCase( “TipoDeImpresion” )) {
    printType = (String)para[ i ].getParameter();
    }
    }

    }

    @Override
    protected String doIt() throws Exception {
    return createReport();
    }

    private String createReport() {

    MProduct producto= new MProduct(getCtx(),AD_Record_ID,null);
    MJasperReport jasperwrapper = new MJasperReport(getCtx(), AD_JasperReport_ID, get_TrxName());
    //
    // Establecemos parametros
    jasperwrapper.addParameter(“CLAVE”, producto.getValue());
    jasperwrapper.addParameter(“ARTICULO”, producto.getName());

    try {
    //jasperwrapper.fillReport(ds);
    jasperwrapper.showReport(getProcessInfo());
    }

    catch (RuntimeException e) {
    throw new RuntimeException (“No se ha podido rellenar el informe.”, e);

    }

    return “doIt”;
    }
    }
    estoy intentando entender el error que dice javAd, pero estoy empezando con java sepan disculpar y tener paciencia
    muchas gracias por contestar

    #34413
    Federico Cristina
    Superadministrador

    Qué excepción está presentando? Fijate qué tiene la RuntimeException e. Podrías hacer algo como:

    Code:
    catch (RuntimeException e) {
    e.printStackTrace();
    throw new RuntimeException (“No se ha podido rellenar el informe.”, e);
    }

    Por otra parte, aunque no creo que esto tenga relación con el problema, fijate que deberías instanciar el producto utilizando la transacción

    MProduct producto= new MProduct(getCtx(),AD_Record_ID,get_TrxName());

    Saludos,
    Federico

    #34415
    Luis Castelat
    Miembro

    Federico esto es el resultado del trace

    java.lang.NullPointerException
    at net.sf.jasperreports.view.JRViewer.setPageIndex(JRViewer.java:1333)
    at net.sf.jasperreports.view.JRViewer.loadReport(JRViewer.java:1419)
    at net.sf.jasperreports.view.JRViewer.(JRViewer.java:285)
    at net.sf.jasperreports.view.JRViewer.
    (JRViewer.java:228)
    at org.openXpertya.JasperReport.OXPJRViewer.
    (OXPJRViewer.java:37)
    at org.openXpertya.JasperReport.OXPJasperViewer.viewReport(OXPJasperViewer.java:29)
    at org.openXpertya.JasperReport.MJasperReport.showReport(MJasperReport.java:171)
    at org.openXpertya.JasperReport.LaunchArticuloPrecio.createReport(LaunchArticuloPrecio.java:113)
    at org.openXpertya.JasperReport.LaunchArticuloPrecio.doIt(LaunchArticuloPrecio.java:52)
    at org.openXpertya.process.SvrProcess.process(SvrProcess.java:154)
    at org.openXpertya.process.SvrProcess.startProcess(SvrProcess.java:114)
    at org.openXpertya.apps.ProcessCtl.startProcess(ProcessCtl.java:527)
    at org.openXpertya.apps.ProcessCtl.run(ProcessCtl.java:282)

    #34416
    Federico Cristina
    Superadministrador

    Bueno, eso ya te da una pauta de que probablemente algo que le estás pasando al reporteador Jasper no se encuentra instanciado (y de ahí el NullPointerException).

    A fin de detectar el problema, te aconsejaría debuggear el código, inspeccionando las instancias que le estás pasando a los métodos.

    Por lo que veo, has comentado la línea:

    Code:
    //jasperwrapper.fillReport(ds);

    Y este es necesario para cargar el array de bytes correspondiente al informe precompilado. (mirá la implementación de éste método en la clase MJasperReport).

    Saludos,
    Federico

    #34417
    Luis Castelat
    Miembro

    veo lo del ds , lo comente porque no le estoy pasando datos al recordsource, solo quiero que muestre los valores de la Clave y el Nombre del articulo, aunque no tenga que rellenar un recordset lo tengo que pasar igual?

    #34418
    Federico Cristina
    Superadministrador

    Sinceramente siempre necesité utilizar un DataSource, así que nunca se me presentó una situación como la tuya.

    Sin embargo, fijate el método fillReport(JRDataSource dataSource) del cual te comentaba en la clase MJasperReport:

    Code:
    byte[] report = getBinaryData();
    if (report == null) {
    throw new RuntimeException(“No se ha podido cargar el informe precompilado.”);
    }
    // Rellenamos el informe
    JPrint = JasperFillManager.fillReport(new ByteArrayInputStream(report), Parameters, dataSource);

    Éste se encarga de obtener el reporte precompilado y pasárselo al JasperFillManager, y fijate que ahí le está pasando tanto el datasource como los parámetros.

    Podrías primeramente probar a invocar a éste método con null como parámetro, a ver si funciona esta alternativa. Después contame como te fue.

    Saludos,
    Federico

    #34438
    Federico Cristina
    Superadministrador

    En lugar de pasarle null, tenés que pasarle un JREmptyDataSource. Fijate en este thread.

    Saludos,
    Federico

    #34501
    Luis Castelat
    Miembro

    Federico lo probe pero no encuentra esa clase en libertya

    JREmptyDataSource

    no la encuentra en ningun lado y por eso me falla..

    #34406
    Javier Ader
    Participante

    Supongo que ya la encontraste, pero bueno, por las dudas el nombre completo de la clase es
    net.sf.jasperreports.engine.JREmptyDataSource
    Un ejemplo de clase que la usa es LauchOrdenPago (el informe de la orden de pago)

Viendo 12 entradas - de la 1 a la 12 (de un total de 12)
  • Debes estar registrado para responder a este debate.