jueves, 27 de enero de 2022

Gradle-7 (7) BUENA: Recapitulación, Dependencias transitivas incompatibles, Shadow Plugin, Strictly, Incluir Sources fuentes

 0. Introducción

1. Quitar la carpeta lib (como antes en Gradle <6.7)

2. El maravilloso Shodow plugin de John Engelman

3. Versionado "sctrictly", para fijar la veersión de la dependencia que funcione bien (FALLA)


 

1. Quitar la carpeta lib (como antes en Gradle <6.7)

Para ello, seguir estos pasos:

1. Crear el propyecto gradle en Eclipse

2. Una vez creado, se aprieta el boton derecho del ratón sobre el proyecto y indicamos "Delete", pero sin borrar el contenido.

3. Borramos todos los ficheros del proyecto creado, excepto la carpeta "lib",

4. Trasladamos el fichero build.gradle y la carpeta src a la carpeta del proyecto.

5. Borramos la carpeta lib, con lo que nos queda: la carpeta del proyecto, y dentro de ella, la carpeta src y el build.gradle

6. Ahora importamos el proyecto gradle desde Eclipse y ya está.


2. El maravilloso Shadow plugin de John Engelman

Este plugin permite:

1.Usar el plugin (línea 4 -> id 'com.github.johnrengelman.shadow' version '7.1.2')

2. Muy importante la línea 12  para ver donde falla la compilación!

3 Crear un "uber jar" o jar total. Para ello se añade la tarea shadowJar (línea 29) 

NO! 4 Reducir el tamaño del "uber jar" (linea 40 -> minimize() ) eliminameos dependencias no usadas

5. Solucionar el problema de las depencias transitivas con diferentes versiones e incompatibles. Para ello utiliza internamente la libreria ASM para cambier el "bytecode" de las clases. (Pueden haver algunos problemillas si se hace referencia a

las clases por reflexión). (Línea   ->relocate 'com.sun.xml.ws', 'com.sun.xml.ws234') En este caso cambiamos la ubicación de la carpeta com.sun.xml.ws a com.sun.xml.ws234

Veamos como hacerlo, para muestra un fichero "build.gradle"

6. Lo mas importante, aparece en las tareas de gradle, una carpeta "shadow" con la tarea shadowJar, que es la que genera el jar.

7. Las líneas 33-34 indicamos el nombre del fichero jar, versión y la carpeta donde se genera (en este caso se crea una carpeta llamada "mytargets" dentro del Workspace (a la misma altura que la carpeta del proyeco, así guardamos todos los jars que hacemos en la misma carpeta.

7. Se puede incluir el código fuente para poder depurarlo en Eclipse (línea 43)


 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
plugins {
    // Apply the java-library plugin for API and implementation separation.
    id 'java-library'
    id 'com.github.johnrengelman.shadow' version '7.1.2'
}

repositories {
    jcenter()
    mavenCentral()
    maven { url "https://jitpack.io" } //@see: https://stackoverflow.com/questions/38905939/how-to-import-library-from-jitpack-io-using-gradle
}
gradle.startParameter.showStacktrace = org.gradle.api.logging.configuration.ShowStacktrace.ALWAYS
dependencies {
    // Use JUnit test framework.
    testImplementation 'junit:junit:4.13.1'
    
    /***********************************************************************
    *********************** LOMBOK DEFINITION ******************************/
    compileOnly             'org.projectlombok:lombok:1.18.20'
    annotationProcessor     'org.projectlombok:lombok:1.18.20'
    testCompileOnly         'org.projectlombok:lombok:1.18.20'
    testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
    /************************************************************************/
   
    /* Apache */
    implementation "commons-io:commons-io:2.11.0"
}    
// Output to build/libs/shadow.jar ?
shadowJar {
    //1. Name and location of jars
	archiveBaseName.set('a004-pdf')
	archiveClassifier.set('')
	archiveVersion.set('1.1')
	destinationDirectory = file("$rootDir/../mytargets") 
	
	//2. Relocate (shadow) old problematic transitive dependency com.sun.xml.ws:jaxws-rt:2.3.4
	relocate 'com.sun.xml.ws', 'com.sun.xml.ws234'
	
	//3. Discard not used libraries
	//minimize() //NO USAR

	//4. Include Sources
	from sourceSets.main.allSource
}
tasks.named('test') { // Use JUnit Platform for unit tests. useJUnitPlatform() }


3. Versionado "strictly" para fijar la version correcta (FALLA)

Con el tema de la migracion de javax a jakarta, hay liobrerias que tienen dependencias a versioes antiguas y otras a las nuevas.

En concreto tengo el error:

java.lang.ClassNotFoundException: javax.xml.bind.JAXBException

Y según se dice en stackoverflow las dependencias "org.glassfish.jaxb:jaxb-runtimealudidas" indirectamente són:

jakarta.xml.bind:jakarta.xml.bind-api
org.glassfish.jaxb:jaxb-runtime

Si intentamos ver las dependencias tal y como se indica en la imagen, cuando elprograma funciona bien para localizar las versiones correctas:



Cuando le añadimos la version de hibernate-core-jakarta, hace referencia a las versiones 3.x.x de ambas dependencias, con lo que deja de funcionar aquellas partes del programa que referencia a versiones 2.x.x.

Para ello le indicamos en la parte de depencencias del gradle, estas dependencias con la clausula "strictly"

 /**********************************************************************/
/* STRICTLY VERSIONS !!!!!!!!!*/
//Avoid version 4.0.0'
implementation ('jakarta.xml.bind:jakarta.xml.bind-api') { version { strictly '2.3.3'} }
    
//Avoid version 3.0.0
implementation ('org.glassfish.jaxb:jaxb-runtime') { version { strictly '2.3.6'} } 	
/**********************************************************************/