lunes, 30 de mayo de 2022

MS SQL Server Express 2019. Instalación

Procedimiento

1. Descargar el programa  MS SQL Server Express 2019 desde la web de Microsoft

2. Instalar la opción básica.

3. Descargar el MS QL management console (MSMC)

4. Ejecutar MSMC

5. Desativar en primera instancia el perfil de dominio y el prefil privado



6. entrar en MS

miércoles, 25 de mayo de 2022

Gradle-7 (10) Repasando conceptos de Gradle. Git

 1. El fichero .gitignore

Este fichero se encuentra en el directorio princial del proyecto. Veamos un ejemplo que a mi me vale

# Ignore Gradle project-specific cache directory
.gradle

# Ignore Gradle build output directory
build

# Ignore build directory
**/build
**/bin

# Ignore other libraries
**/webapp/libraries

Recordar que:

* representa cualquier palabra

** representa cualquier directorio

2.  Comandos básicos del git

git init   Crea un git en el directorio .git de nuestro proyecto

git add .   Guarda en un buffer los ficheros antes de guardarlos en el git

git status | more   Para ver los fichero guardados en el buffer

git rm --cached * -r  Para eliminar todos los fichero de la cache (recursivamente)

git commit -m "initialise project" Gurda definitivament el buffer anterior. Pero a veces pide que se haya indicado usuario y mail

git config --global user.emai="myemail@ximo.org" Damos el mail

git config --global user.name="ximo" Damos el nombre

Gradle-7 (9) Gradle Multiproyecto (3). Creando wars. Shadow plugin. Reflexiones

1. Creando wars en multiproject

NOTA: Hay un conflicto entre el plugin war (cuando usamos la opcion api(project(":A000-Basic")) para cada uno de los proyectos de los que depende y la ejecución/depuración de la aplicación web en eclipse, ya que eclipse no copia los jars de los proyectos que depende a la carpeta de despliegue local de tomcat en eclipse:

WORKSPACES/WS_JSP01/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/Mywebapp/WEB-INF/lib

Pero cuando genera el war desde la ventanda de "Gradle-tasks", si que lo genera bien.

Hay 2 opciones "sucias" para arreglarlo:

1. Copiar a mano los jars de los proyectos-dependencia a en dicha carpeta o
2. Indicar en el build.gradle 

implementation files(
      'path_to_firstjar/firstjar.jar',
        'path_to_secondjar/secondjar.jar',
        ........
)

Después de reflexionar, me parece que lo más lógico es crear 2 ficheros build.gradle (build.gradle.eclipse y build.gradle.gradle

Cada vez que queramos ejecutar el proyecto en eclipse o generar el war se copiará  build.gradle.eclipse a build.gradle. Esto equivale a como casi si sacáramos nuestro proyecto del multiproyecto

Solamente, para tener todo actualizado y sincronizado se copiará build.gradle.gradle a build.gradle por tanto esta última opción hay que utilizarla poco. Además esta última opción pierde mas dependencias que la otra por lo que los build.gradle pueden cambiar significativamente.

Veamos para un proyecto complejo primeramente el build.gradle que se ejecuta bien desde eclipse y también su jar es menos problemático (build.gradle.eclipse) y la parte de amarillo es donde se indican las dependencias, y varía significativamente con respecto a la otra versión.

plugins {
    // Apply the java-library plugin for API and implementation separation.
    id 'java-library'
    id 'war'
    id "org.gretty" version "4.0.1"
}

repositories {
    jcenter()
    mavenCentral()
}


//Configuration
project.war.destinationDirectory = file("$rootDir/../mynewtargets")  
project.archivesBaseName = 'CSV01' 
project.version = '3.0'


dependencies {
       
    //=============LOMBOK BEGIN ============================
    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'
    //=============LOMBOK END ==============================
    
    // JSP & SERVLETS
    compileOnly 'jakarta.servlet:jakarta.servlet-api:5.0.0'
    implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl:2.0.0'
    
    compileOnly 'jakarta.platform:jakarta.jakartaee-api:9.1.0' 
    compileOnly 'jakarta.el:jakarta.el-api:4.0.0'
        
    compileOnly 'jakarta.platform:jakarta.jakartaee-web-api:9.1.0' //Multipart
    implementation 'jakarta.activation:jakarta.activation-api:2.1.0'
    
    
    //Apache
    implementation 'commons-io:commons-io:2.11.0' 
    implementation 'org.apache.commons:commons-lang3:3.12.0' 
    implementation 'commons-codec:commons-codec:1.15'
    implementation "org.apache.commons:commons-vfs2:2.9.0"
    
    /* SELENIUM */
    api "org.seleniumhq.selenium:selenium-server:3.141.59"
    implementation 'org.seleniumhq.selenium:selenium-java:4.1.2'
    implementation "org.seleniumhq.selenium:selenium-firefox-driver:4.1.2"
    implementation "org.seleniumhq.selenium:selenium-chrome-driver:4.1.2"
    
    /* PDFBox */
    implementation 'org.apache.pdfbox:pdfbox:2.0.24'
    
    /* Samba */
    implementation "com.hierynomus:smbj:0.11.3"
    
    /* sftp */
    implementation 'com.jcraft:jsch:0.1.55'
    
    /* HIbernate */    
    implementation "org.hibernate:hibernate-core-jakarta:5.6.9.Final"
    implementation "org.hibernate:hibernate-envers-jakarta:5.6.9.Final"
    implementation "org.hibernate:hibernate-validator:7.0.4.Final" 
        
    
    /*DB Drivers */
    //runtimeOnly "com.h2database:h2:1.4.200"
    implementation "org.postgresql:postgresql:42.2.20"
    implementation "net.sourceforge.jtds:jtds:1.3.1"      
    
     /*CMIS*/    
    implementation "org.apache.chemistry.opencmis:chemistry-opencmis-client-impl:1.1.0"
    
     /* Jackson */
    implementation "com.fasterxml.jackson.core:jackson-core:2.13.2"
    implementation "com.fasterxml.jackson.core:jackson-annotations:2.13.2"
    implementation "com.fasterxml.jackson.core:jackson-databind:2.13.2.2"
    implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.2"
    implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.2"
    implementation "com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:2.13.2"
    implementation "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.2"
    implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2"   
    
    /* BAR CODES */
    implementation 'com.google.zxing:core:3.4.1'
    implementation 'com.google.zxing:javase:3.4.1'
    
    //Own libraries
    
    implementation files(
     	"$rootDir/../mynewtargets/a000-basic-3.0.jar",
     	"$rootDir/../mynewtargets/a002-jackson-3.0.jar",
     	"$rootDir/../mynewtargets/a004-pdf-3.0.jar",
     	"$rootDir/../mynewtargets/a006-cmis-3.0.jar",
        "$rootDir/../mynewtargets/a009-samba-3.0.jar",
        "$rootDir/../mynewtargets/a010-sftp-3.0.jar",
        "$rootDir/../mynewtargets/a011-barcode-3.0.jar",
        "$rootDir/../mynewtargets/a012-selenium-3.0.jar",
        "$rootDir/../mynewtargets/b001-model-base-3.0.jar",
        "$rootDir/../mynewtargets/b003-dao-3.0.jar",
        "$rootDir/../mynewtargets/c002-model-control-3.0.jar",
        "$rootDir/../mynewtargets/c005-model-csv-3.0.jar",
        "$rootDir/../mynewtargets/c007-model-gexflow-3.0.jar",
        "$rootDir/../mynewtargets/d001-dao-imp-3.0.jar",
      )
}


Para la versión que sirve únicamente para tener el proyecto actualizado (build.gradle.gradle), en amarillo se ven los cambios respecto a la anterior versión.

plugins {
    // Apply the java-library plugin for API and implementation separation.
    id 'java-library'
    id 'war'
    id "org.gretty" version "4.0.1"
}

repositories {
    jcenter()
    mavenCentral()
    maven { url "https://jitpack.io" } //@see: https://stackoverflow.com/questions/38905939/how-to-import-library-from-jitpack-io-using-gradle
    maven { url "https://repository.mulesoft.org/nexus/content/repositories/public/"}
}


//Configuration
project.war.destinationDirectory = file("$rootDir/../mynewtargets")  
project.archivesBaseName = 'CSV01' 
project.version = '3.0'


dependencies {
       
    //=============LOMBOK BEGIN ============================
    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'
    //=============LOMBOK END ==============================
    
    // JSP & SERVLETS
    compileOnly 'jakarta.servlet:jakarta.servlet-api:5.0.0'
    implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl:2.0.0'
    
    compileOnly 'jakarta.platform:jakarta.jakartaee-api:9.1.0' 
    compileOnly 'jakarta.el:jakarta.el-api:4.0.0'
        
    compileOnly 'jakarta.platform:jakarta.jakartaee-web-api:9.1.0' //Multipart
    implementation 'jakarta.activation:jakarta.activation-api:2.1.0'
    
    
    //Apache
    implementation 'commons-io:commons-io:2.11.0' 
    implementation 'org.apache.commons:commons-lang3:3.12.0' 
    implementation 'commons-codec:commons-codec:1.15'
    implementation "org.apache.commons:commons-vfs2:2.9.0"
    
    /* SELENIUM */
    api "org.seleniumhq.selenium:selenium-server:3.141.59"
    implementation 'org.seleniumhq.selenium:selenium-java:4.1.2'
    implementation "org.seleniumhq.selenium:selenium-firefox-driver:4.1.2"
    implementation "org.seleniumhq.selenium:selenium-chrome-driver:4.1.2"
    
    /* PDFBox */
    implementation 'org.apache.pdfbox:pdfbox:2.0.24'
    
    /* Samba */
    implementation "com.hierynomus:smbj:0.11.3"
    
    /* sftp */
    implementation 'com.jcraft:jsch:0.1.55'
    
    /* HIbernate */    
    implementation "org.hibernate:hibernate-core-jakarta:5.6.9.Final"
    implementation "org.hibernate:hibernate-envers-jakarta:5.6.9.Final"
    implementation "org.hibernate:hibernate-validator:7.0.4.Final" 
        
    
    /*DB Drivers */
    //runtimeOnly "com.h2database:h2:1.4.200"
    implementation "org.postgresql:postgresql:42.2.20"
    implementation "net.sourceforge.jtds:jtds:1.3.1"      
    
     /*CMIS*/    
    implementation "org.apache.chemistry.opencmis:chemistry-opencmis-client-impl:1.1.0"
    
     /* Jackson */
    implementation "com.fasterxml.jackson.core:jackson-core:2.13.2"
    implementation "com.fasterxml.jackson.core:jackson-annotations:2.13.2"
    implementation "com.fasterxml.jackson.core:jackson-databind:2.13.2.2"
    implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.2"
    implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.2"
    implementation "com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations:2.13.2"
    implementation "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.2"
    implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2"   
    
    /* BAR CODES */
    implementation 'net.sourceforge.barbecue:barbecue:1.5-beta1'
    implementation 'net.sf.barcode4j:barcode4j:2.1'  
    implementation 'com.github.kenglxn.qrgen:core:v2.2.0'
        
    implementation 'com.google.zxing:core:3.4.1'
    implementation 'com.google.zxing:javase:3.4.1'
        
    //1. Reference to other maven project in muiltiproject scenario
    api(project(":A000-Basic"))
    api(project(":A002-Jackson"))
    api(project(":A004-PDF"))
    api(project(":A006-CMIS"))
    api(project(":A009-Samba"))
    api(project(":A010-SFTP"))
    api(project(":A011-BarCode"))
    api(project(":A012-Selenium"))
    api(project(":B001-Model-Base"))
    api(project(":B003-DAO"))
    api(project(":C002-Model-Control"))
    api(project(":C005-Model-CSV"))
    api(project(":C007-Model-Gexflow"))
    api(project(":D001-DAO-Imp"))
}

Como se puede ver, se pierden referencias a algunos repositorios y a también a ciertos "jars", y además en este caso concreto, da errores de dependencias transitivas con las versiones de org.codehaus.woodstox:stax2-api

Esto en cambio no ha pasado en el build.gradle anterior

2. Gradle build-build vs shadow-shadowJar

En el proyecto principal (en este caso Multiproject), hay 2 operaciones importantes que no hay que confundir:

1. build-build: Genera todos los jars y wars del proyecto

2. shadow-shadowJar: Genera todos los jars o wars pero solo de aquellos proyectos que han utilizado el shadow plugin, junto con los proyectos que son necesitados(dependencias) por los proyectos con shadow.


Por tanto para construir todos los jars y wars convierne utilizar la primera opción


3. Errores y resultados inesperados en la ejecución

Cuando incluimos un subproyecto con shadow jar, Eclipse tarda muchísimo en actualizar las referencias, de manera que si ejecutamos el projecto que hace referencia a otro con shadow plugin aparecen resultados incoherentes.

Esto es debido a que Eclipse utiliza "caches" para que la cosa vaya más rápida, pero lo que está haciendo es provocar resultados extraños pues no tarda mucho en actualizarse los caches. Mucho cuidado y paciencia.

Para evitar estos problemas, es conveniente sacar los proyectos que dependan de aquellos que se utiliza el shadow jar, fuera de este gradle multiproyecto

martes, 24 de mayo de 2022

Gradle-7 (8) Gradle Multiproyecto (2) Shadow plugin con Apache CXF . Soluciónes al problema de ejecución- Manda Güevos!

0. Introducción

El famoso "jar hell" o infierno de los jars, se manifiesta aquí en todo su esplendor. En concreto la integración de Apache CXF ha corrido mas ríos de sangre y frustación que de tinta.

1. Shadow plugin con Apache CXF

Recordar crear el subproyecto dentro del módulo principal y añadirle la referencia al subproyecto en "settings.properties" del proyecto principal 


El settings.gradle seria:


rootProject.name = 'Multiproject'

include('lib', 

        'A000-Basic', 'A003-Excel', 'A004-PDF', 

        'B001-Model-Base', 'B003-DAO', 

        'C002-Model-Control', 'C005-Model-CSV', 

        'D001-DAO-Imp', 'D002-Sedipualba-WS-Shdw',   

        'PH01', 'PH01-Simple')


Veamos el fichero build.gradle

Hay que prestar especial atención a las líneas que hacen referencia al transformer y a las reubicaciones que son muy truculentas ("tricky")

 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
plugins {
    // Apply the java-library plugin for API and implementation separation.
    id 'java-library'
    //id 'application'
    id 'com.github.johnrengelman.shadow' version '7.1.2'
}

import com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer


repositories {
    jcenter()
    mavenCentral()
    maven { url "https://jitpack.io" } //@see: https://stackoverflow.com/questions/38905939/how-to-import-library-from-jitpack-io-using-gradle
}


dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'

    /***********************************************************************
    *********************** 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'
    /************************************************************************
    *********************** END LOMBOK DEFINITION ***************************/
    
    api(project(":A000-Basic"))
        
    // Apache general //
    implementation "commons-beanutils:commons-beanutils:1.9.4"
    implementation "commons-io:commons-io:2.11.0"
    implementation "org.apache.commons:commons-lang3:3.12.0"
        
    
    /*Apache CXF*/
    implementation 'org.apache.cxf:cxf-core:3.5.2'
    implementation 'org.apache.cxf:cxf-rt-features-logging:3.5.2'
    implementation 'org.apache.cxf:cxf-rt-ws-security:3.5.2' // WSS4JInterceptors, WSPasswordCallback
    implementation 'org.apache.cxf:cxf-rt-frontend-jaxws:3.5.2' //Dynamic client
    implementation 'org.apache.cxf:cxf-rt-transports-http:3.5.2'//Si no es fica,  es queda penjat !!!
    
    implementation 'com.sun.xml.ws:jaxws-ri:2.3.5' //FUNCIONA!  Quita:com.sun.tools.internal.xjc.api.XJC   
    
    /* Jackson */
    implementation "com.fasterxml.jackson.core:jackson-databind:2.13.3"
    
 } //dependencies

shadowJar {
    transform(AppendingTransformer) {
    	resource = 'META-INF/cxf/bus-extensions.txt'
    }	
    //1. Name and location of jars
    destinationDirectory = file("$rootDir/../mynewtargets") 
    archiveBaseName.set('d002-sedipualba-ws-shdw')
    archiveClassifier.set('')
    archiveVersion.set('2.1')
	//mainClassName = 'openadmin.utils.sedipualba.SedipuAlbaUtilsWSSeres'
	
    //2. Relocate (shadow) old problematic transitive dependency
    relocate 'com.sun.xml.bind.v2', 'com.sun.xmlv2.internal.bind.v2'
    relocate 'com.sun.xml'        , 'com.sun.xmlv2'    
    relocate 'javax.xml.bind'     , 'javax.xml.bindv2' 
	
	
    //4. Include sources
    from sourceSets.main.allSource
	
}//shadowJar


tasks.named('test') {
    // Use JUnit Platform for unit tests.
    useJUnitPlatform()
}//tasks

Veamos las líneas importantes:

5: Se importa el gradle shadow plugin.

8: Se importa el transformer, pieza clave para que se pueda empaquetar apache cxf. Ver la contestación de petternordholm 

40-44: Dependencias de Apache CXF

46-49: Dependencias que se requieren en apache CXF

54-56: Aplicación del transformer. Sin esto, da un montón de referencias nulas (Bindings...)

58-61: Se define nombre y ubicación del jar generado

66: Reubicación importante: Hay conflictos a partir de la versión 3, pues se cambia la referencia desde javax a jakarta. Por tanto hay que utilizar el shadow para que reubique estas dependencias antiguas que las llama apache cxf. (que internamente llaman a javax)

65: Volvemos atras una línea, para indicar que si se reubiva la línea 65, entonces el sistema se "inventa" una reubicación intermedia llamada "internal". Por tanto hay que tener cuidado

67: Reubicación del javax para que nlo lo machaque el jakarta

71. Incluimos las fuentes ".java" para que la depuración sea más fácil

2. Subproyecto que usa este como referencia.

Aquí la cosa tiene truco.

Para ello seguimos la entrada anterior del blog y creamos un subproyecto "PH01-Simple" que solo va a tener de dependencia al subproyecto anterior, y otro. Recordar de crear la referencia a settings.gradle del proyecto padre.


Veamos el build.gradle

 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
plugins {
    // Apply the java-library plugin for API and implementation separation.
    id 'java-library'
    id 'application'
}

repositories {
    jcenter()
    mavenCentral()
}

gradle.startParameter.showStacktrace = org.gradle.api.logging.configuration.ShowStacktrace.ALWAYS

project.jar.destinationDirectory = file("$rootDir/../mynewtargets")
project.archivesBaseName = 'PH01-Simple' 
project.version = '2.0'


dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
        
    //=============LOMBOK BEGIN ============================
    // Not generated by the Vaadin starting-project
    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'
    //=============LOMBOK END ==============================
    api(project(":A000-Basic"))
implementation project(path: ':D002-Sedipualba-WS-Shdw', configuration: 'shadow') } application { mainClass = 'alba.utils.AlbaEdu' } jar { duplicatesStrategy = 'exclude' from sourceSets.main.allSource //Include java sources }

Observar que:

  • No utilizamos el shadow plugin
  • Para referenciar a un proyecto hecho shadow plugin, ver la línea 32. En cambio un proyecto normal se referencia con la línea 31

Si le damos a la task de gradle application -run, parece ser que funciona 


Pero si le damos a ejecutar una clase que hace referencia al proyecto anterior (AlbaEdu) que usamos el shadow plugin. da error de ejecución y no encuentra la referencia a apache cxf.


Exception in thread "main" java.lang.NoClassDefFoundError: org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory

at openadmin.utils.sedipualba.SedipualbaUtilsOther.getClientsAndClassLoadersIRunBO(SedipualbaUtilsOther.java:270)

at alba.utils.AlbaEdu.<init>(AlbaEdu.java:32)

at alba.utils.AlbaEdu.main(AlbaEdu.java:106)

Caused by: java.lang.ClassNotFoundException: org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory

at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:827)

at java.base/jdk.internal.loader.ClassLoaders$Aimplementation project(path: ':D002-Sedipualba-WS-Shdw', configuration: 'shadow')implementation project(path: ':D002-Sedipualba-WS-Shdw', configuration: 'shadow')ppClassLoader.loadClass(ClassLoaders.java:188)

at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:1112)

... 3 more

3. 1ª Solución al problema

Para poder depurar esta clase en Eclipse, es importante que se pueda ejecutar. Para ello, como Eclipse no  puede encontrar las referencias al proyecto anterior (del shadow plugin), hay que indicárselo en la configuración de ejecución.

Apretar el botón derecho del ratón sobre la clase en cuestión (en mi caso AlbaEdu) y Run As ->Run Configurations o también Debug As > Debug Configurations

Le indicamos Add External Jars, y buscamos donde está el jar generado en el subproyecto anterior y lo añadimos. Y a funcionar!!!



4. 2ª Solución al problema

Es evidente que la solución anterior no es precisamente muy elegante. Parece ser que el shadow plugin y la implementación multiproyecto de eclipse no se comunican muy bien.

Otra solución poco elegante pero no tanto consiste en realizar estos pasos:

1. Generar el jar del proyecto que contiene el shadow plugin (maven lo contempla)

2. En vez de hacer referencia a este proyecto, se haría referencia al jar generado. En concreto bastaría con cambiar esta línea en el build-gradle:

implementation project(path: ':D002-Sedipualba-WS-Shdw', configuration: 'shadow')

por esta otra

implementation files(

        '../mynewtargets/d002-sedipualba-ws-shdw-2.1.jar',

)




Ahora me toca probar con un war!



lunes, 23 de mayo de 2022

Gradle-7 (7) Gradle Multiproyecto (1) Introduccion

 0. Introducción

Se agradece a tomgregory sus claras explicaciones

1. Crear un proyecto gradle en Eclipse

Como es habitual utilizamos el menú: File -> New -> Gradle -> Gradle Project

Le damos un nombre del projecto por ejemplo "Multiproject"

Es importante configurar el workspace


y asegurarnos que tengamos Gradle 7.4.2 y java igual o superior a 16



Y observamos que nos ha preparado el entorno para tener un Multiproyecto, pues nos ha creado un subproyecto llamado lib.


Analicemos lo que tenemos:

En el diectorio principal (Multiproject) tenemos:

  1. La carpeta del subproyecto hijo (lib)
  2. La carpeta gradle
  3. 3 ficheros: gradlew, gradle.bat y settings.gradle
En el proyecto hio (lib) tenemos una estructura de proyecto java normal, y el fichero "build.gradle"

Para que gradle sepa cuales son sus subproyectos, tenemos que indicarle en "settings.gradle" los subproyectos:

rootProject.name = 'Multiproject'
include('lib')


2. Crear un subproyecto 

Vamos a guradarnos el subproyecto "lib" como modelo para generar otros subproyectos.

Desde eclipse creamos una nueva carpeta llamada por ejemplo "WS", justo debajo de "Multiproject" (por tanto al mismo nivel que "lib"), y copiamos desde la carpeta "lib" estos ficheros:

  • carpeta src
  • fichero build.gradle

Editamos el "settings.gradle" y le añadimos 'WS' al include

include('lib', 'WS')

Y nos situamos sobre el proyecto "Multiproject" y con el boton derecho "Gradle"->"Refresh gradle project", y a veces desaparece, pero si le damos a F5 ya nos aparece "WS" como subproyecto

Si no apareciera, se podría abrir una 

Para ello abrimos una ventana de terminal, nos situamos en la carpeta "Multiproject" y ejecutamos 

./gradlew projects

y después 

./gradlew build

3. Dependencias entre proyectos.

Supongamos que hemos creados 2 subproyectos

  • A000-Basic
  • D002-Sedipualba-WS-Shdw
Y el primero es una dependencia del segundo
entonces en el "build.gradle" del segundo proyecto le indicamos.

api(project(":A000-Basic"))




miércoles, 18 de mayo de 2022

POSTGRES (I) Buscar que tabla y campo contiene un valor

 En stackoverflow aparece esta cosulta que a mi me ha valido


CREATE OR REPLACE FUNCTION search_whole_db(_like_pattern text)
  RETURNS TABLE(_tbl regclass, _ctid tid) AS
$func$
BEGIN
   FOR _tbl IN
      SELECT c.oid::regclass
      FROM   pg_class c
      JOIN   pg_namespace n ON n.oid = relnamespace
      WHERE  c.relkind = 'r'                           -- only tables
      AND    n.nspname !~ '^(pg_|information_schema)'  -- exclude system schemas
      ORDER BY n.nspname, c.relname
   LOOP
      RETURN QUERY EXECUTE format(
         'SELECT $1, ctid FROM %s t WHERE t::text ~~ %L'
       , _tbl, '%' || _like_pattern || '%')
      USING _tbl;
   END LOOP;
END
$func$  LANGUAGE plpgsql;

y luego se llama así

SELECT * FROM search_whole_db('mypattern');






viernes, 13 de mayo de 2022

Java REST client (2) :GET con autorización de "token"

 Ahora toca crar una petición con GET insertando el token en la cabecera (de tipo Authorisation), y atacando a una url diferente con distintos nombres de operacion.

Para simplficar suponemos que el token es "mitoken" y la url de servicio es:

https://urlserviciodeprueba/api/padron/motivospeticion 

sindo "motivosoperacion" el nombre de la operacion

Con  "curl" sería para una operación sin parámetros:


curl https://urlserviciodeprueba/api/padron/motivospeticion  -H "Authorization: Bearer mitoken"

y para una operacion con  parámetros

curl "https://urlserviciodeprueba/api/padron/volantefirmado?filtros[0].Nombre=CodigoProvincia&filtros[0].Valor=99&filtros[1].Nombre=CodigoMunicipio&filtros[1].Valor=999&filtros[2].Nombre=TipoDocumentoINE&filtros[2].Valor=1&filtros[3].Nombre=Documentacion&filtros[3].Valor=11111111H" -H "Authorization: Bearer mitoken"


Veamos todo el código en java tanto para el post anterior como este de forma unificada

hay que tener en cuenta de meter en gradle las dependencias de apache http client y Jackson (tambien puede falta algunas como lombok..)

//Apache
implementation 'org.apache.httpcomponents:httpclient:4.5.13'
    
/* Jackson */
implementation "com.fasterxml.jackson.core:jackson-core:2.13.2"
implementation "com.fasterxml.jackson.core:jackson-annotations:2.13.2"
implementation "com.fasterxml.jackson.core:jackson-databind:2.13.2.2"

Y el codigo java

package ph.utils;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.Getter;

public class HttpXimo {
	private CloseableHttpClient httpclient = null;
	@Getter private String urlAuth = null;
	@Getter private String urlService = null;

	public HttpEdu(String urlAuth, String urlService) {
		this.urlAuth = urlAuth;
		this.urlService = urlService;
		try {
			httpclient = HttpClients.createDefault();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String get(String url, String operation, String[] paramNames, String[] paramValues, String token) throws Exception {
		String urlWithParams=url+operation;
		for (int i=0; i<paramNames.length; i++) {
			String myUnionChar = "&";
			if (i==0) myUnionChar="?";
			urlWithParams+= myUnionChar + paramNames[i] + "=" + paramValues[i];
		}	
		System.out.println(urlWithParams);
		HttpGet request = new HttpGet(urlWithParams);
		//String auth = "Authorization: Bearer " + token;
		//byte[] encodedAuth = Base64.encodeBase64(
		//  auth.getBytes(StandardCharsets.ISO_8859_1));
		//String authHeader = "Basic " + new String(encodedAuth);
		String authHeader = "Bearer " + token;
		request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
		
		System.out.println("request.uri=" + request.getURI());
		for (Header header : request.getAllHeaders()) System.out.println("HEADER=" + header.getName() + "====" + header.getValue());

		//HttpClient client = HttpClientBuilder.create().build();
		HttpResponse response = httpclient.execute(request);
		HttpEntity entity = response.getEntity();
		InputStream in = entity.getContent();
		String s = new String(in.readAllBytes());
		System.out.println("ENTITY=" + s);
		// do something useful with the response body
		// and ensure it is fully consumed
		EntityUtils.consume(entity);
		return s;

	}
	
	public String post(String url, String[] paramNames, String[] paramValues) throws Exception {
		
		HttpPost httpPost = new HttpPost(this.urlAuth);
		List<NameValuePair> nvps = new ArrayList<>();

		//Add form parameters
		for (int i = 0; i < paramNames.length; i++)
			nvps.add(new BasicNameValuePair(paramNames[i], paramValues[i]));
		
		//Encode url
		httpPost.setEntity(new UrlEncodedFormEntity(nvps));
		
		//Get response
		CloseableHttpResponse response2 = httpclient.execute(httpPost);
		HttpEntity entity2 = response2.getEntity();
		
		//Read the response from input stream
		InputStream in = entity2.getContent();
		String s = new String(in.readAllBytes());
		
		//Close input stream
		EntityUtils.consume(entity2);
		return s;

	}
	
	public String getKeyValue(String jsonString, String key) throws JsonMappingException, JsonProcessingException {
		ObjectMapper  objMapper= new ObjectMapper();
		Map<String,String>mp=new HashMap<>();
		mp=objMapper.readValue(jsonString, mp.getClass());
		return mp.get(key);
	}	
	
	
	public static void main(String[] args) throws Exception {
		HttpEdu myHttp = new HttpXimo(
				"https://urlautorizaciondeprueba/identity/connect/token",
				"https://urlserviciodeprueba/api/padron/");
		String[] names = { "username", "password", "grant_type", "scope", "client_id", "client_secret" };
		String[] values = { "miUsuario", "miClave", "password", "miEmpresa",
				"yoMismo", "1234567890" };

		String strResponse= myHttp.post(myHttp.getUrlAuth(), names, values);
		System.out.println(strResponse);
		String token =myHttp.getKeyValue(strResponse, "access_token");
		System.out.println("TOKEN="+token);
		
		//===================MOTIVOS PETICION==============================
		String[] names1 = {};
		String[] values1 = {};
		
		strResponse= myHttp.get(myHttp.getUrlService(), "motivospeticion", names1, values1, token);
		System.out.println(strResponse);
		
		//===================VOLANTE FIRMNADO==============================
		String[] names2 = { "filtros[0].Nombre", "filtros[0].Valor", "filtros[1].Nombre", "filtros[1].Valor", 
				"filtros[2].Nombre", "filtros[2].Valor","filtros[3].Nombre", "filtros[3].Valor" };
		String[] values2 = { "CodigoProvincia", "99", "CodigoMunicipio", "999",
				"TipoDocumentoINE", "1", "Documentacion", "11111111H"  };
				
		strResponse= myHttp.get(myHttp.getUrlService(), "volantefirmado", names2, values2, token);
		System.out.println(strResponse);
		
		
	}

}