jueves, 28 de febrero de 2013

Configuracion de Struts 1.3.10 taglib sobre JBoss as 6

Me encontré con que debo migrar la aplicación antes realizada en Struts 1.3.10, que corre muy bien sobre JBoss As 5, a JBoss AS 6, pero me aparece un error que tiene que ver con :

http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd

donde se decía que no se podía resolver o estaba mal formada.

Todo tiene que ver con el formato de las tld de struts, como anteriormente el proyecto se había creado en Struts 1.2, quedaron las tld con el formato anterior (1_1), entonces hay que cambiar al formato correcto (1_2), para ello hay que modicar los archivos que se encuentran en :

[APP_HOME]/WEB-INF/struts-bean.tld
[APP_HOME]/WEB-INF/struts-logic.tld
[APP_HOME]/WEB-INF/struts-nested.tld
[APP_HOME]/WEB-INF/struts-tiles.tld
[APP_HOME]/WEB-INF/struts-html.tld

Y colocar el formato para la versión 1.2 reemplazando:

Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd

por

Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_2.dtd

y colocando el formato de trags correspondiente reemplazando donde aparezca:

tlibversion por tlib-version
jspversion por jsp-version
shortname por shortname
tagclass por tag-class
teiclass por tei-class
bodycontent por body-content

Asi debe quedar el codigo:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_2.dtd">
<taglib>
    <tlib-version>1.3</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>bean</short-name>

Como se ve deben quedar las versiones correspondientes a cada caso:


<tlib-version>1.3</tlib-version>
<jsp-version>1.2</jsp-version>



Hay que realizar estos cambios en todos los archivos antes mencionados, guardar cambios y reconstruir el war de la aplicación.

Algo mas, si en la aplicación en las librerías esta una libreria bsf*.jar esta debe ser eliminada de esa ruta, ya que JBoss ya tiene esa librería en su path.

:)

lunes, 30 de abril de 2012

Como ejecutar un Servicio Web en JBoss 5 AS?

Como ejecutar un Servicio Web en JBoss 5 AS?

Trabajando con Netbeans tuve que hacer un SW, lo cual no es difícil y pues corriendo en Tomcat no tiene misterio. El problema vino cuando quise correr el servicio en JBoss 5. Pues aparecía un error algo extraño:

setProperty must be overridden by all subclasses of SOAPMessage

Raro, dice uno. ¿Por qué en tomcat funciona bien y en JBoss no?

Pues bien, la solucion no es estan dificil solo debia seguir dos instrucciones simples:

1. Ir a la carpeta JBOSS_HOME/client, y de alli copiar los archivos: 

jbossws-native-saaj.jar,
jbossws-native-jaxrpc.jar,
jbossws-native-jaxws.jar,
jbossws-native-jaxws-ext.jar

2. Pegar los archivos copiados en la carpeta  JBOSS_HOME/lib/endorsed.

3. Reiniciar el JBoss.

JBOSS_HOME es la carpeta donde se ha instalado el JBOSS. que en mi caso era C:\jboss-5.1.0.GA... si, un windows.

Y listo!!, pero cuando uno no sabe algo tan sencillo puede tomarse un par de dias encontrar la solucion :(.

viernes, 2 de marzo de 2012

Sybase Procedimiento almacenado con out y resulset de java jdbc

Me encontré con que no se pueden hacer tantas cosas como uno quiere en SYBASE como si ocurre en ORACLE, asi que me puse en la tarea de hacerlo, y pum!! Duro contra el mundo.

Tengo un procedimiento almacenado que me devuelve tanto un resulset como el total de los registros consultados, pero o sorpresa!, en SYBASE no va, mientras que en SQL todo bien... QUE PASO??? una tarde y una noche con el problema en mente, casi no duermo y llego al otro día y me pongo a investigar... y que cosa cruel.

Resulta que la consulta:

SELEC TOP 13 * FROM S_SOLICITUDES
WHERE SOL_ID NOT IN(
SELECT TOP 0 SOL_ID INTO #SOLICITUDES
FROM S_SOLICITUDES
ORDER BY SOL_ID
)

NO FUNCIONA EN SYBASE!!!!

(Lookup Error - Msg 156, Level 15, State 34, Server XXX, Line 1 - Sybase Database Error: Sintaxis incorrecta junto a la palabra clave 'TOP'.)

Carambas, mientras que en SQL Server todo bien, uno a, run like hell.

Pues pregúntale a google, y por supuesto da pereza buscar en ingles, buscaba en español y o sorpresa encontré algo:

En SYBASE solo se puede colocar el TOP en la primera línea de ejecución, en otro lugar como en una sub-consulta es un error garrafal... cosas del dueño.

Así que... y ahora que!?

A pelar papas, cargar bultos, o vender tintos!! Pero no, no, no me rindo.

Encontré la solución, crear la tabla temporal antes de la consulta así:

SELECT TOP 0 SOL_ID INTO #SOLICITUDES
FROM SOLICITUDES
ORDER BY SOL_ID

SELEC TOP 13 * FROM S_SOLICITUDES
WHERE SOL_ID NOT IN(
SELECT SOL_ID FROM #S_SOLICITUDES
)

Y SYBASE RULS!! Todo bonito, la vida nos sonríe... pero y si no lo hago en una ejecución normal, es decir si creo un procedimiento almacenado donde se haga esto? Pues bien a darle al PL, digo al TL jejejeje, ya estoy medio corrido.

y obtengo este hermoso bloque:

CREATE PROCEDURE PPAG_S_SOLICITUDES
@index INT,
@pageSize INT,
@strWhere VARCHAR(16000),
@strOrderBy VARCHAR(16000),
@totalRecords NUMERIC(15) OUTPUT
AS
BEGIN
DECLARE @STRSQL VARCHAR(16000)
DECLARE @v_pageSize INT
DECLARE @v_index INT

SET @v_index = @index - 1
SET @v_pageSize = @pageSize + 1

SET @STRSQL = 'SELECT @totalRecords = COUNT(SOL_ID) FROM S_SOLICITUDES'
IF @strWhere <>'' AND @strWhere IS NOT NULL
SET @STRSQL = @STRSQL || ' WHERE 1=1 ' || @strWhere

SET @STRSQL = @STRSQL || ' SELECT TOP ' || CAST(@v_index AS VARCHAR)
||' SOL_ID INTO #S_SOLICITUDES FROM S_SOLICITUDES'
IF @strWhere <>'' AND @strWhere IS NOT NULL
SET @STRSQL = @STRSQL || ' WHERE 1=1 ' ||@strWhere
||' ORDER BY SOL_ID'

SET @STRSQL = @STRSQL || ' SELECT TOP ' || CAST(@v_pageSize AS VARCHAR)||' * FROM S_SOLICITUDES'
||' WHERE SOL_ID NOT IN( SELECT SOL_ID FROM #S_SOLICITUDES ) '
IF @strWhere <>'' AND @strWhere IS NOT NULL
SET @STRSQL = @STRSQL || ' WHERE 1=1 ' ||@strWhere
IF @strOrderBy <>'' AND @strOrderBy IS NOT NULL
SET @STRSQL = @STRSQL || ' ORDER BY ' ||@strOrderBy

EXEC(@STRSQL)

END /* PPAG_S_SOLICITUDES */


Creo que estoy tan mal con esto de los lenguajes que hasta estoy usando CAST en vez de CONVERT, nehhhh, pero SYBASE no chilla, asi que deje asi.

Y lalalala, dale al compilar y que lindo… pasó!!! Vamos bien, ahora a ejecutar:

declare @totalRecords_out Numeric
execute PPAG_S_SOLICITUDES @index = 1,@pageSize = 13,@strWhere = '',@strOrderBy = 'SOL_FECHA_REG DESC',@totalRecords = @totalRecords_out output
select @totalRecords_out

y...... plop!!! se cayó condorito!!!

E investigando encontré una buena respuesta:Enlace
http://www.forosdelweb.com/f21/sybase-15-tabla-temporal-955230/

Así que me toco meterme con ese parámetro sp_dboption database_name,"ddl in tran", true pero no se recomendaba, bueno habrá que ver que dicen en el Cliente.

Y Run like hell!!!

Y dije para mis adentros YATTA!!! I love SYBASE!, Corro entonces la aplicación y oops!!

Output parameters have not yet been processed. Call getMoreResults()

Qué es eso!?? Sera que me va bien de camarero??? No, no, no a revisar el código… y me voy a la famosa función que hace el llamado al procedimiento, que por supuesto me toco arreglar para nuestro SYBASE, migrando desde ORACLE, y así se veía…

public ArrayList page(int index, FilterDAO filter, String orderBy) throws PersistenciaException {
Connection conn = null;
CallableStatement stmt = null;
ResultSet rs = null;
ArrayList result = null;
String strSQL = "", strWhere = "";
if (filter != null) {
strWhere = filter.getStrWhere();
}

try {
/*
* Se revisa la base de datos para determinar que algoritmo usar.
*/
int pageSize = 13;
if (this.BASE_CONTROL.equalsIgnoreCase("ORACLE")) {
strSQL = "{call PPAG_S_SOLICITUDES(?,?,?,?,?,?)}";
} else if (this.BASE_CONTROL.equalsIgnoreCase("SQL") || this.BASE_CONTROL.equalsIgnoreCase("SYBASE")) {
strSQL = "{call PPAG_S_SOLICITUDES(?,?,?,?,?)}";
}

conn = this.getConnection();
stmt = conn.prepareCall(strSQL);
setInteger(stmt, index, 1);
setInteger(stmt, pageSize, 2);
setString(stmt, strWhere, 3);
setString(stmt, orderBy, 4);
stmt.registerOutParameter(5, java.sql.Types.NUMERIC);

if (this.BASE_CONTROL.equalsIgnoreCase("ORACLE")) {
stmt.registerOutParameter(6, oracle.jdbc.OracleTypes.CURSOR);
stmt.execute();
rs = (ResultSet) stmt.getObject(6);
filter.setTotal(stmt.getDouble(5));
} else if (this.BASE_CONTROL.equalsIgnoreCase("SQL") || this.BASE_CONTROL.equalsIgnoreCase("SYBASE")) {
rs = (ResultSet) stmt.executeQuery();
}
/*
* Si todo ha ido bien se llena el ArrayList con los TOs de
* resultado
*/
filter.setTotal(stmt.getDouble(5));
int posicion = 1;
SSolicitudesTO callTO;
result = new ArrayList();
while (rs.next()) {
callTO = new SSolicitudesTO();
callTO.setPosicion(posicion++);
poblarTO(rs, callTO);
result.add(callTO);
}
} catch (Exception ex) {
throw new PersistenciaException("SSolicitudesDAO.page:{" + ex.toString() + "}");
} finally {
/*
* Ocurra o no error se debe cerrar la conexion para liberar el JNDI
*/
cerrarConexiones(conn, stmt, rs);
}
return result;
}

Vueltas y mas vueltas hasta que después de una mañana entera doy con el chiste, el problema es simple y muy muy bobo así que solo debo hacer el llamado del parámetro out después de haber terminado de recorrer el resultset, osea que la función queda asi:

public ArrayList page(int index, FilterDAO filter, String orderBy) throws PersistenciaException {
Connection conn = null;
CallableStatement stmt = null;
ResultSet rs = null;
ArrayList result = null;
String strSQL = "", strWhere = "";
if (filter != null) {
strWhere = filter.getStrWhere();
}

try {
/*
* Se revisa la base de datos para determinar que algoritmo usar.
*/
int pageSize = 13;
if (this.BASE_CONTROL.equalsIgnoreCase("ORACLE")) {
strSQL = "{call PPAG_S_SOLICITUDES(?,?,?,?,?,?)}";
} else if (this.BASE_CONTROL.equalsIgnoreCase("SQL") || this.BASE_CONTROL.equalsIgnoreCase("SYBASE")) {
strSQL = "{call PPAG_S_SOLICITUDES(?,?,?,?,?)}";
}

conn = this.getConnection();
stmt = conn.prepareCall(strSQL);
setInteger(stmt, index, 1);
setInteger(stmt, pageSize, 2);
setString(stmt, strWhere, 3);
setString(stmt, orderBy, 4);
stmt.registerOutParameter(5, java.sql.Types.NUMERIC);

if (this.BASE_CONTROL.equalsIgnoreCase("ORACLE")) {
stmt.registerOutParameter(6, oracle.jdbc.OracleTypes.CURSOR);
stmt.execute();
rs = (ResultSet) stmt.getObject(6);
filter.setTotal(stmt.getDouble(5));
} else if (this.BASE_CONTROL.equalsIgnoreCase("SQL") || this.BASE_CONTROL.equalsIgnoreCase("SYBASE")) {
rs = (ResultSet) stmt.executeQuery();
}
/*
* Si todo ha ido bien se llena el ArrayList con los TOs de
* resultado
*/
int posicion = 1;
SSolicitudesTO callTO;
result = new ArrayList();
while (rs.next()) {
callTO = new SSolicitudesTO();
callTO.setPosicion(posicion++);
poblarTO(rs, callTO);
result.add(callTO);
}
if (this.BASE_CONTROL.equalsIgnoreCase("SQL") || this.BASE_CONTROL.equalsIgnoreCase("SYBASE")) {
/*
* Colocamos el valor de total de registros en el filtro, si se
* necesita manipular desde donde se ha llamado a page
*/
try {
stmt.getMoreResults();
filter.setTotal(stmt.getDouble(5));
} catch (Exception e) {
System.out.println(e.toString());
}
}

} catch (Exception ex) {
throw new PersistenciaException("SSolicitudesDAO.page:{" + ex.toString() + "}");
} finally {
/*
* Ocurra o no error se debe cerrar la conexion para liberar el JNDI
*/
cerrarConexiones(conn, stmt, rs);
}
return result;
}

Compilamos y run.... y ahora si YATTA!!!

Bueno creo que esta cituacion a desatado una serie de eventos que repercutiran directamente en el futuro de la humanidad, pero no hay que desesperar, se veran los efectos como en los tataranietos de luck skywalker. Ahora si me puedo tranquilizar :P

martes, 1 de marzo de 2011

Librerias Open Source JTwain Scaner y Java, soporta hasta TWAIN 2.0

Estas librerías pueden ser muy útiles.


Habia unas librerias para usar el escaner y la cámara conectados a nuestro pc desde java, por ejemplo desde un applet. Se llama mms-computting, pero volviendo a la pagina del autor no esta habilitada como antes, mas bien aparece un formulario de login, y pues ni modos, antes era otra cosa.


Coloco los links de lo que alcance a obtener de estas librerias, espero a alguien que encuentre esto le sirva.


Los links de cada descripción están en One Drive, no debe haber problema para descargar, en caso de que lo haya se puede descargar el archivo completo desde mediafire en el siguiente link.


http://www.mediafire.com/download/i5pd661abrd711b/mmsc_scanner_libs.zip



Descripción:

mmsc.jar - la librería completa, en este caso es la librería de clases.

source_code_mmsc.jar - Es la librería de los códigos fuentes, muy útil.

uk.co.mmscomputing.application.imageviewer.jar - la librería de clases para ejecutar el ejemplo de la applet.

prueba.html - Archivo html donde se implementa el uso de la applet.


Espero sea de utilidad, por favor comenten!.

Para que no se me olvide como firmar un applet

De esto hay mucho en la red, pero yo lo coloco para que no se me olvide como firmar un applet de java.

Genero la llave en el jre con una vigencia de 360 dias, casi un año:

"C:\Program Files\Java\jdk1.6.0_06\bin\keytool" -genkey -alias grp_sico -validity 360 -v

Construyo mi jar(NBCorresScanner.jar), que usa unas librerias (mmsc), las cuales tuve que descomprimir para que funcionaran con lo que hice:

"C:\Program Files\Java\jdk1.6.0_06\bin\jar" cmf MANIFEST.MF NBCorresScanner.jar ApNBCorresScanner\JApMain.class ApNBCorresScanner META-INF uk

Por ultimo aplico la llave al applet con lo cual queda firmado y listo para colocarlo en web:

"C:\Program Files\Java\jdk1.6.0_06\bin\jarsigner" NBCorresScanner.jar grp_sico -verbose


Uno nunca sabe es mejor tener esto por aqui arribita.