Desarrollo WEB.


Las practicas de programación orientadas a la web son muy cambiantes en el tiempo. Es necesario conocer e implementar tecnologías, conocer lenguajes,integrar comunidades,usar Ides, etc, recientes, para responder al mercado que se acerca.

jueves, 26 de agosto de 2021

SonarQube

El Sonar.

Actualmente las herramientas para los desarrolladores son incontables, entre ellas, una de las mas implementadas en los ámbitos laborales es el Sonar. Al igual que un sonar en el mar, es una señal que se envía para captar elementos novedades en el campo de acción. Al aplicar un sonar a un proyecto podemos detectar todas las malas practicas de codificación y a la vez se presentan formas para solventar y depurar estas partes de código.

Sonarqube es una de las herramientas de la actualidad mas comunes para esta practica laboral super importante. Funciona desde el directorio que se obtiene al descomprimir el zip de la aplicación. Esta carpeta contiene las fuentes para ejecutar el sonar.

Para encontrar mas información dirígete directamente al sitio oficial de sonarqube. https://www.sonarqube.org/, allí encontraras información actualizada de como instalar. Por favor siga las indicaciones de instalación y ejecución



Correr Servicio

Para correr el servicio de sonar por favor ejecute desde consola Windows(en este caso).

Activar en el archivo de configuración ubicado en conf/sonar.properties

Imagen 1


C:\sonarqube-9.0.1.46107\bin\windows-x86-64\StartSonar.bat

Si al intentar correr el servicio este se detiene es decir al correr el servicio este no arranca, por favor diríjase al archivo conf/wraper.conf y configure allí su versión de java, sencillamente tenga en cuenta que tu versión del jdk debe estar configurada en este archivo.

Imagen 2

Al arrancar sin novedades el servicio del sonar se debe ver algo así (imagen 3)en la consola indicando su arranque.


Imagen 3


Aplicar sonar a un proyecto C#

.NET

Instalar Sonar Escaner

    dotnet tool install --global dotnet-sonarscanner

Para aplicar sonar a un proyecto por favor parece desde la consola en la raíz del proyecto y ejecute secuencialmente los siguientes comandos.

    1. dotnet sonarscanner begin /k:"sigaig_api_netcore" /d:sonar.host.url="http://localhost:9000"  /d:sonar.login="0d3d2062b8f704d7df9e6bbbb07aee538cc06072"

    2. dotnet build

    3. dotnet sonarscanner end /d:sonar.login="0d3d2062b8f704d7df9e6bbbb07aee538cc06072"

Nota: use la llave generada desde la interface del sonar en su pagina web http://localhost:9000

Así como a este proyecto .NET, se puede también generar para todo tipo de proyectos. Sonar se basa en reglas y las aplica para cada tipo de tecnología. Estas reglas son configurables, muy personalizables, pero la idea siempre será participar de los estándares.



martes, 21 de enero de 2014

Capturar valor de un campo de búsqueda de una JDatatable

En ocasiones con JSF requerimos enviar valores con javascript de componentes html y pasarlos por parámetros al controlador, logrando así obtener información cargada en variables de sesión o en entidades EJB.

Una de esas ocasiones es cuando teniendo un campo de búsqueda principal de una JDatatable (plugin de jquery), se quiere llevar de él su valor de búsqueda, para enviar a un reporte ireport o a una consulta sql externa, entre otros casos.

Es decir busco por código, 504290, busca en el json y trae los valores, podría obtener esos valores leyendo el DOM de la tabla o con una función del plugin JDatatable para leer las filas del resultado de la búsqueda, pero lo que realmente requerimos es hacer llegar el criterio con el cual se busco.

Este es un proceso de programación sencillo, el lió se da es cuando se quiere obtener ese valor de la caja, porque esta no posee recurso de código alguno fuera del plugin donde editar este componente, entonces nos vamos  de esta la forma mas fácil.
   
          //En el Controlador
              string2 += "script type="text/javascript"";
              string2 += "  $(function() {";
              string2 += "      var oTableSP =  $('#TablaSeguimientoProduccion').dataTable({"
                    + "             \"bJQueryUI\": true,\n"
                    + "      \"bPaginate\": false\n"
                    + "      \"sScrollY\": '200px',\n"
                    + "      \"bPaginate\": false,\n"
                    + "      \"bScrollCollapse\": true\n"
                    + "        });";
              string2 += "  });";
              string2 += " $(document).ready(function() { "
                    + "     $('div#TablaSeguimientoProduccion_filter input').change(function() { "
                    + "         document.getElementById('formVisor:hiddengeneral').value = $('div#TablaSeguimientoProduccion_filter input').val();"
                    + "      }); "
                    += "  }); ";
              string2 += "/script";
              return string2;
            }
        //el setter y getter para gestionar la informacion de busqueda
            private String filtroGeneral;
            public String getFiltroGeneral(){
               return filtroGeneral;
            }
            public void setFiltroGeneral(String filtroGeneral){
               this.filtroGeneral=filtroGeneral
            }
    

                 //componente xhtml para pasarle el valor, es de tipo oculto no se necesitaria mostrar solo es para que el controlador sepa donde esta la informacion 
                 //y con javascript se pueda enviar.
                            h:inputHidden id="hiddengeneral" value="#{controllador.filtroGeneral}"/

domingo, 8 de diciembre de 2013

Ejecutar Reportes Ireport (java) desde una Aplicación Web php


Cuando surgió la necesidad de ejecutar un reporte .jasper desde una aplicación web php, inicie un proceso de investigación y cacharreo con herramientas que me permitieran llamar un reporte java desde un recurso php. Esta forma sirve tanto para linux como para windows.

Al inicio solo encontré en la red javabridge, pero pasado el tiempo sin obtener resultados después de ensayar muchas formas, decidí ir a una herramienta que hace mucho tiempo había escuchado y hasta leído, una herramienta de caucho(resin) que nos permite ejecutar una aplicación php dentro de un servidor de aplicaciones web en mi caso glassfish. 

Quercus me saco del apuro, lo que hice, y que muchos en la red no enfrentaron fue, no tener que depender de un servidor apache, en mi caso dependía de lampp, configure php.ini, instale recursos javabridge de todas las formas y métodos, y solo encontré problemas, al final de la noche me decidí y empece a usar quercus para ver como desde allí podía llamar los reportes, ya que al estar dentro de un contenedor de aplicaciones java me permitiría ir directamente a los recursos de java y así fue.

el mecanismo para realizar este procedimiento es sencillo.
  • PHP: los recursos normales instalados en el servidor físico o maquina de trabajo linux
  • Quercus: recurso para ejecutar una aplicación php dentro de un servidor de aplicaciones java
    • Descarga: descargar de http://quercus.caucho.com/Quercus_x.x.x.war
    • Instalación: 
      • desplegar el Quercus_x.x.x.war desde la consola de administración de glassfish.
    • Librerías: Copiar las librerías necesarias dentro del web-inf del proyecto quercus desplegado, todas las usadas en jasperreport para exportar el pdf, para conexión el driver conector postgres, y alticJasper.jar parar realizar la conexión desde php al conector y el jasperreport.
  • Glassfish: servidor de aplicaciones web J2EE, JSE, etc.
  • Jasperreport: tecnología para realizar reportes java enlazados a bases de datos 

Código php usado para llamar el reporte .jasper, adaptado de la red.



//directorio de los reportes
$dir = "/home/iproject/glassfish-3.1.2.2/glassfish/domains/domain1/applications
/quercus-4.0.37/EAOptimaERP_v1.2_Contabilidad/reportes";
//Especificamos el nombre del reporte
$informe = "/reporte";

    try {


//Creamos la conexión JDBC
        $Conn = new Java("org.altic.jasperReports.JdbcConnection");

//Seteamos el driver mysql
        $Conn->setDriver("org.postgresql.Driver");

//Especificamos los datos de la conexión
        $Conn->setConnectString("jdbc:postgresql://localhost:5432/
optimaerp_db");
        $Conn->setUser("postgres");
        $Conn->setPassword("");

// Creamos una variable tipo arreglo que contendrá los parámetros 
        $parametrosMap = new Java("java.util.HashMap");
        $parametrosMap->put("usuario", new Java('java.lang.String','YovanySuarez'));

//Creamos el objeto JasperReport que permite obtener el reporte
        $sJfm = new Java("net.sf.jasperreports.engine.JasperFillManager");

//Guardamos el reporte en una variable $print para luego exportarla
        $print = $sJfm->fillReportToFile($dir . $informe . ".jasper", 
$parametrosMap, $Conn->getConnection());

//pdf en el directorio donde están los reportes
        $sJem = new Java("net.sf.jasperreports.engine.JasperExportManager");
        $sJem->exportReportToPdfFile($print, $dir . $informe . ".pdf");

//abre el archivo generado desde el explorador
        if (file_exists($dir . $informe . ".pdf")) {
            header("Content-disposition: attachment;filename=" . $informe . ".pdf");
            header("Content-Type: application/pdf");
            header("Content-Transfer-Encoding: binary");
            header("Content-Length: " . @filesize($dir . $informe . ".pdf"));
            header("Pragma: no-cache");
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Expires: 0");
            set_time_limit(0);
            @readfile($dir . $informe . ".pdf") or die("error.");
        }
    } catch (JavaException $ex) {
        echo "error ";
        $trace = new Java("java.io.ByteArrayOutputStream");
        $ex->printStackTrace(new Java("java.io.PrintStream", $trace));
        print "java stack trace: $trace\n";
    }

viernes, 18 de octubre de 2013

El Modelo de negocio de las aplicaciones android.!

pensar en aplicaciones móviles en la era actual y pensar que se obtendrán beneficios por su elaboración o por la publicidad aunque no es falso es una dura forma de obtener ganancias y continuar con la evolución de un proyecto android app.
Lo mejor es pensar en la red del negocio, el sistema de procesos que realmente contienen la aplicación móvil, es decir no pensar en hacer una aplicación de guardar fotos en un servidor web  y guardar la localización de esa foto y ya, si más bien pensar en que esa foto ( por ejemplo un hueco peligroso en una autopista) hace parte de una red que contiene nodos importantes y que sus procesos son muy necesarios para la sociedad y para el que se moviliza por las calles.

Con datos obtenidos por clientes individuales se le puede dar información mas compleja a una sociedad. Cada cliente con cuenta independiente alimenta el sistema, el sistema procesa y toma decisiones de acuerdo a análisis previos programados.

lunes, 19 de agosto de 2013

Pasar parámetros desde cliente javascript a JSF

En ocasiones se hace necesario llevar desde nuestra capa de presentacion, valores de javascript a un controlador jsf y de una a un xhtml, lo importante aca no es como se hace llegar sino como se captura, se puede enviar mediante ajax, mediante una url, etc.

Con las nuevas actualizaciones de JSF 2.0 se puede hacer de una manera muy fácil.
  •  Enviar el parametro por url
  • Código en el .xhtml que espera el parámetro y muestra.
  • Código en el controlador que recoge y envia al .xhtml

Aplicación movil con primefaces, JSF, EJB y postgres

Cuando me encontré con la necesidad laboral de realizar una aplicación móvil según  requerimiento del sistema ERP que venimos desarrollando hace dos años, para una empresa multinacional en Panamá  empece a investigar a fondo cual seria la opción mas viable para integrar mecanismos de software para móviles que nos permitiera tomar parte de la lógica del negocio ya existente (EJB) , con un costo computacional bajo, tecnología multiplataforma y orientado a la web, tome la decision de usar los recursos de primefaces mobile.

Estas fueron mis opciones:

  • Opción 1: Aplicación móvil para Android
Tenia todos los recursos para conectividad con postgres, recursos gráficos y demás componentes del jdk de android, plataforma de desarrollo integrada en netbeans, ágil y fácil de instalar, pero a la hora de pensar en ¿si todos mis usuarios tendría android?, se callo en el dilema multiplataforma, pailas no había nada que hacer con android, muy bonito y todo, fácil de programar, pero nada que hacer a la hora de requerir sistema operativo especifico.
 
  • Opción 2: Aplicación web para móviles en Primefaces Mobile.
Con primefaces mobil tenia la útil herramienta que me brindaba componentes fáciles de integrar con mis controladores de sesión ya existentes, ademas me permitía usar como librería mi componente principal en la aplicación grande (ERP), Primefaces es un framework para aplicaciones web integrado con xhtml (JSF 2), su evolución es constante y posee una gran comunidad de foristas y blogeros
  • Opción 3: Windows móvil
Esta si que ni mente le gaste, iba a ser igual a la primera opción.

Definitivamente me quedaría con la opción 2, por ser la mas atractiva a cumplir mi requerimiento de multiplataforma, solo se necesitaría un navegador web para usar la interfaz y como todo SO en la actualidad tiene sus navegadores afines, entonces empece a desarrollar este cuento, después de esta historia les comparto la técnica y los recursos para que monten sus app móviles de manera rápida y oportuna.

  1. Librería primefaces mobile.
    1. Descargar la libreria de la pagina oficial del proyecto primefaces.org
  2. Themes
    1. no se requiere agregar libreria del tema visual pues  ya viene con uno por defecto
  3. Configuracion
    1.  en el archivo web xml ...
  4. Entidades ...
  5. Interfaces ...
  6. Controladores ...
  7. Vistas(xhtml) ...
 Imagenes.










viernes, 16 de agosto de 2013

Uso del System.out.print en java

Escribir en consola es bueno, agradable a nuestra satisfacción de respuesta de la maquina ante lo que le programamos que haga, pero evidentemente cuando este aspecto pasa a producción es decir sale de nuestra maquina de desarrollo y pasa a un servidor de aplicaciones j2ee configurado para producción,  un log que se escribe constantemente, nos puede recargar recursos de la maquina (y de centavo en centavo se ... ). Es necesario una buena optimización de una aplicación j2ee en un servidor en producción y se debe empezar por los pequeños detalles.





Dos opciones, para optimizar, 

  • Retirar de la configuración en el archivo de glassfish que genera el log(archivo físico , la linea que escribe los sucesos de las acciones en la aplicación. lo que se escribimos en el System.out.print. esta es la mas breve y solo se requiere llegar hasta los archivos físicos en el interior del código de glassfish o buscarlo por administración de glassfish.
  • Ser cuidadoso a la hora de dar respuestas muchas veces obvias por cada acción que se realice en el sistema, esta obviedad pueda brindar información de momento muy importante, como quien registro en cierta estación de trabajo, con solo ver un log, y no tener que ir hasta una bd y consultar. Genera un costo de proceso, claro, asignarle a un procesador que haga esta acción, implementado en java con procesamiento paralelo sera genial y liviana la carga de los procesadores.
mas sobre paralelismo y como empezar orientándolo a nuestras aplicaciones j2ee...

domingo, 11 de agosto de 2013

Upload de archivos en una aplicación web con JSF 2.0

Upload con JSF 2.0
  • Carpeta destino
Es importante tener una carpeta definida en el contexto de la aplicación para crear los archivos subidos por el recurso java de fileupload y primefaces en jsf 2.0
nuestro directorio destino se encuentra en /modulos/rh/rhEmpleadoFoto/fotos

  • En el .xhtml

<h:form enctype="multipart/form-data" id="formfileupload" prependid="false">
     <!--aca neustro componente se ejecuta automaticamente apenas recibe el archivo-->
            <p:fileupload actualiza="" allowtypes="/(\.|\/)(gif|jpe?g|png)$/" auto="true" cancellabel="Cancelar" componente="" donde="" dragdropsupport="true" fileuploadlistener="#{rhEmpleadoFotoController.accionFileUpload}" foto="" grafico="" id="fileupload" imagen="" la="" label="Seleccionar" mi="" mode="advanced" rendered="true" renderiza="" se="" sizelimit="1000000" update=":formpersonal:idRhEmpleadoFoto" uploadlabel="Subir al servidor" xhtml="">
            </p:fileupload> 
            <!--
  para tener donde visualizar la imagen despues de ingresarse.
                El nombre en el contexto de la aplicacion para mi controlador es rhEmpleadoFotoController 
                -->
        <p:graphicimage cache="false" height="300" id="imagemTmp" style="margin: 0 auto;" value="#{rhEmpleadoFotoController.imagem}">
</p:graphicimage></h:form>
En nuestro xhtml ingresamos el anterior codigo, lo adaptamos de acuerdo al framework que estemos usando en mi caso primefaces.
  • Controlador
En el cuerpo de mi controlador ingreso estas funciones teniendo en cuenta que algunas propiedades se deben declarar como privadas en el controlador y se les debe crear métodos accesores y colocadores para que sean accedidos desde otros ámbitos de la aplicación en las .xhtml(UI)
    
public void accionFileUpload(FileUploadEvent event) { //evento propio del framework
        try {
            file = event.getFile();
            byte[] foto = event.getFile().getContents();
            String nomeArquivo = event.getFile().getFileName();
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ServletContext scontext = (ServletContext) facesContext.getExternalContext().getContext();
            String archivo = scontext.getRealPath("/modulos/rh/rhEmpleadoFoto/fotos/" + nomeArquivo); //guardar en ruta basica para luego mover
            crearArchivo(foto, archivo);
            imagem = new DefaultStreamedContent(event.getFile().getInputstream()); //agregar geter y seter para poder ser accedida desde otros xhtml
            
            selectedEntidad = new RhEmpleadoFoto(); //entidad para persistir en la base de datos
            selectedEntidad.setNombre(nomeArquivo);
            selectedEntidad.setIdRhEmpleado(idRhEmpleado);
            long peso = event.getFile().getSize();
            int x = (int) peso;
            selectedEntidad.setPeso(x);
            selectedEntidad.setRuta("/modulos/rh/rhEmpleadoFoto/fotos");
            selectedEntidad.setLlaveUnica(GenerarRandom().toString());
            selectedEntidad.setEstadoEliminado(Boolean.FALSE);
            getFacade().create(selectedEntidad); //crea el objeto(RhEmpleadoFoto) en la bd

     //dos objetos para hacer renombrado de archivo y copiado a carpetas
            RhEmpleadoFoto current = ejbFacade.findObjeto(selectedEntidad);
            RhEmpleadoFoto current2 = new RhEmpleadoFoto();
            RhEmpleadoFoto current2 = ejbFacade.findObjeto(selectedEntidad);
            
            
            if (renombrarArchivo(current2.getRuta() + "/" + current2.getNombre(), current2.getRuta() + "/" + (idRhEmpleado.getIdRhEmpleado() + ""))) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Mensaje:", "Ingreso Exitoso"));
            } else {
                if (renombrarArchivo(current2.getRuta() + "/" + current2.getNombre(), current2.getRuta() + "/" + (idRhEmpleado.getIdRhEmpleado() + ""))) {
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Mensaje:", "Ingreso Exitoso")); //para enviar el mensaje a la growl del framework
                } else {
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Mensaje:", "" + current2.getRuta() + "/" + current2.getNombre() + " " + current2.getRuta()));
                }
            }

            recreateModel();
            FacesMessage msg = new FacesMessage("Succesful", file.getFileName() + " Fue Cargado Exitosamente.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
            //cerrarPanelFoto(); //una funcion booleana para renderizar el contenido en el xhtml de acuerdo a lo sucedido
        } catch (Exception ex) {
            Logger.getLogger(IngenieriaProductoImagenController.class.getName()).log(Level.SEVERE, null, ex.getMessage());
            FacesMessage msg = new FacesMessage("Succesful", file.getFileName() + " Error en la carga:" + ex.getMessage());
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }
    
     /**
     * Funcion para mover y renombrar un archivo
     *
     * @param String archivo Archivo o directorio a renombrar
     * @param String directorio Directorio destino
     * @exception RCException Se genera una excepción genérica.
     * @return boolean
     */
    public boolean renombrarArchivo(String archivo, String directorio) {
        try {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ServletContext scontext = (ServletContext) facesContext.getExternalContext().getContext();
            String Sarchivo = scontext.getRealPath(archivo);
            File archivos = new File(Sarchivo);
            String Sdirectorio = scontext.getRealPath(directorio);
            File dir = new File(Sdirectorio);
            String name = archivos.getName();
            int j = name.indexOf(".");
            String newname = "" + GenerarRandom() + "" + name.substring(j, name.length());
            boolean semovio = archivos.renameTo(new File(dir, newname));
            if (!semovio) {
                System.out.print("El archivo no se ha Movido ...");
                return false;
            } else {
                current.setNombre(newname);
                current.setRuta("/modulos/rh/rhEmpleadoFoto/fotos/" + idRhEmpleado.getIdRhEmpleado()); //una carpeta con el id del objeto que lo contiene, en mi caso empleado
                ejbFacade.edit(current);
                System.out.print("Se Movio ...");
                return true;
            }
        } catch (Exception e) {
            System.out.print("" + e.getMessage());
            return false;
        }
    }

     /**
     * Funcion para crear un archivo
     *
     * @param byte[] bytes objeto
     * @param String archivo archivo
     * @exception RCException Se genera una excepción genérica.
     * @return void
     */
    
    public void crearArchivo(byte[] bytes, String archivo) {
        FileOutputStream fos;
        try {
            fos = new FileOutputStream(archivo);
            fos.write(bytes);
            fos.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(IngenieriaProductoImagenController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(IngenieriaProductoImagenController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
  • Web.xml
Anexar estas lineas al archivo de configuración de la aplicación web, pero depende del framework usado, en mi caso primefaces.
   <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class> //de mi framework
        <init-param>
            <param-name>thresholdSize</param->
<!--tamaño maximo de los archivos para el contexto de la aplicacion-->
            <param-value>512000</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    <filter>
        <mime-mapping>
        <extension>png</extension>
        <mime-type>image/png</mime-type>
    </mime-mapping>
  •  Librerías 
 usar la librería commons-fileupload-1.2.2.jar y sus librerías dependientes

 Para una opcion mas clara en lenguaje nativo descargue este ejemplo. >>

sábado, 13 de julio de 2013

Rango de fechas y limite de registros en una consulta (EJBQL)


   
 @Override
 public List FindByUsuario(int idSeguridadUsuario) {
        Date start = fourDaysLater3pm();
        Date end = nextDay11Am();
        Query query = em.createQuery("select object(o) 
            from OrdenProduccionRegistros as o 
            where o.idSeguridadUsuario.idSeguridadUsuario='" + idSeguridadUsuario + "' 
           and o.fecha BETWEEN :start AND :end 
           ORDER BY o.fecha, o.idOrdenProduccionRegistros DESC")
.setParameter("start", start, TemporalType.DATE)
.setParameter("end", end, TemporalType.DATE);
        query.setMaxResult(10);
        return query.getResultList();
    }

    @SuppressWarnings("unused")
    private Date nextDay11Am() {
        Calendar t = (Calendar) today().clone();
        t.set(Calendar.AM_PM, Calendar.AM);
        t.set(Calendar.DATE, t.get(Calendar.DATE) + 1);
        t.set(Calendar.HOUR, 11);

        return t.getTime();
    }

    @SuppressWarnings("unused")
    private Date fourDaysLater3pm() {
        Calendar t = (Calendar) today().clone();
        t.set(Calendar.AM_PM, Calendar.PM);
        t.set(Calendar.DATE, t.get(Calendar.DATE) + 4);
        t.set(Calendar.HOUR, 3);

        return t.getTime();
    }

    private Calendar today() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);

        return calendar;
    }

martes, 14 de mayo de 2013

Ireport y el error : net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression

Cuando se usa la tecnología ireport para generar reportes, se presentan algunos detalles a tener en cuenta, cuando de su implementación en J2EE se trata.
  • Groovy es un lenguaje de desarrollo al igual que java.
  • Ireport contiene mecanismos para generar reportes en .pdf, .xls, etc. Su tecnología permite que las plantillas .xml que generan el contenido dinámico sea editadas en el ide en cualquier sistema operativo. Si no fuera así ireport no tendría versiones según el sistema operativo, es decir esa es una opción descartada en el proceso de test de fallos.
  • Ireport es un ide para editar plantillas xml que generan contenido en diferentes formatos
  • Jasperreport es la librería que permite transformar a partir de plantillas xml un archivo .pdf, .xls, etc.
  • Jaspersoft es la comunidad creadora de todo este cuento.

Mensaje de error enviado por el servidor sobre la excepción
 lanzada de ireport  cuando se trabaja con groovy.

[#|2013-05-14T15:53:21.684-0500|WARNING|glassfish3.1.2|javax.enterprise.resource
.webcontainer.jsf.lifecycle|_ThreadID=99;_ThreadName=Thread-2;|#{
controllerReporte.generarImpresion('reporte_comercial_pedidos.jasper',
comercialPedidoController.selected.idComercialPedido,'OF')}: 
net.sf.jasperreports.engine.JRRuntimeException: 
net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression : 
Source text : new java.lang.Integer(1)
javax.faces.FacesException: 
#{controllerReporte.generarImpresion('reporte_comercial_pedidos.jasper',
comercialPedidoController.selected.idComercialPedido,'OF')}: 
net.sf.jasperreports.engine.JRRuntimeException: 
net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression : 
Source text : new java.lang.Integer(1) at 
com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.
java:118)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:935)
at 
com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.
java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at 
org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)

Para dar solución se configura el ireport para que su compilador sea java mas no groovy. igualmente a cada reporte se le configura su lenguaje como java no groovy.

Configuración de propiedades en el reporte.