Para solucionar el error:
XMLHttpRequest cannot load: No 'Access-Control-Allow-Origin' en Wildfly, se debe modificar el archivo de configuración standalone.xml y agregar las líneas que se encuentran resaltadas a continuación:
Recordatorios de un Ingeniero
martes, 26 de septiembre de 2017
jueves, 19 de mayo de 2016
Descifrar una clave de WebLogic
Realizar los siguientes pasos en el WebLogic Scripting Tool (wlst.cmd ó wlst.bash):
domain = C:\\bea\\user_projects\\domains\\base_domain
service = weblogic.security.internal.SerializedSystemIni.getEncryptionService(domain)
encryption = weblogic.security.internal.encryption.ClearOrEncryptedService(service)
print encryption.decrypt("{3DES}5pLoc3OzmAiQ8MyEZBJTkw==")
Visto en: Justin's Blog
domain = C:\\bea\\user_projects\\domains\\base_domain
service = weblogic.security.internal.SerializedSystemIni.getEncryptionService(domain)
encryption = weblogic.security.internal.encryption.ClearOrEncryptedService(service)
print encryption.decrypt("{3DES}5pLoc3OzmAiQ8MyEZBJTkw==")
Visto en: Justin's Blog
sábado, 31 de enero de 2015
Cliente GitHub detrás de un proxy
Agregar las siguientes líneas en el archivo .gitconfig en el directorio de usuario:
[http]
proxy = http://<user>:<pass>@<proxy address>:<proxy port>
[https]
proxy = https://<user>:<pass>@<proxy address>:<proxy port>
martes, 20 de enero de 2015
RC: 73 A connection with a remote socket was reset by that socket
"Many times this issue can be seen in firewall environment and has been seen with network DNS problems and/or network config problems. One of the most common is when a passive device (router, switch, hub, etc.) is in between the client & the server. If the port on the passive device is set to Auto-Negotiate, it will automatically defer to the active device (the NIC in the client) to set the connection speed. If the NIC is also set to Auto-Negotiate (default in most OS's) this often causes excessive delays and interruptions in connectivity. This is because the NIC is looking to the network appliance to set the connection speed and vice-versa, it takes some time before the network device will find a suitable connection speed (not always optimal, just suitable) and begin data transfer. This repeats every time a data packet is sent across the network. While the negotiating period is relatively short by human standards (usually in the nanosecond range) it adds up over time when trying to send a large amount of data at a high speed and causes the connection to be broken. The best work around for that is to hard code both the NIC and the network port for a specific setting. This is usually 100Mb Full Duplex for a standard CAT-5 copper connection, although older equipment may require reconfiguration of 10/100 NICs to allow for that speed.
Another possible workaround for this issue is to estimate the file transfer time and increase the IDLETIMEOUT to a level higher than that time."
IBM
IBM
Etiquetas:
IBM,
was,
web services,
WebSphere
miércoles, 14 de enero de 2015
Iterar objetos de un tipo tabla
DECLARE v_Return TRANSACCION_TBL; BEGIN v_Return := PKG.GET_TRANSACCIONES(); FOR counter IN v_Return.first .. v_Return.last LOOP DBMS_OUTPUT.PUT_LINE('ID: '||v_Return(counter).id_transaccion); DBMS_OUTPUT.PUT_LINE('NOMBRE: '||v_Return(counter).nombre); END LOOP; END;
viernes, 10 de octubre de 2014
Recuperación de transacciones Oracle en WebSphere (AS) 8.5
En el momento de iniciar el servidor de aplicaciones después de una caída, éste intenta recuperar las transacciones de base de datos correspondientes a data sources XA. Con una base de datos Oracle en ocasiones se presenta la siguiente excepción:
El problema se debe a que el usuario de base de datos que estamos usando no tiene permisos para recuperar transacciones, lo que se solucciona ejecutando lo siguiente:
Visto en www-01.ibm.com
0000048 XARminst E WTRN0037W: The transaction service encountered an error on an xa_recover operation. The resource was com.ibm.ws.rsadapter.spi.WSRdbXaResourceImpl@e0881a27. The error code was XAER_RMERR. The exception stack trace follows: javax.transaction.xa.XAException
at oracle.jdbc.xa.OracleXAResource.recover(OracleXAResource.java:709)
at com.ibm.ws.rsadapter.spi.WSRdbXaResourceImpl.recover(WSRdbXaResourceImpl.java:1116)
at com.ibm.ws.Transaction.JTA.XARminst.recover(XARminst.java:141)
at com.ibm.ws.Transaction.JTA.XARecoveryData.recover(XARecoveryData.java:716)
at com.ibm.tx.jta.impl.PartnerLogTable.recover(PartnerLogTable.java:431)
at com.ibm.tx.jta.impl.RecoveryManager.resync(RecoveryManager.java:1534)
at com.ibm.tx.jta.impl.RecoveryManager.performResync(RecoveryManager.java:2267)
at com.ibm.ws.tx.jta.RecoveryManager.performResync(RecoveryManager.java:117)
at com.ibm.tx.jta.impl.RecoveryManager.run(RecoveryManager.java:2220)
at java.lang.Thread.run(Thread.java:773)
El problema se debe a que el usuario de base de datos que estamos usando no tiene permisos para recuperar transacciones, lo que se solucciona ejecutando lo siguiente:
grant select on pending_trans$ to <user>; grant select on dba_2pc_pending to <user>; grant select on dba_pending_transactions to <user>; grant execute on dbms_system to <user>;Si la versión de Oracle es mayor a la 10.2.0.4, se debe remplazar el último privilegio por:
grant execute on dbms_xa to <user>;Otra manera de solucionarlo, en caso de que no sea importante recuperar las transacciones (por ejemplo en un ambiente de desarrollo), es borrando el contendio del directorio <WebSphere Application Server_install_root>\profiles\<PROFILE_NAME>\tranlog\<CELL_NAME>\<NODE_NAME>\<SERVER_NAME>\transaction antes de iniciar el Application Server.
Visto en www-01.ibm.com
martes, 15 de enero de 2013
domingo, 22 de mayo de 2011
element.getAttribute("class") y element.setAttribute("class", "nuevaClase")
Hace mucho tiempo no me encontraba con el problema que tiene Internet Explorer con el atributo class.
Según el estándar DOM, por medio de javascript podemos obtener la clase de un elemento con esta línea:
La razón por la que esto funciona es porque se está accediendo a la propiedad del elemento directamente y no al atributo que es la manera sugerida.
Según el estándar DOM, por medio de javascript podemos obtener la clase de un elemento con esta línea:
clase = element.getAttribute("class");
Y cambiarla, con la siguiente:element.setAttribute("class", "nuevaClase")Pero como a Internet Explorer no le importan los estándares, esos comandos no tienen utilidad en ese "navegador". Hay varias formas de resolver el problemita, pero la más sencilla es no usar los comandos anteriores (los que son del estándar), si no los siguientes:
clase = element.className; element.className = "nuevaClase";De esta forma funciona en todos los navegadores.
La razón por la que esto funciona es porque se está accediendo a la propiedad del elemento directamente y no al atributo que es la manera sugerida.
lunes, 9 de mayo de 2011
Expresiones regulares: diferencia entre match y exec
En javascript las funciones String.match() y RegExp.exec() son muy parecidos. Su única diferencia está en que si se usa la opción g (global), el segundo retornará el primer match y todos lo grupos que se hayan definido en la expresión regular, mientras que el primero no retorna los grupos.
Ejemplo:
Ejemplo:
texto = "aaaa12345aaaa"; regex = /(aaaa)(.*)(aaaa)/g; errorExec = regex.exec(texto); // [aaaa12345aaaa, aaaa, 12345, aaaa] errorMatch = texto.match(exec); // [aaaa12345aaaa]
Etiquetas:
Expresiones regulares,
javascript,
RegExp
jueves, 2 de diciembre de 2010
SciTE: Encontrar números con Regexp
En SciTE, al buscar números utilizando expresiones regulares no es válido usar el caracter especial \d. En esos casos se debe usar [0-9].
Etiquetas:
Expresiones regulares,
RegExp,
SciTE
Cadena vacía en llamado a SP de SQL Server
Al hacer un llamado a un procedimiento almacenado de SQL Server desde Java, en el que uno de los parámetros era una cadena vacía, éste la recibía como si se le estuviera enviando un espacio en blanco, lo cuál no era válido para el SP.
Se me ocurrió hacer una prueba enviando null en el parámetro en cuestión y resultó que el SP lo tomó correctamente.
Etiquetas:
java,
MSSQL,
Procedimiento almacenado,
SP,
SQL Server
lunes, 23 de agosto de 2010
Oracle: Cómo encontrar las tablas hijas de una tabla
Con el siguiente script se pueden encontrar las tablas hijas para determinada tabla:
Visto en Foros de Oracle
select table_name as hijas from user_constraints where r_constraint_name in (select constraint_name from user_constraints where table_name=upper('&table_name') and constraint_type='P') order by table_name;
Visto en Foros de Oracle
lunes, 28 de junio de 2010
HTTPS hostname wrong
Al acceder a una URL como en el post anterior pero utilizando la dirección IP se me pesentó el siguiente error:
java.io.IOException: HTTPS hostname wrong: should be <10.1.84.139>
Encontré en algún lado que para poder pasar esa verificación de hostname se puede crear un HostNameVerifier y setearlo como el que se va a usar por defecto en la aplicación:
El resultado es:
HostName: 10.1.84.139 sessionHost: 10.1.84.139
java.io.IOException: HTTPS hostname wrong: should be <10.1.84.139>
Encontré en algún lado que para poder pasar esa verificación de hostname se puede crear un HostNameVerifier y setearlo como el que se va a usar por defecto en la aplicación:
HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String urlHostName, SSLSession session){ return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(hv);Lo que no entendí es por qué falla la verificación, si al poner la siguiente línea dentro del método verify:
System.out.println("HostName: " + urlHostName + " sessionHost: " + session.getPeerHost());
El resultado es:
HostName: 10.1.84.139 sessionHost: 10.1.84.139
Etiquetas:
HostNameVerifier,
https,
HttpsURLConnection,
java,
ssl
martes, 2 de marzo de 2010
Java: URL's seguras con certificados no confiables
Para acceder a una URL segura desde Java, se hace el mismo procedimiento que con una URL no segura:
Entonces lo que hay que hacer es instalar un TrustManager que no valide los certificados, en el Contexto SSL.
Una vez hecho esto ya podemos hacer lo del código de arriba sin que nos falle por certificados de seguridad.
URL url = new URL("https://www.urlsegura.com"); URLConnection conn = url.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String linea; while ((linea = in.readLine()) != null) System.out.println(linea); in.close();Pero si esa URL segura tiene un certificado no confiable, el acceso a esa URL va a fallar, generando un error similar al siguiente:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Entonces lo que hay que hacer es instalar un TrustManager que no valide los certificados, en el Contexto SSL.
TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { }
Una vez hecho esto ya podemos hacer lo del código de arriba sin que nos falle por certificados de seguridad.
Etiquetas:
java,
ssl,
TrustManager,
URL,
ValidatorException
jueves, 18 de febrero de 2010
iReport 3.7 unable to resolve class JRBeanCollectionDataSource
Hace ya años que no diseñaba un reporte en iReport.
El que tuve que hacer hoy requería de un subreporte y perdí mucho tiempo buscando el origen del error mencionado arriba.
Pues resulta que cuando yo hacía los subreportes, podía pasar el Data Source Expression de la siguiente manera:
Ahora eso genera un error al compilar la plantilla. Y la solución es muy sencilla, toca poner toda la ruta de la clase, es decir:
El que tuve que hacer hoy requería de un subreporte y perdí mucho tiempo buscando el origen del error mencionado arriba.
Pues resulta que cuando yo hacía los subreportes, podía pasar el Data Source Expression de la siguiente manera:
new JRBeanCollectionDataSource($P{unParametro})
Ahora eso genera un error al compilar la plantilla. Y la solución es muy sencilla, toca poner toda la ruta de la clase, es decir:
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{unParametro})
jueves, 4 de febrero de 2010
Autenticación contra Websphere MQ 6.0
Al trabajar contra Websphere MQ 6.0 desde Java, encontré que hacen una autenticación del usuario que intenta leer las colas. El problema es que siempre se envían las credenciales del usuario que está logueado localmente, por lo que siempre nos va a decir que no somos un usuario válido.
El error que sale es:
Para solucionar esto hay algunas alternativas
El error que sale es:
javax.jms.JMSSecurityException: MQJMS2013: se ha indicado una autentificación de seguridad no válida para MQQueueManager
Para solucionar esto hay algunas alternativas
- Agregar el usuario que inicia la aplicación (ej: oas103) en el grupo MQM de la máquina que hospeda el MQ.
- Utilizar la propiedad del sistema user.name y pasarle el valor SYSTEM. Esta propiedad es leída por las clases en com.ibm.mqjms.jar. Este "truco" funciona porque el si servidor de MQ está corriendo como un servicio standard de Windows, se debe estar ejecutando con el usuario SYSTEM.
- Insertar en el código Java, en alguna parte, la misma variable de entorno del punto anterior.
System.setProperty("user.name","SYSTEM")
- En el servidor MQ en el JMSAdmin.config agregar la línea:
"SECURITY_AUTHENTICATION=none"
que deshabilite toda la autenticación.
martes, 2 de febrero de 2010
Error al iniciar JDeveloper 11g
Después de instalar JDeveloper 11g intenté iniciarlo, pero me salió un error diciendo "Unable to create an instance of the Java Virtual Machine Located at path...".
La solución es editar el archivo jdev.conf de la carpeta en la que se instaló el JDeveloper, ejemplo: C:\oracle\Middleware\jdeveloper\jdev\bin.
En este archivo se debe agregar la siguiente linea:
La solución es editar el archivo jdev.conf de la carpeta en la que se instaló el JDeveloper, ejemplo: C:\oracle\Middleware\jdeveloper\jdev\bin.
En este archivo se debe agregar la siguiente linea:
AddVMOption -Xmx256MDespués de la línea que dice:
AddVMOption -XX:MaxPermSize=256MVisto en: http://javainnovations.blogspot.com/2009/10/jdeveloper11g-startup-error.html
jueves, 3 de diciembre de 2009
Cómo ejecutar un archivo sql desde SQL Plus
Para ejecutar un archivo sql desde SQL Plus se pasa como comando la ruta del archivo precedida de un símbolo de arroba(@). Ejemplo:
SQL> @C:\scripts\InsertsBD.sql
viernes, 27 de noviembre de 2009
ajaxEngine.sendRequest : Envío dinámico de parámetros
El uso normal de este método es el siguiente:
ajaxEngine.sendRequest('loadData', 'paramName1=' + paramValue1, ..., 'paramNameN=' + paramValueN);Esto es válido cuando el número de parámetros es fijo. Pero en algunos casos, ese número de parámetros puede variar, por ejemplo si vamos a enviar los valores de un arreglo javascript (como los del post anterior). En tal caso, no resulta tan sencillo el llamado a dicho método. Pero la solución está aquí:
var queryS = "parteNombre="+parteNombre + "&incluir="+incluir; for (i = 0; i < roles.length; i++){ queryS += "&roles=" + roles[i]; } var opt = { method: 'post', postBody: queryS, onSuccess: function(t) { }, on404: function(t) { }, onFailure: function(t) { } }; ajaxEngine.sendRequest('loadData', opt);Primero se crea el queryString con todos los parámetros que queremos enviar y luego se le pasa dinámicamente esa variable al postBody. La verdad no entiendo muy bien cómo funciona, pero funciona. Visto en http://forum.openrico.org/topic/519
Cómo enviar un arreglo en el request
No debe ser algo muy común, pero necesité enviar un arreglo de javascript en un request.
Digo que no debe ser algo muy común, porque pues para eso está el input checkbox.
Pero en este caso la idea no era que lo enviara el usuario sino que el arreglo se carga con variables de la jsp.
En fin, el caso es que para enviar ese arreglo como un parametro en el request, lo que toca hacer es enviar cada uno de los valores del arreglo con el mismo nombre de parámetro. Entonces el querystring sería:
Ya en el servlet, los valores se reciben de la misma manera que se reciben los valores de los checkboxes:
Digo que no debe ser algo muy común, porque pues para eso está el input checkbox.
Pero en este caso la idea no era que lo enviara el usuario sino que el arreglo se carga con variables de la jsp.
En fin, el caso es que para enviar ese arreglo como un parametro en el request, lo que toca hacer es enviar cada uno de los valores del arreglo con el mismo nombre de parámetro. Entonces el querystring sería:
...ActualizarRoles?roles=1&roles=3&roles=4&roles=8
Ya en el servlet, los valores se reciben de la misma manera que se reciben los valores de los checkboxes:
String [] roles = request.getParameterValues("roles");
lunes, 23 de noviembre de 2009
Rico: Too much recursion
Este error ha aparecido con algunas versiones de Rico. Lo que se debe hacer es usar una versión que no tenga el problema.
Pero me acaba de pasar con una versión de Rico que no tiene ese problema. Después de darle muchas vueltas encontré que estaba incluyendo dos veces cada una de las librerías prototype.js y rico.js.
Al dejar la inclusión de solo una de cada una, se resolvió el problema.
miércoles, 2 de septiembre de 2009
Obtener el referer de un servlet
Para obtener el referer (la url desde la que se hizo la petición) de un servlet basta con utilizar lo siguiente:
public void processRequest(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse) throws ServletException{ ... String referer = httpservletrequest.getHeader("referer"); ... }
jueves, 27 de agosto de 2009
Conexión a BD Derby: El esquema no existe
Cuando se crea una nueva base de datos en Derby a través de NetBeans éste no crea el esquema. Es necesario crearlo antes de poder usarlo en una aplicación, de lo contrario nos encontraremos con un mensaje de error diciendo que el esquema que intentamos usar no existe.
Para crear el esquema basta con abrir una conexión a la BD y ejecutar:
Para crear el esquema basta con abrir una conexión a la BD y ejecutar:
CREATE SCHEMA nombredelesquema;
martes, 11 de agosto de 2009
Sentencias en Oracle con ampersand
Cuando se va a hacer un insert o update en SQL*Plus que contenga el símbolo ampersand (&), se pueden obtener resultados que no esperamos.
Hay dos maneras para poder realizar correctamente el insert:
Opción 1:
INSERT INTO empresa values('A & B')SQL*Plus intentará resolver lo que haya después del ampersand como si se tratara de una variable.
Hay dos maneras para poder realizar correctamente el insert:
Opción 1:
SET DEFINE OFF INSERT INTO empresa values('A & B')Opción 2:
INSERT INTO empresa values('A &'||' B')En la segunda opción cada ampersand que vayamos a insertar debe quedar al final de una cadena y luego concatenamos el resto de lo que queremos insertar.
martes, 9 de junio de 2009
Oracle Functions Decode y Sign
Estas funciones son bastante útiles cuando se necesita seleccionar un valor u otro dependiendo de cierta condición.
La función Decode trabaja como un IF-THEN-ELSE o como un IF-THEN-ELSEIF-ELSEIF-...-ELSE. Su sintaxis es:
La función Decode trabaja como un IF-THEN-ELSE o como un IF-THEN-ELSEIF-ELSEIF-...-ELSE. Su sintaxis es:
decode( expression , search , result [, search , result]... [, default] )En los parámetros, expression es el valor que queremos comparar y cada par search-result, funciona como un if, es decir, IF search THEN result. Mejor escribo un ejemplo:
SELECT decode( codigo_empresa, 100, 'Yahoo!', 200, 'Google', 300, 'Sun') FROM empresa;Esto es como si hicieramos algo como:
if ( codigo_empresa == 100 ){ echo 'Yahoo!'; } else if( codigo_empresa == 200 ) { echo 'Google'; } else if( codigo_empresa == 300 ) { echo 'Sun'; }La función Sign nos devuelve un valor para indicar si un número es positivo, negativo o cero (0). Ejemplos:
SELECT sign(-5) from dual; -- Devuelve -1 SELECT sign(1000) from dual; -- Devuelve 1 SELECT sign(0) from dual; -- Devuelve 0 SELECT sign(0.0001) from dual; -- Devuelve 1Ahora, cómo usar juntas estas funciones para obtener un gran provecho? Supongamos que tenemos dos tablas con estructuras similares, donde manejamos unos valores para diario, semanal y mensual. En una de las tablas manejamos los detalles y en la otra manejamos los "topes" máximos que se van a obtener al consultar.
SELECT decode( sign( det.diario - tope.diario ), -1, det.diario, 0, det.diario, tope.diario ) AS diario decode( sign( det.semanal - tope.semanal ), -1, det.semanal, 0, det.semanal, tope.semanal ) AS semanal decode( sign( det.mensual - tope.mensual ), -1, det.mensual, 0, det.mensual, tope.mensual ) AS mensual FROM detalle det, tope;Este query nos va a traer el valor más bajo de las columnas diario, semanal y mensual entre la tabla Detalle y la tabla Tope.
viernes, 5 de junio de 2009
Control de cache en conexiones seguras
Hace poco me salía el siguiente error cuando descargaba un archivo por medio de un servlet desde un sitio seguro a través de Internet Explorer.
Extrañamente, en Firefox este error no se presentaba.
Después de buscar un rato (creo que fue más de un rato) a qué se debía el error, encontré que el problema parece ser un bug de IE (que raro!) y se genera por el uso de una etiqueta que había puesto en el encabezado de la respuesta. La etiqueta que yo tenía es:
Pragma: null
Internet Explorer tiene problemas con este encabezado cuando el sitio es seguro. La solución fue demasiado sencilla, eliminar la etiqueta en cuestión y utilizar la siguiente:
Cache-Control: private
En mi caso puse las cabeceras así :
Extrañamente, en Firefox este error no se presentaba.
Después de buscar un rato (creo que fue más de un rato) a qué se debía el error, encontré que el problema parece ser un bug de IE (que raro!) y se genera por el uso de una etiqueta que había puesto en el encabezado de la respuesta. La etiqueta que yo tenía es:
Pragma: null
Internet Explorer tiene problemas con este encabezado cuando el sitio es seguro. La solución fue demasiado sencilla, eliminar la etiqueta en cuestión y utilizar la siguiente:
Cache-Control: private
En mi caso puse las cabeceras así :
response.setHeader("Cache-Control", "private"); response.setHeader("Pragma", null); response.setHeader("Expires", null);Y ahora sí funciona.
martes, 16 de diciembre de 2008
ORA-00942 La tabla o vista no existe (pero sí existe)
Este error nos ha salido a muchos y generalmente se presenta cuando realmente la tabla o vista no existe en el esquema en el que la queremos usar.
Pero otras veces se genera porque no se han dado los permisos necesarios hacia la tabla o vista, o porque estamos intentando referenciar la tabla sin su esquema (cuando pertenece a otro) y el motor de base de datos se confunde si hay otro objeto en la base de datos con el mismo nombre.
Sin embargo, aunque la tabla exista y aunque se tengan los permisos necesarios para acceder a ella y se use el nombre del esquema al que pertenece, todavía existe la posibilidad de que nos salga el error ORA-00942. Resulta que si los permisos sobre la tabla o vista son concedidos a un rol al que pertenece el usuario con el que necesitamos accederla, es posible ejecutar query's normalmente. Pero si estos query's se van a ejecutar dentro de un procedimiento almacenado, nos vamos a encontrar con ORA-00942.
Qué pasa?
Pues no sé si sea un bug en el RDBMS, o esa sea su forma de administrar los privilegios o tal vez es por razones de seguridad, pero para poder acceder a una tabla o vista desde un procedimiento almacenado, el usuario debe haber adquirido los privilegios directamente y no a través de un rol.
Pero otras veces se genera porque no se han dado los permisos necesarios hacia la tabla o vista, o porque estamos intentando referenciar la tabla sin su esquema (cuando pertenece a otro) y el motor de base de datos se confunde si hay otro objeto en la base de datos con el mismo nombre.
Sin embargo, aunque la tabla exista y aunque se tengan los permisos necesarios para acceder a ella y se use el nombre del esquema al que pertenece, todavía existe la posibilidad de que nos salga el error ORA-00942. Resulta que si los permisos sobre la tabla o vista son concedidos a un rol al que pertenece el usuario con el que necesitamos accederla, es posible ejecutar query's normalmente. Pero si estos query's se van a ejecutar dentro de un procedimiento almacenado, nos vamos a encontrar con ORA-00942.
Qué pasa?
Pues no sé si sea un bug en el RDBMS, o esa sea su forma de administrar los privilegios o tal vez es por razones de seguridad, pero para poder acceder a una tabla o vista desde un procedimiento almacenado, el usuario debe haber adquirido los privilegios directamente y no a través de un rol.
miércoles, 15 de octubre de 2008
Cómo ordenar colecciones de objetos en java
Ordenar colecciones de objetos en java es muy sencillo, basta con hacer un cambio en la clase de los objetos que se van a agregar en la colección.
El cambio consiste en implementar la interface java.lang.Comparable, la cuál nos obliga a implementar únicamente el método compareTo(Object objeto2) de forma que devuelva un entero. El valor devuelto por este método debe ser el equivalente a this - objeto2.
Ejemplo:
Después, suponiendo que articulos es una colección de Articulos, podemos hacer:
El cambio consiste en implementar la interface java.lang.Comparable, la cuál nos obliga a implementar únicamente el método compareTo(Object objeto2) de forma que devuelva un entero. El valor devuelto por este método debe ser el equivalente a this - objeto2.
Ejemplo:
public class Articulo implements Comparable { private String nombre; private Double valor; public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public Double getValor() { return valor; } public void setValor(Double valor) { this.valor = valor; } public int compareTo(Object objeto2) { Articulo articulo2 = (Articulo) objeto2; return this.valor.compareTo(articulo2.getValor()); } }En este ejemplo se hace uso del método ya implementado por parte de la clase Double, pero la implementación la pudimos haber hecho de la manera en que más nos convenga.
Después, suponiendo que articulos es una colección de Articulos, podemos hacer:
Collections.sort(articulos);Y nuestra lista de artículos quedará ordenada.
martes, 7 de octubre de 2008
Internet Explorer y cookies remotas
Una vez más, problemas por culpa de Internet Explorer...
Resulta que a los "genios" desarrolladores del navegador (?) se les ocurrió una grandiosa idea: tratar a las cookies de un sitio cargado dentro de un iframe, como cookies de terceros.
Por ejemplo, tenemos el sitio www.sitiouno.com y dentro de este queremos cargar un iframe con el sitio www.sitiodos.com. El sitio sitiodos envía una cookie al navegador y cuando se ingresa de forma normal a él, el sitio tiene un funcionamiento normal. Al entrar a sitiouno con Internet Explorer se recibe la cookie, pero ésta es tratada como una cookie de terceros.
El problema de que la cookie sea tratada de esa manera es que regularmente los usuarios tienen configurado su IE en un nivel de privacidad medio, el cual "Bloquea cookies de terceros que no tienen una directiva de seguridad sólida". Este bloqueo consiste en que la cookie es eliminada, es decir, no es tomada en cuenta por el maravilloso navegador y generar una experiencia no muy grata para el usuario.
Para corregir este problema de forma rápida, basta con agregar una política de privacidad compacta en las cabeceras de la respuesta antes de intentar crear la cookie. La forma de hacer esto es:
En PHP:
El problema se presenta de la versión 6 en adelante.
Bueno, ese fue el camino corto. El camino largo requiere permiso de cambiar la instalación de Apache para poder instalar mod_header y acceso a los archivos de configuración. Aunque la solución larga no la probamos, si encontramos bastante información:
Los seis pasos para crear y publicar la P3P:
http://www.w3.org/P3P/details.html
Estos son más detallados:
http://www.windley.com/archives/2008/08/p3p_and_internet_explorer.shtml
http://www.builderau.com.au/architect/webservices/soa/Implementing-privacy-preference-policies-with-P3P/0,339024590,320264989,00.htm
Acá les dejo más información:
http://www.w3.org/P3P/
http://www.webmasterworld.com/forum21/788.htm
Resulta que a los "genios" desarrolladores del navegador (?) se les ocurrió una grandiosa idea: tratar a las cookies de un sitio cargado dentro de un iframe, como cookies de terceros.
Por ejemplo, tenemos el sitio www.sitiouno.com y dentro de este queremos cargar un iframe con el sitio www.sitiodos.com. El sitio sitiodos envía una cookie al navegador y cuando se ingresa de forma normal a él, el sitio tiene un funcionamiento normal. Al entrar a sitiouno con Internet Explorer se recibe la cookie, pero ésta es tratada como una cookie de terceros.
El problema de que la cookie sea tratada de esa manera es que regularmente los usuarios tienen configurado su IE en un nivel de privacidad medio, el cual "Bloquea cookies de terceros que no tienen una directiva de seguridad sólida". Este bloqueo consiste en que la cookie es eliminada, es decir, no es tomada en cuenta por el maravilloso navegador y generar una experiencia no muy grata para el usuario.
Para corregir este problema de forma rápida, basta con agregar una política de privacidad compacta en las cabeceras de la respuesta antes de intentar crear la cookie. La forma de hacer esto es:
En PHP:
<?php header('P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); ?>En Java:
httpservletresponse.setHeader("P3P","CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");Cada conjunto de letras tiene un significado y uno lo puede adaptar según a la forma en la que quiera definir su política de privacidad. El anterior ejemplo funcionó muy bien para el problema que tuvimos nosotros, pero en http://www.w3.org/P3P/implementations.html se encuentra software para crear, editar y probar estas políticas a la medida de las necesidades. También está este formulario http://www.dmaresponsibility.org/PPG/, que genera la política según las respuestas que demos.
El problema se presenta de la versión 6 en adelante.
Bueno, ese fue el camino corto. El camino largo requiere permiso de cambiar la instalación de Apache para poder instalar mod_header y acceso a los archivos de configuración. Aunque la solución larga no la probamos, si encontramos bastante información:
Los seis pasos para crear y publicar la P3P:
http://www.w3.org/P3P/details.html
Estos son más detallados:
http://www.windley.com/archives/2008/08/p3p_and_internet_explorer.shtml
http://www.builderau.com.au/architect/webservices/soa/Implementing-privacy-preference-policies-with-P3P/0,339024590,320264989,00.htm
Acá les dejo más información:
http://www.w3.org/P3P/
http://www.webmasterworld.com/forum21/788.htm
miércoles, 24 de septiembre de 2008
Cómo incrementar el valor de una secuencia
El siguiente PL/SQL es útil para incrementar el valor de una secuencia al valor que deseemos:
En PostgreSQL existe la función setval que permite hacer lo mismo.
DECLARE i NUMBER(10); BEGIN SELECT SQCUENTA.NEXTVAL INTO i FROM dual; WHILE i < 1000000 LOOP SELECT SQCUENTA.NEXTVAL INTO i FROM dual; END LOOP; END;Esto me ha funcionado en una BD Oracle 10g.
En PostgreSQL existe la función setval que permite hacer lo mismo.
SELECT setval('SQCUENTA', 1000000);
miércoles, 18 de abril de 2007
Esquema de autenticación de MySQL
Desde la versión 4.1.1 de MySQL el esquema de autenticación cambió para hacerlo más seguro. Desafortunadamente, este nuevo esquema no es compatible con las versiones anteriores (clientes anteriores a la versión 4.1.1) y cuando intentamos loguearnos nos dará el siguiente error:
Client does not support authentication protocol requested by server; consider upgrading MySQL client.
Si no es posible actualizar la versión del cliente con la que nos estamos conectando, podemos hacer una de las dos cosas siguientes, tener en cuenta que esto reducirá la seguridad de nuestro servidor de bases de datos:
Client does not support authentication protocol requested by server; consider upgrading MySQL client.
Si no es posible actualizar la versión del cliente con la que nos estamos conectando, podemos hacer una de las dos cosas siguientes, tener en cuenta que esto reducirá la seguridad de nuestro servidor de bases de datos:
mysql> SET PASSWORD FOR 'username'@'hostname' = OLD_PASSWORD('password');ó
mysql> use mysql; mysql> UPDATE user SET password = OLD_PASSWORD('password') WHERE user = 'username' AND host = 'hostname';Se debe tener en cuenta que los cambios no harán efecto hasta que se haga
mysql> flush privileges;
Etiquetas:
autenticación,
MySQL,
seguridad
Suscribirse a:
Entradas (Atom)