Acerca de:

Este blog contiene los códigos, ejemplos y bases de datos que he usado cuando aprendía acerca de algún tema específico. En lugar de borrarlos (una vez dominado ya el tema), he decidido publicarlos :)
Mostrando entradas con la etiqueta Java 8. Mostrar todas las entradas
Mostrando entradas con la etiqueta Java 8. Mostrar todas las entradas

miércoles, 9 de febrero de 2022

Arreglando el Error: "No appropriate protocol (protocol is disabled or cipher suites are inappropriate)" en Jdk 1.8.0_301

 Quise conectarme desde una aplicación chiquita de java a una base de datos en Sql Server 2017 via el driver jdbc sqljdbc4-2.0.jar. La aplicación la estaba depurando en Netbeans 11.1, corriendo en Windows 10. Todo estaba bien hasta que actualicé a la versión del Jdk a la 1.8.0_301, entonces en la línea:

Connection connection = DriverManager.getConnection(connectionString);

me arrojó esta excepción:

El controlador no pudo establecer una conexión segura con SQL Server con el cifrado de Capa de sockets seguros (SSL). Error: "No appropriate protocol (protocol is disabled or cipher suites are inappropriate)"

En inglés:

The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: “No appropriate protocol (protocol is disabled or cipher suites are inappropriate)”.

Lueo de rebuscar en foros raruchos, hallé en éste la solución:


Es hora de ir a buscar ese archivo. Primero debo cerrar todas las aplicaciones de java: jars y Netbeans incluídos. En mi caso el archivo a modificar está en C:\Program Files\Java\jdk1.8.0_301\jre\lib\security\java.security. Las líneas que debo comentar son las 723, 724 y 725:


Debe quedar así:


En mi caso, basta volver a arrancar las aplicaciones de java (Netbeans incluídos) para resolver el problema y poder conectarme a mi base de datos. Puede ser que en algunos casos sea necesario reiniciar el sistema operativo.

lunes, 25 de enero de 2021

Compilando las librerías Opencv 4.2 y Opencv_contrib con CMake y Visual Studio 2019 para Java

Continuando con el tutorial de OpenCV, esta vez toca generar el jar para poder usarlo desde java.

Yo tengo instalado JDK 8. Mi variable de entorno JAVA_HOME está seteada como C:\Program Files\Java\jdk1.8.0_231. Esta variable de entorno es importante para que CMake pueda hallar la ruta de instalación de java.

Al crear el jar para OpenCV, la diferencia está en algunas opciones al compilar con CMake. Lo bueno de Opencv es que se puede recompilar tantas veces como queramos, y tener una compilación distinta en carpetas diferentes. En este ejemplo, estoy enviando mi compilación para Java a la carpeta D:\opencv2.

Primero: descargar y descomprimir Apache Ant. Ant no se instala, sólo se descomprime. OpenCV lo necesita para generar el jar.

Añadir a la variable de entorno Path la ruta a donde hemos descomprimido Ant, en mi caso es C:\apache-ant-1.10.9\bin

 



Reiniciar el sistema. 

Luego de configurar  CMake, debe de poder reconocer las rutas de java y de ant:


 

A continuación, se deben escoger las siguientes opciones en CMake:

Build_Java:


BUILD_FAT_JAVA_LIB:


Si se desea compilar con opencv-contrib se deben elegir estas opciones:

Y se presiona Generate. Esto creará los proyectos de Visual Studio para crear las librerías y el jar. Se debe compilar como Release los proyectos All_Build e Install como explico en el tutorial anterior.

Y me pasó que no me generó el jar.

Debía aparecer en la carpeta D:\opencv2\bin o en D:\opencv2\install\java. En este caso se debe buscar los proyectos gen_opencv_java_source y opencv_java_jar, y compilarlos primero gen_opencv_java_source y luego opencv_java_jar, ambos como release:


 Necesité más de un intento para poder generar mi jar.

El jar y los archivos lib y dll deben estar en la misma carpeta, yo prefiero ponerlos en la carpeta de mi proyecto. Para usar este jar basta añadirlo como librería (yo uso netbeans):


domingo, 28 de enero de 2018

Abrir y pasarle parámetros a una ventana secundaria desde Java swing en Netbeans

Lo que se necesita en esta ocasión es que al presionar un botón de una ventana en Java Swing, se abra una ventana secundaria una sola vez sin importar cuántas veces se presione el botón, que al cerrar sólo la ventana secundaria la ventana pricipal continúe ejecutandose, y que ambas ventanas se cierren y el programa finalice al cerrar la ventana principal. Además tengo que pasarle parámetros desde la ventana principal a la ventana secundaria al abrirse ésta:


Hacerlo es bastante fácil, se deben crear dos ventanas, la principal frmMain y la secundaria frmOther, ambas del tipo JFrame:


En la ventana principal se declara a nivel de clase:

frmOther formOther;

Y en el listener del botón que abre la ventana secundaria se ingresa el siguiente código:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)                                        
{                                            
    if (formOther == null || !formOther.isVisible())
    {
        formOther = new frmOther("Nuevo ", "Título");
        formOther.setVisible(true);
    }
    else
        formOther.setExtendedState(JFrame.NORMAL);
}  


En este caso la ventana secundaria recibe dos parámetros tipo String, pero se puede hacer que reciba cualquier cantidad  y tipo de parámetros, para esto basta sobrecargar el constructor en la clase de la ventana secundaria (en este caso sólo voy a cambiar el título):

public frmOther(String param1, String param2)
{
    initComponents();
    this.setTitle(param1 + param2);
}


Por último, en la propiedad DefaultCloseOperation  de la ventana secundaria se escoge DISPOSE.



Y eso es todo!
El proyecto en Netbeans 8.0.2 se puede descargar de aquí.

lunes, 30 de marzo de 2015

Recorrer todos los controles en un contenedor: .Net y Java Swing

En este ejemplo, se quiere habilitar los controles de un contenedor en función al valor de selección de un checkbox.

En el caso de Java, el contenedor es un jPanel:

En Java 7:

for (Component c : jPanel1.getComponents())
    c.setEnabled(jcheckBox1.isSelected());
   
En Java 8:

Arrays.stream(jPanel1.getComponents()).forEach(c -> c.setEnabled(jcheckBox1.isSelected()));

Si sólo se quiere procesar los controles que sean cajas de texto:

Arrays.stream(jPanel1.getComponents()).forEach(c -> { if (c instanceof JTextField) c.setEnabled(jcheckBox1.isSelected()); } );

En el caso de .Net, el contenedor es un GroupBox:

foreach (Control c in groupBox1.Controls) 
       c.Enabled = checkBox1.Checked;

Usando Linq será:
groupBox1.Controls.Cast<Control>().ToList().ForEach(c => c.Enabled = checkBox1.Checked);

Si sólo se quiere procesar los controles que sean cajas de texto:
groupBox1.Controls.Cast<Control>().ToList().ForEach(c => { if (c is TextBox) c.Enabled = checkBox1.Checked; });