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

jueves, 2 de diciembre de 2010

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.

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:
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

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:

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.

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:
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:

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.
Más información en http://www.topsecurity.dk/cmview/View?id=1575

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:
AddVMOption -Xmx256M
Después de la línea que dice:
AddVMOption  -XX:MaxPermSize=256M
Visto en: http://javainnovations.blogspot.com/2009/10/jdeveloper11g-startup-error.html

viernes, 27 de noviembre de 2009

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:
...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");

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");
...
}

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í :
response.setHeader("Cache-Control", "private");
response.setHeader("Pragma", null);
response.setHeader("Expires", null);
Y ahora sí funciona.

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:
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:
<?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