¿Cómo generar el JAR para poder distribuir la aplicación?
Tras codificar la aplicación Java + openCV + JavaCV surge esta cuestión muy importante. Lo normal para cualquier aplicación Java creada en Netbeans es hacer Run > Clean and Build Project, pero ésto no es todo lo necesario para que todo funcione bien.Aquí es donde hay que rebuscárselas:
1) Copiamos los siguientes archivos en una carpeta dentro de nuestro proyecto. La llamaremos OPENCV e incluiremos los siguientes archivos en ella:
- libopencv_calib3d.so.2.3.1
- libopencv_contrib.so.2.3.1
- libopencv_core.so.2.3.1
- libopencv_features2d.so.2.3.1
- libopencv_flann.so.2.3.1
- libopencv_gpu.so.2.3.1
- libopencv_highgui.so.2.3.1
- libopencv_imgproc.so.2.3.1
- libopencv_legacy.so.2.3.1
- libopencv_ml.so.2.3.1
- libopencv_objdetect.so.2.3.1
- libopencv_video.so.2.3.1
2) De esta manera, al generar los JAR se incluirá esa carpeta con las Shared Libraries (.so). Pero para hacerlas funcionar, se deben extraer durante el runtime y cargarlas mediante System.load(). Para ello, primero se crea un string con las librerías a cargar. El órden debe ser el especificado, caso contrario, no funcionará:
private final static String[] libs = {
"libopencv_core.so.2.4.1","libopencv_imgproc.so.2.4.1",
"libopencv_flann.so.2.4.1","libopencv_features2d.so.2.4.1",
"libopencv_calib3d.so.2.4.1","libopencv_highgui.so.2.4.1",
"libopencv_ml.so.2.4.1","libopencv_video.so.2.4.1",
"libopencv_objdetect.so.2.4.1","libopencv_contrib.so.2.4.1",
"libopencv_gpu.so.2.4.1","libopencv_legacy.so.2.4.1",
"libopencv_nonfree.so.2.4.1","libopencv_photo.so.2.4.1",
"libopencv_stitching.so.2.4.1","libopencv_ts.so.2.4.1",
"libopencv_videostab.so.2.4.1"};
3) Luego, se crea un constructor de clase (static initialisation block), donde se cargan por única vez las librerías nativas necesarias en un directorio temporal:
static {
String path = "OCV_" + new Date().getTime();
for (int i = 0; i < libs.length; i++) {
loadLibFromJar(libs[i],path);
}
}
4) Por último, la función:
private static void loadLibFromJar(
String libreriaEspecifica, String path) {
try {
InputStream in = frmEditor.class.getResourceAsStream(
LIB_BIN + libreriaEspecifica);
File fileOut = new File(System.getProperty("java.io.tmpdir") +
"/" + path + LIB_BIN + libreriaEspecifica);
OutputStream out = FileUtils.openOutputStream(fileOut);
IOUtils.copy(in, out);
in.close();
out.close();
System.load(fileOut.toString());
} catch (Exception e) {
System.out.println("Error al cargar librería nativa: " + libreriaEspecifica +" " + e);
}
}
6) Abrimos una terminal y escribimos:
- cd /UbicacionElegida
- java -jar ./TuProyecto.jar