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

sábado, 19 de marzo de 2022

Java SE 10/11: Nuevas características para desarrolladores

Bueno ya hicimos en su día los post sobre las características de Java 8 y 9 y ahora vamos por la 10 y 11. La versión 10 fue la última lanzada por Oracle con caracter gratuito. Y la 11 fue la siguiente LTS después de Java 8 y la primera con el nuevo modelo de sistema de licenciamiento. Y de lanzamiento, sacando una nueva versión cada 6 meses. Debido a eso, la versión 10 fue lanzada en Marzo de 2018 y la 11 en Septiembre del mismo año. 

En este post haremos un listado centrado principalmente en las mejoras para desarrolladores. Con la idea de seguir poniéndonos un poco al día y al menos saber manejar las nuevas y más importantes características. Por lo que no entraremos al detalle de mejoras a nivel de rendimiento u otras características menos llamativas.

  • Java 10: Tipo variable local
Ya podemos inicializar una variable sin indicar específicamente de que tipo es. Como si se tratase de un lenguaje de programación no tipado. 

var s = "this is a String object";

Con algunas excepciones, cómo puede ser que solo se declare, que se utilice para almacenar una expresión lambda o para inicializar un array. 

//cannot infer type for local variable
var a;
var b = null;
var c = () -> { };
var d = { 1 , 2 };
  • Java 10: Métodos inmutables
Ahora las interfaces List, Map y Set cuentan con el nuevo método copyOf que permite la creación de copias de listas que a la vez son inmutables. Y el método toUnmodifiableList/Map/Set en la interfaz Collectors.

List<String> numbers = new ArrayList<>();
numbers.add("one");
List<String> copy = List.copyOf(numbers);
numbers.add("two");
//copy.add("three"); // throw java.lang.UnsupportedOperationException
copy.forEach(System.out::println); //only prints one
List<String> collect = numbers.stream().collect(Collectors.toUnmodifiableList());
collect.forEach(System.out::println); // prints one two
//collect.add("three");// throw java.lang.UnsupportedOperationException
  • Java 10: Nuevo método de Optional
Ahora existe el nuevo método orElseThrow() que es exactamente igual que get() pero con un nombre más aclarativo.

String str = "str";
Optional<String> opt = Optional.ofNullable(str);
System.out.println(opt.orElseThrow()); // same as opt.get()
  • Java 10: Certificados por defecto
Ahora las versiones de Oracle y Open JDK vendrán con un conjunto por defecto de certificados de entidades de confianza. Acabando de camino con los problemas de TLS al utilizar OpenJDK. 
  • Java 10: Nuevo versionado de los release en base al Tiempo 
$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)
    • Java 11: Nuevos métodos de String
    Se han incorporado nuevos métodos de utilidad en la propia clase String. strip() es una mejora de trim().

    System.out.println(" ".isBlank()); //true
    
    String lines = "one\nsecond\nthird";
    System.out.println(lines.lines().collect(Collectors.toList())); //[one, second, third]
    
    String str = "  str  ";
    System.out.println("-"+str.strip()+"-"); // print -str-
    System.out.println("-"+str.stripLeading()+"-"); // print -str  -
    System.out.println("-"+str.stripTrailing()+"-"); // print -  str-
    
    System.out.println("2".repeat(2)); //22
    • Java 11: Var en expresiones Lambdas
    Ya indicábamos arriba, que una de las grandes características de Java 10 como era la sintaxis de variable local. Ahora podremos utilizarlas en las lambdas. 

    Map<String, Integer> map = new HashMap<>();
    map.put("2", 2);
    map.forEach((final var x, final var y) -> System.out.println(x+y)); // prints 22
    
    • Java 11: Facilitar la lectura y escritura de String en ficheros
    Se han creado los métodos readString writeString que lo permiten

    Path filePath = Files.writeString(Paths.get("tmp.txt"), "Sample text");
    String fileContent = Files.readString(filePath);
    System.out.println(fileContent.equals("Sample text")); // prints true
    • Miembros anidados
    A partir de ahora se incorpora los conceptos de netmates y mejora el acceso entre estos.
    • Java 11: Estandarización de HTTPClient
    Introducido en Java SE 9 ahora se convierte en un standard.
    • Java 11: Compilar y ejecutar clases con un único comando
    java HelloWorld.java
    • Java 11: Eliminación de módulos de Java EE y CORBA 
    Ya fueron deprecados en Java SE 9 y ahora han sido eliminados: java.xml.ws, java.xml.bind, java.activation, java.xml.ws.annotation, java.corba, java.transaction, java.se.ee, jdk.xml.ws, jdk.xml.bind.


    Si quieres ver todas las especificaciones de Java 10 SE puedes verlas aquí y las de Java SE 11 aquí.

    lunes, 21 de junio de 2021

    Mockito: Como emular métodos estáticos o construcción de objetos

    Hace poco hicimos un post sobre como ejecutar Mockito junto a JUnit 5 en eclipse. Hoy veremos un poco más acerca del tema. 

    Más concretamente veremos un par de nuevas características: Como mockear un atributo estático y la creación de un objeto de forma interna. Ambas cosas ya se podían realizar con otra librería de testing como Powermock, como puedes ver aquí. Pero esta librería aún no es compatible con JUnit 5. 

    Para empezar con el desarrollo de las pruebas, vamos a utilizar la versión de mockito-inline en vez de directamente mockito-core. Esta versión de la librería nos permitirá dos cosas:

    • Ahorrarnos la anotación @ExtendWith(MockitoExtension.class)
    • Evitar errores con las nuevas funcionalidades. Del tipo: The used MockMaker SubclassByteBuddyMockMaker does not support the creation of static mocks.
    Ahora veremos como mockear un método estático. Dicha característica está disponible desde la versión 3.4.0. 

    En función de si el método admite parámetros o no, la forma de realizar la prueba será ligeramente diferente. Pero en ambos haremos uso de la clase MockedStatic que nos permitirá mockear el funcionamiento del método estático en el ámbito de un try/catch. La única diferencia es la posibilidad de usar el operador :: cuando no se usa parámetros y de esta forma tener un código más reducido y leíble. 
    • Sin parámetros:
        @Test
        public void info() {
    	assertThat("Calculator v 1.0", equalTo(Calculator.info()));
    	try (MockedStatic<Calculator> mocked = mockStatic(Calculator.class)) {
    	    mocked.when(Calculator::info).thenReturn("Calculator mocked");
    	    assertThat("Calculator mocked", equalTo(Calculator.info()));
    	    mocked.verify(Calculator::info);
    	}
    	assertThat("Calculator v 1.0", equalTo(Calculator.info()));
        }
    
    • Con parámetros:

        @Test
        public void sum() {
    	assertThat(5, equalTo(Calculator.sum(2, 3)));
    	try (MockedStatic<Calculator> mocked = mockStatic(Calculator.class)) {
    	    mocked.when(() -> Calculator.sum(2, 3)).thenReturn(6);
    	    assertThat(6, equalTo(Calculator.sum(2, 3)));
    	    mocked.verify(() -> Calculator.sum(2, 3));
    	}
    	assertThat(5, equalTo(Calculator.sum(2, 3)));
        }
    

    En ambos ejemplos se puede ver cual es el comportamiento del método estático antes y después de su simulación. Y como podemos mockearlo dentro del try/catch gracias a MockedStatic. 

    Recordar que para poder ejecutar estos test a través de Maven es necesario tener una versión superior del maven-surefire-plugin a 2.2.

    Ahora veremos como emular la creación de objetos dentro de métodos que queremos probar. Esta característica esta disponible desde la versión 3.5.0. 

    Tenemos una clase que dentro de un método crea un objeto que luego es usado. Como puede ser este ejemplo:

    public class BookService {
        private BookDao dao;
        public Book getById(final int i) {
    	dao = new BookDao();
    	return dao.getById(i);
        }
    }
    

    Es posible que no siempre tengamos el código o la configuración disponible para utilizar ese objeto que se construye dentro de nuestro método, y debido a ello debemos emularlo. A través de MockedConstruction podremos emular la creación de una clase concreta y además modificar su comportamiento. 

    En este caso tendremos que definir el funcionamiento de la clase que será instanciada en la misma invocación del método mockConstruction. Y realizar las pruebas pertinentes dentro del ámbito de ese try/catch. 

    @Test
    public void getById() {
        assertThat("Ender's Game", equalTo(new BookService().getById(1).getName()));
        try (MockedConstruction<BookDao> mdu = Mockito.mockConstruction(BookDao.class, (mockdao, context) -> {
            Book b = new Book(1, "The stars my destination", "Alfred Bester");
            when(mockdao.getById(1)).thenReturn(b);
        })) {
            BookService service = new BookService();
            assertThat("The stars my destination", equalTo(service.getById(1).getName()));
        }
        assertThat("Ender's Game", equalTo(new BookService().getById(1).getName()));
    }
    

    Si queremos emular más de una construcción deberemos duplicar y anidar la creación de esos constructores y sus ámbitos try/catch. 

    Con estas dos nuevas características de Mockito solventamos un par de las mayores dificultades a la hora de hacer pruebas de lógica compleja. Y sin necesidad de más frameworks de testing o lógica compleja. 

    martes, 23 de marzo de 2021

    Como ejecutar pruebas con JUnit5 y Mockito en Eclipse

    Hoy vamos a ver algo muy sencillo, y es simplemente como hacer funcionar JUnit y Mockito desde Eclipse. No es un gran post que nos aporte o clarifique el funcionamiento concreto de una tecnología. Pero si es un post de ayuda que puede sernos util tenerlo a mano para configurar rapidamente nuestro proyecto, sobre todo si no tenemos buena memoría. 

    Eclipse es uno de las herramientas de desarrollo más famosas y mi preferida, al menos cuando en cuanto a Java se refiere. Facilita mucho el trabajo y en el caso de las pruebas, te permite ejecutarlas facilmente a través del menú contextual. Pudiendo ejecutar un único tests o todos los tests de una determinada clase o proyecto. 

    El asunto, es que con JUnit 5, no es que sea dificl hacerlo funcionar pero si que requiere de un mínimo de configuración. 

    Antes de empezar vamos a ver como siempre un poco de teoría. JUnit 5 es la suma de tres proyectos diferentes:

    • JUnit Platform: Es la base del Framework de testing. Y contiene la API de testing que nos permite ejecutar lso tests. 
    • JUnit Jupiter: Es la librería que contiene el nuevo modelo de programación de JUnit 5 y su modelo de extensión. Incluye anotaciones como @Tests, imprecindibles. 
    • JUnit Vintage: Es el proyecto que nos permite ejecutar versiones antiguas de JUnit, concretamente las versiones 3 y 4. Por tanto, este proyecto no lo necesitaremos. 
    Lo primero que debemos configurar son las dependencias: 

    <!-- junit.jupiter.version = 5.7.1 -->
    <!-- junit.platform.version = 1.7.1 -->
    <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>${junit.jupiter.version}</version>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-runner</artifactId>
    <version>${junit.platform.version}</version>
    <scope>test</scope>
    </dependency>

    Ya solo nos queda preparar nuestro test para que podamos ejecutarlo. Las pruebas las podremos ejecutar desde Eclipse o con comandos Maven. Eso sí, para ejecutarlas desde eclipse es necesario utilizar el Eclipse Photon o alguno posterior. 

    Aparte del la anotación imprescindible de @Test sobre cada uno de los tests que desarrollemos. Esta última anotación es la que permitirá que los métodos de la clase sean tenidos en cuenta como tests por Eclipse.

    public class BookDaoTest {
    @Test
    void getBook(final TestInfo testInfo) {
    BookDao dao = new BookDao();
    Book book = dao.getById(0L);
    assertThat(book.getId(), equalTo(0L));
    }
    }

    Pero necesitaremos una actualización más de nuestro proyecto si queremos que dichas pruebas sean tenidas en cuenta por Maven. Y es usar una versión del plugin maven-surefire-plugin superior a 2.22.0

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.22.2</version>
    </plugin>
    

    Como hemos dicho podemos ejecutar el código con el típico comando de maven:

    mvn clean test
    

    O directamente sobre eclipse a través del menú contextual, si queremos ejecutar únicamente una clase o método concreto:


    Ahora llega el turno de Mockito, algo que tampoco es complicado. Mockito es una librería genial que nos ayuda a 'mockear' objetos concretos para por ejemplo, poder devolver una respuesta concreta por nuestro objeto o simular respuesta de objetos que no conseguirias de otra forma. Podemos decir que también es una librería fundamental si queremos una gran cobertura de nuestras pruebas. 

    Lo primero que tendremos que hacer será incluir la dependencia de Mockito. Este framework tiene una dependencia específica para la ejecución de pruebas de JUnit 5. 

    <!-- mockito.version = 3.8.0 -->
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-junit-jupiter</artifactId>
        <version>${mockito.version}</version>
        <scope>test</scope>
    </dependency>
    

    El siguiente paso será añadir la extensión @ExtendWith a nuestra clase de Test, indicando que vamos a usar la extensión MockitoExtension que hace uso del modelo de extensión de JUnit 5. 

    @ExtendWith(MockitoExtension.class)
    public class BookDaoTest {
    	@Mock
    	BookDao dao;
    	@Test
    	void getBook(final TestInfo testInfo) {
    		Book bookMocked = new Book(0L, "Orson S. Card", "Ender's Game");
    		when(dao.getById(0L)).thenReturn(bookMocked);
    		Book book = dao.getById(0L);
    		assertThat(book.getName(), equalTo("Ender's Game"));
    	}
    }
    

    Como veis con 3 dependencias y 1 anotación ya podemos ejecutar sin problemas dos de los frameworks de testing más importantes en nuestro IDE preferido. 

    viernes, 19 de febrero de 2021

    Docker tips: Como gestionar los logs

    Hoy vamos a ver un truco sencillo sobre Docker y sus logs. Pero puede ocasionarnos más de un dolor de cabeza, y esto es el tratamiento de los logs y su tamaño. 

    Por defecto, Docker tiene diversas formas de mostrar la información sobre sus contenedores. Y por defecto selecciona la opción de almacenar dicha información en formato de fichero JSON. Esto lo podemos visualizar a través del siguiente comando:

    docker info --format '{{.LoggingDriver}}'

    El problema principal de esto, es que Docker almacena la información de forma descontrolada. Es decir, si no lo configuramos, almacenará información sin ningún tipo de límite y que deje sin espacio el disco. Del cual nos podemos dar cuenta a través del mensaje del sistema no space left on device. Este problema también podemos comprobarlo a través del siguiente comando, el cual nos mostrará cuanto ocupan los ficheros:

    sudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log"

    Si nos encontramos con este error, podemos solucionarlo de varias formas. La primera de ellas, es la rápida pero incorrecta. Y es simplemente borrar los ficheros. 

    sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

    Pero esto solo conseguirá que más tarde o más temprano tengas el mismo problema. Por lo que no podemos decir que sea una solución. Ahora veremos como cambiarlo de forma permanente, de tres formas diferentes.

    • Indicar como debe rotar el log en el momento de arrancar el contenedor
    Podemos indicar diferentes opciones para rotar el log, como el máximo tamaño del log (max-size) o el número máximo de ficheros ha guardar (max-file). Ejemplo

    docker run --log-opt max-size=1m --log-opt max-file=3 \
    -d busybox sh -c "while true; do $(echo date); sleep 0; done" 
    

    Aquí también podemos ver un ejemplo de como rota el log. 

    • Indicar la configuración en el docker-compose. 
    También podemos indicarle a un contenedor concreto como queremos que roten los logs, dentro del docker-compose. Esto lo podemos hacer a través del parámetro logging y sus distintas opciones. 

    version: '3'
    
    services:
      portainer:
        image: portainer/portainer:1.24.1
        ports:
          - 9000:9000
          - 8000:8000
        command: --admin-password "$$2y$$12$$U5o8Pawz6T1rflKzFRzzyO3P9aDa.1Pm6M8xtHiUVhEIQurMkTilW"   
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - ./data/portainer:/data
      busybox:
        image: busybox
        logging:
          driver: "json-file"
          options:
            max-size: "200k"
            max-file: "10"
        command: ["sh","-c", "while true; do $$(echo date); sleep 0; done"]

    • Indicar la configuración en el fichero daemon.json
    De esta forma la configuración para rotar los logs se aplicará a todos los contenedores y no solo a los específicos que se lo indiques. Para ello tenemos que modificar el fichero /etc/docker/daemon.json e indicar el siguiente contenido:

    {
      "log-driver": "json-file",
      "log-opts": {"max-size": "10m", "max-file": "3"}
    }
    

    Como veis, es similar a las opciones que hemos puesto anteriormente y admite las mismas opciones. Pero en este caso deberemos reiniciar docker a través del siguiente comando:

    systemctl reload docker
    

    Por último, indicar que a través de la opción driver, se pueden indicar distintos destinos para los logs de docker. Algunos de estos pueden ser:
    • none: no almacena ningún tipo de log
    • syslog: envia los logs al demonio syslog
    • journald: envia los logs al demonio journald.
    • awslogs: envia los logs a Amazon CloudWatch Logs
    Puedes ver más drivers, aquí. 

    miércoles, 19 de agosto de 2020

    Maven Tips & properties

    En este post vamos a utilizarlo para compilación de variables de Maven y su funcionalidad.

    Vamos a hacer una pequeña recopilación de variables, propieades y trucos básicos de Maven que nos pueden ayudar a un mejor entendimiento y manejo del mismo.

    Empezaremos por las variables, las cuales podemos utilizar dentro del pom.xml y que nos darán acceso a información dentro del mismo proyecto. Como pueden ser:
    • project: Objeto referencia del proyecto. A través del cual podemos acceder al resto de sus valores. 
    • parent.project: Objeto referencia al proyecto padre dentro de un proyecto multimódulo.
    • env: Objeto referencia a variables de entorno del sistema.
    • settings: Objeto referencia a la configuración local de maven.
    • maven: Objeto referencia al software Maven ejecutor.
    A través de estos objetos podemos acceder a distintas propiedades dentro de cada uno de ellos, como pueden ser:
    • project.artifactId: Identificador del proyecto
    • project.groupId: Identificador del proyecto
    • project.version: Identificador del proyecto.
    • project.basedir: Carpeta principal del proyecto. 
    • project.build.directory: Carpeta donde se ubica el código compilado, normalmente el target. 
    • project.build.finalName: El nombre del fichero del proyecto una vez empaquetado.
    • maven.build.timestamp: Fecha actual en el momento de hacer el build. 
    • maven.repo.local: Ruta al repositorio local del usuario ${user.home}/.m2/repository
    • settings.localRepository: Ruta al repositorio local del usuario ${user.home}/.m2/repository
    Estas variables deben usarse entre llaves y anteponiendo el simbolo del dollar. Ejemplo: ${project.groupId}. En esta página podreis encontrar el listado completo.

    También existen ciertas propiedades que podemos configurar para modificar el comportamiento del proyecto, como son:
    • maven.compiler.source: Nos permiten indicar el nivel de compilación de nuestro código
    • maven.compiler.target: Nos permite indicar el nivel de compilación, del código compilado. 
    • project.build.sourceEncoding: Nos permite indicar el charset asociado a nuestro código fuente. 
    • project.reporting.outputEncoding: Nos permite indicar el charset asociado al código generado. 
    Otra asunto a tener muy en cuenta son las fases de maven. Esto es un apartado fundamental y que mucha gente desconoce. Debemos saber el funcionamiento del ciclo de vida de Maven, que este está compuesto por fases y que la ejecución de unas implica la ejecución previa de las anteriores. 
    Es decir, que si indico el comando mvn package, le estaré indicando que ejecute la fase del ciclo de vida package, pero que para llegar a ella pasaré anteriormente por las fases validate, compile y test. 
    • validate: valida que el proyecto sea correcto y esta la información mínima y necesaria. 
    • compile: compila el código fuente.
    • test: prueba el código fuente usando un framework de testing unitario. 
    • package: empaqueta el código comilado en un formato distribuible.
    • integration-test: procesa y despliega el paquete generado, si es preciso, en un entorno específico donde se ejecutarán los tests de integración.
    • verify: verifica que el paquete sea correcto.
    • install: almacena el paquete generado en el repositorio local.
    • deploy: almacena el paquete generado en un repositorio remoto.  
    Aparte hay dos fases que se saltan este ciclo de vida y que su ejecución no aplica la ejecución de otra fase. Estas son: 
    • clean: permite limpiar el directorio build.
    • site: genera la documentación del proyecto dentro de la carpeta site.
    Por último también debemos entender que estas fases estan asociadas a goals. Y que estos goals ejecutados en cada fase, funcionan de una forma en función del tipo de proyecto (indicado en base a su empaquetado, propiedad packaging). Es decir que al ejecutar mvn package, en un proyecto de tipo JAR, se ejecutará el jar:jar y al ejecutarlo sobre un proyecto WAR, se ejecutará war:war.

    miércoles, 15 de enero de 2020

    Maven: Encriptar contraseñas

    Una práctica habitual es crear perfiles para la configuración de distintos entornos en una aplicación maven. Y como es normal dentro de esta configuración es posible que vayan contraseñas. Hoy mostraremos como encriptar contraseñas en Maven y un par de consejos para el correcto manejo de las mismas.

    Para empezar debemos generar una clave maestra. Esta la crearemos a través del siguiente comando:

    mvn --encrypt-master-password
    

    Al introducirlo nos pedirá que introduzcamos nuestra clave maestra. Y nos la devolverá códificada.

    {Q0eIoh2W24Hovj4oE0pXgObO3zHOXn/gvQC1gMFoI=}
    

    Esta clave maestra, con el siguiente formato, la incluiremos en el fichero .m2/settings-security.xml, (que como sabéis se encuentra dentro de la carpeta home del usuario).

    <settingsSecurity>
      <master>{Q0eIoh2W24Hovj4oE0pXgObO3zHOXn/gvQC1gMFoI=}</master>
    </settingsSecurity>
    

    Ahora ya podremos encriptar contraseñas a través del comando --encrypt-password o -ep

    mvn -ep root
    {d/vIFp4AAAH2yHgBmc4A5NHaUdhOQWon9htDpHZBY=}
    

    Pero aquí viene un pequeño pero. Estas contraseñas generadas las podremos incluir solamente en el fichero settings.xml (ubicado también en la carpeta m2). ¿Por qué en el settings.xml y no directamente en el pom.xml?. Pues porque es una best practices, y la sección server del settings.xml se creó para eso mismo: gestionar información sensible sobre servidores, la cual no debería esta navegando libremente. Por tanto nuestra configuración quedaría así:

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0                         https://maven.apache.org/xsd/settings-1.0.0.xsd">
      <localRepository />
      <interactiveMode />
      <offline />
      <pluginGroups />
      <servers>
        <server>
          <id>mysql-local</id>
          <username>root</username>
          <password>{d/vIFp4AAAH2yHgBmc4A5NHaUdhOQWon9htDpHZBY=}</password>
        </server>
      </servers>
      <mirrors />
      <proxies />
      <profiles /> 
      <activeProfiles />
    </settings>
    

    Y con esto ya tendríamos nuestras contraseñas relativas a los servidores codificadas y listas para usar con maven... ¿Pero como lo uso dentro del pom.xml? Esto parece una verdad a medias...

    Buena pregunta. podemos hacerlo de dos formas:
    • Si vamos a utilizar un plugin, podemos cambiar la configuración username/password por server. Siempre que ese plugin lo permita, por ejemplo tomcat7-maven-plugin lo permite.  
    <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
            <url>http:// localhost:8080/manager</url>
            <server>TomcatServerConfiguredInSettingsXml</server>
        </configuration>
    </plugin>
    <build>
        <extensions>
            <extension>
                <groupId>com.github.shyiko.servers-maven-extension</groupId>
                <artifactId>servers-maven-extension</artifactId>
                <version>1.3.1</version>
            </extension>
        </extensions>
    </build>
    <profiles>
        <profile>
            <id>local</id>
            <properties>
                <mysql.userName>${settings.servers.mysql-local.username}</mysql.userName>
                <mysql.password>${settings.servers.mysql-local.password}</mysql.password>
            </properties>
        </profile>
    </profiles>
    

    domingo, 31 de marzo de 2019

    EclipseTips: Como sacar provecho a tu IDE

    Hoy vamos a ver varios trucos de eclipse, para mi gusto el mejor IDE para java. Esta no es idea original mía (igual no hay ninguna en todo el blog :-P) sino que la he sacado de Twitter. El contenido se basa en el hashtag #EclipseTips, que es utilizado mayormente por la cuenta @EclipseJavaIDE. La idea es hacer una pequeña recompilación de los más interesantes y/o desconocidos. En cada descripción irá un enlace al tweet que contiene al truco. 
    Selecciona un conjunto de String concatenados, botón secundario y pulsar 'use StringBuilder for concatenation'.
    A la hora de autocomplementar puedes poner las letras mayúsculas del método para llegar antes a el. Similar a gradle.


    Poniendote sobre un equals y pulsando 'Ctrl+1' puedes invertir su orden. Util para evitar NullPointetException sino usas Apache Commons-Lang


    Si te pones sobre el atributo y pulsas 'Ctrl+1' te puedes crear su getter and setter específico. Pero si pulsas sobre la clase con botóns secundario, dentro de la sección 'source' esta la opción 'Generate Getters and Setters' que te permitirá crear todos los que aún no se han creado de una vez.

    Creando solo el valor de la variable o atributo (Ej: 1;). La seleccionamos y pulsamos "Ctrl+2+L" crearemos una variable local (para el ejemplo un entero), pero si pulsamos "Ctrl+2+F" crearemos un atributo de clase. 
    Si seleccionamos una variable y pulsamos 'Alt+Shift+R' se abrirá un menú para renombrar dicha variable. pero si lo pulsamos dos veces se abrirá un menú más amplio que nos permitirá indicar que se cambien los getters y los setters también.
    Seleccionando una linea completa de código y pulsando 'Alt+up' o 'Alt+Down' puedes mover dicha linea arriba o abajo. 

    Si por el contrario quieres copiarla arriba o abajo usa 'Ctrl+Alt+Up' o 'Ctrl+Alt+Down'.