Subir a maven central una librería propia

Ahora que ya acabas de construir una librería interesante en Java, la has hecho pública (en github, por ejemplo) y quieres que todo el mundo la use… Queda una tarea pendiente, subirla a un repositorio maven para ponerla a disposición de los que utilicen este sistema (o gradle, que hoy en día ya son casi todos).

Vamos a verlo con un ejemplo que he subido esta mañana… Hay cosas que todavía no entiendo del todo, pero el resultado ha sido bueno, por lo que, al menos, podremos usar esta receta como guía para próximas veces.

El código que intento subir es una librería simple que tengo alojada en github con su pom.xml básico y que si te descargas el proyecto podrías compilar e instalar en tu maven con mvn install. La dirección es esta:

https://github.com/yoprogramo/nomorepass-java/

Ahora, para que todo el mundo pueda descargárselo como dependencia y no tenga que hacer el mvn install del proyecto, tenemos que subirlo a un repositorio público, podemos ver una guía en esta página: Guide to Public Maven Repositories. Tal como explican en la página, lo más sencillo para publicar en Maven Central es usar el repositorio Sonatype. Dicho y hecho… Lo intentamos por aquí.

Lo primero es crear una cuenta en el Jira de Sonatype aquí. Lo siguiente, y esto es un poco «tricky» es crear un ticket solicitando un nuevo id de grupo en esta dirección. No se puede pedir cualquier id de grupo (en mi caso quería pedir com.nomorepass) y generalmente se pedirá alguna prueba de que el dominio es tuyo. En mi caso este es el ticket que creé: https://issues.sonatype.org/browse/OSSRH-49426, para demostrar que el dominio era mío cambié el DNS e incluí una entrada TXT con el identificador del ticket:

Una vez autorizado (tarda un poco, es un proceso manual) hay que modificar nuestro código y prepararlo para la subida, pero, antes de eso, tenemos que generar nuestras claves gpg para poder firmar el código. eso se hace con este comando:

gpg --gen-key

Una vez generada podremos acceder a la lista de claves con el comando:

gpg --list-keys

Toma nota del id de la clave y recuerda la contraseña que usaste para generarla, porque tendrás que recordarla. Además, tendrás que publicarla en algún servidor de claves públicas para que pueda ser comprobada.

gpg --keyserver hkp://keys.gnupg.net --send-keys <el-id-de-la-clave>

Ahora empezamos a modificar el pom.xml para que cumpla con los requisitos para el repositorio Maven Central. En nuestro caso pusimos esto:

<groupId>com.nomorepass</groupId>
  <artifactId>nomorepass</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>

  <name>Nomorepass java library</name>
  <description>NoMorePass protocol 2 implemented on Java.</description>
  <url>https://nomorepass.com</url>

  <licenses>
    <license>
      <name>Apache License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
      <distribution>repo</distribution>
    </license>
  </licenses>

  <developers>
    <developer>
      <name>Jose Antonio Espinosa</name>
      <email>[email protected]</email>
      <organization>Nomorepass</organization>
      <organizationUrl>https://nomorepass.com</organizationUrl>
    </developer>
  </developers>

  <scm>
    <connection>scm:git:git://github.com/yoprogramo/nomorepass-java.git</connection>
    <developerConnection>scm:git:ssh://github.com:yoprogramo/nomorepass-java.git</developerConnection>
    <url>https://github.com/yoprogramo/nomorepass-java/tree/master</url>
</scm>

Y, una vez informado de todo esto, hay que incluir los plugins que nos permitirán hacer el despliegue directamente. Yo añadí esto:

<distributionManagement>
    <snapshotRepository>
      <id>ossrh</id>
      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
      <id>ossrh</id>
      <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

Y puse en mi directorio de maven settings.xml los datos de mi usuario

<settings>
  <servers>
    <server>
      <id>ossrh</id>
      <username>xxxxxxxxxx</username>
      <password>xxxxxxxxxx</password>
    </server>
  </servers>
</settings>

Por último, toda la sección de build (que no tenía) la sustituí por esto:

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-gpg-plugin</artifactId>
        <executions>
          <execution>
            <id>sign-artifacts</id>
            <phase>verify</phase>
            <goals>
              <goal>sign</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.sonatype.plugins</groupId>
        <artifactId>nexus-staging-maven-plugin</artifactId>
        <version>1.6.7</version>
        <extensions>true</extensions>
        <configuration>
          <serverId>ossrh</serverId>
          <nexusUrl>https://oss.sonatype.org/</nexusUrl>
          <autoReleaseAfterClose>true</autoReleaseAfterClose>
        </configuration>
      </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-source-plugin</artifactId>
          <version>2.2.1</version>
          <executions>
            <execution>
              <id>attach-sources</id>
              <goals>
                <goal>jar-no-fork</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-javadoc-plugin</artifactId>
          <version>2.9.1</version>
          <executions>
            <execution>
              <id>attach-javadocs</id>
              <goals>
                <goal>jar</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
    </plugins>
</build>

Y ya, finalmente, pude ejecutar el mágico:

mvn clean deploy

Si todo ha ido bien, el artefacto estará subido a un repositorio que tendremos que promocionar a «Release» para que se sincronice con el repositorio central… Pero al final ya lo tendremos disponible para todo el mundo…

Aquí podéis encontrar lo que acabo de subir: https://search.maven.org/artifact/com.nomorepass/nomorepass/1.0/jar

Protege tu .git

Hasta hace poco en mi empresa utilizábamos subversion como repositorio, no somos un equipo grande y las funcionalidades que nos ofrecía el repositorio eran suficiente para nuestros proyectos.
Recientemente, debido a que un cliente nos ha impuesto utilizar git como repositorio principal y dado que nuestra relación con ellos es muy importante, decidimos mover todos nuestros repositorios a git. Tampoco es que vayamos a utilizar extensivamente las ventajas que nos ofrece, pero si que nos obligaría a funcionar de manera más fluida con una herramienta que vamos a necesitar si-o-si.

El caso es que, en nuestra anterior configuración, utilizábamos subversion para mantener el código de producción de algunas webs y al modificar el repositorio hicimos lo propio con git, teniendo una «feliz transición». El problema vino en que, realmente, no eramos conscientes de las diferencias reales que tenían los dos repositorios y dentro de los directorios servidos junto a la web en cuestión se encontraba el directorio .git.

¿Qué significa esto? Pues ni más ni menos que todo el mundo mundial tiene acceso a tu repositorio local y puede, entre otras cosas, acceder a todo el código de lo que hay allí publicado… Y eso no puede ser. ¿Qué hacemos para evitarlo?

Hay varias formas de hacerlo, dependiendo de si tienes o no un .htaccess en tu web o no y de la configuración de tu servidor, en mi caso la solución que implementamos fue añadir las siguientes líneas al archivo de configuración de cada web:

        <Directory /directorio.de.la.web/.git>
		Options FollowSymLinks
		AllowOverride All
		Require all denied
	</Directory>

Esto indica al servidor que todo lo que hay bajo el directorio .git no está autorizado para ser visto… Reiniciamos el servidor o recargamos la configuración y ya tendremos el problema resuelto.

Y con esto y un bizcocho… Podemos empezar nuestra semana.

Instalar un servidor de correo con docker

Hace tiempo que vengo mirando la tecnología de contenedores con interés, la verdad es que desde hace mucho tiempo el trabajo más ingrato, después de haber terminado un desarrollo, era configurar el servidor donde se iba a ejecutar finalmente. No basta con saber el sistema operativo, necesitas instalar una miriada de dependecias y de versiones de software que no siempre se encuentra en la versión que usaste para el desarrollo. Docker promete poder replicar entornos completos mediante una virtualización parcial y eso me parece muy, muy interesante.

Aunque no entraré al análisis profundo de cómo funciona docker, por el momento, si que veremos un ejemplo práctico de una tarea muy habitual como administrador de sistemas, configurar un servidor de correo con todos los servicios habituales. Para ello vamos a utilizar una máquina virtual (no sirve cualquiera, hay sistemas de virtualización que no se llevan bien con docker, en mi caso usé un VPS de OVH después de desechar otros dos de strato y webserver4you). Nuestra máquina virtual tiene un ubuntu 14.04… Al lío.

Lo primero que hay que hacer es instalar docker. Por suerte esto es bastante sencillo:

sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates
sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
sudo apt-get install docker-engine

Con esto ya tendremos docker en la máquina. Podemos probarlo:

sudo service docker start
sudo docker run hello-world

Si no queremos andar usando sudo para cada comando, añadiremos nuestro usuario al grupo de docker:

sudo groupadd docker
sudo usermod -aG docker $USER

Ahora usaremos Poste.io como contenedor de nuestro servidor de correo. Es una solución simplemente completa y muy sencilla de instalar y configurar. En nuestro caso lo único que hay que hacer para ponerlo a funcionar es crear un directorio (en mi caso /home/mail/data) y ejecutar lo siguiente:

docker run \
-p 25:25 \
-p 81:80 \
-p 110:110 \
-p 143:143 \
-p 8443:443 \
-p 465:465 \
-p 587:587 \
-p 993:993 \
-p 995:995 \
-v /etc/localtime:/etc/localtime:ro \
-v /home/mail/data:/data \
-e "HTTPS=OFF" \
--name "mailserver" \
--restart=always \
-t analogic/poste.io

Lo más relevante en este caso es que NO queremos las redirecciones https porque vamos a configurar el servidor apache que ya tenemos para que actúe de proxy y será él quien tenga el https y los certificados y que el puerto que exponemos para la administración es el puerto 81 (redirigido al puerto 80 del contenedor).

Para que sea accesible desde el exterior por https lo que hicimos fue configurar un virtualhost en apache de esta manera:

<VirtualHost *:80>
        ServerName mail.midominio.es
        AssignUserId mailuser mailuser

        ServerAdmin [email protected]
        DocumentRoot /home/mailuser/www

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        <Directory /home/mailuser/www>
                Options Indexes FollowSymLinks
                AllowOverride All
                Require all granted
        </Directory>

ProxyPass / http://localhost:81/

RewriteEngine on
RewriteCond %{SERVER_NAME} =mail.midominio.es
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
</VirtualHost>

La configuración del https es similar, aunque yo dejé que el certbot de let’s encrypt me lo configurase automáticamente al generar los certificados, quedó una cosa como esta:

<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerName mail.midominio.es
        AssignUserId mailuser mailuser

        ServerAdmin [email protected]
        DocumentRoot /home/mailuser/www

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        <Directory /home/mailuser/www>
                Options Indexes FollowSymLinks
                AllowOverride All
                Require all granted
        </Directory>

ProxyPass / http://localhost:81/

SSLCertificateFile /etc/letsencrypt/live/mail.midominio.es/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mail.midominio.es/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/mail.midominio.es/chain.pem
</VirtualHost>
</IfModule>

Si todo ha ido bien (seguro que algún detalle se nos pasa), tendremos el contenedor funcionando y podremos acceder al administrador de esta manera:

https://mail.midominio.es/admin/

Y, después de verificar la identidad y hacer los primeros ajustes de dominio, cuentas y demás podremos disfrutar de nuestro servidor de correo…

 

Construyendo mi propia máquina de arcade

Esta, tengo que reconocerlo, es una entrada que tenía muchas ganas de escribir. Para mi es muy especial el poder construir cualquier cosa, y si esa cosa es útil, o aporta algo a quien la usa, pues mejor que mejor… El caso es que yo, como cualquiera nacido en los setenta, he tenido una infancia y juventud muy influenciada por los videojuegos arcade. Y dado que tenía un ordenador viejo por casa y que me entró la nostalgia de esos tiempos, me puse como tarea construirme una. Y este es el resultado:

bartop_finalAhora bien, llegar hasta este resultado no ha sido fácil, ni rápido. Pero el esfuerzo creo que ha merecido la pena y, la verdad, toda esta actividad de constructor me ha entretenido un montón y me ha despejado la mente de muchos otros problemas….

Y al principio era el ordenador…

La idea que me rondaba por la cabeza cada vez con más insistencia y, revisando mi trastero, descubrí que tenía un ordenador que ya no usaba con una forma que me estaba llamando. El ordenador era este:

IMG_20141026_122921Un ordenador con su base y todo que había servido como kiosko de fotos y que tenía toda la placa detrás del monitor y la base era la fuente de alimentación… Tome unas cuantas medidas y me hice un plano mental, que luego convertí en cartón. Ah! y mientras tanto compré unos mandos arcade para ir notando el tacto del joystick.

Usando un poco de cartón que encontré por ahí e imprimiendo mis plantillas en hojas de papel terminé montando esto:

IMG_20141107_183624Aproveché entre recorte y recorte y me decidií a probar algunas distribuciones linux con mame para darle la vida a mi maquinita. Al final me decanté por Live MameCab, que tenía todo lo que podría desear y se manejaba todo con los mandos. Luego conseguí unos cuantos cientos de gigas en ROMS de mame y, bueno, todavía estoy eligiendo los juegos.

Después de mucho tiempo decidiendo si terminar o no la máquina, me puse manos a la obra y saqué un despiece (todo hecho con el inkscape, a mi el 3d no se me da demasiado bien) y me fui a pedir las maderas. Todo en MDF de 10mm, bastante barato y resistente. El problema es que en la tienda solo me hacían cortes en escuadra y con cierto tamaño mínimo, así que al final lo que obtuve fue esto:

IMG_20141116_131101Y me puse manos a la obra en mi terraza (perdón a los vecinos afectados) y con una sierra de calar que me costó 19 Euros (no se si será desechable, pero los huesos de mi mano terminaron por separarse de la carne del traqueteo). Obteniendo esto otro (se nota que no soy un experto):

IMG_20141116_160907Después de una sesión de lija interminable y de aumentar la contaminación en mi zona con un montón de serrín, empecé el montaje (nota para los que quieran escuchar, la pintura es más fácil darla antes del montaje), pero no podía esperar a verla montada:

IMG_20141116_190102A partir de ver mi caja ya con forma me puse creativo y diseñé (yo co mi gimp y mucho corta-pega) unos vinilos que encargué por internet y que quedaron así:

IMG_20141203_190526Pero claro, no podía pegar el vinilo sobre el MDF (es poroso), por lo que compré un poco de laca negra (me costó más cara que la madera) y le di un par de capas de pintura a todo el invento… La verdad es que queda la mar de bien la laca si se aplica de la manera correcta (no es el caso).

IMG_20141206_184305Una vez seco del todo, ya podíamos poner los vinilos, los mandos (y su glorioso cableado) y el resultado fue este:

la foto 2(1)Para llegar al resultado final (lo que hay en la primera foto) solo le faltaba un panel de metacrilato transparente para el frontal (y así poder poner más vinilos al rededor) y unas luces led para la marquesina, que, como van a 12 voltios las conecté directamente a la fuente de alimentación del ordenador y redirigir el botón de encendido del ordenador a otro más discreto (si, se ve en la foto del principio, pero hay que echarle imaginación, a ver quien la encuentra).

Y ahora a disfrutar… He instalado ya unos cuantos juegos y, la verdad, estoy empezando a jugar con mis hijos y recordando viejos tiempos. Una inversión perfecta.

 

 

WikiWars

Wikipedia no es libre

Perdón por el título tan extraño, pero es que es una etiqueta que llevo tiempo teniendo en mi mente y he creído que ahora era un buen momento para usarla, os explico por qué:

Como ya os he contado, estoy enfrascado con un proyecto que a mi me ilusiona mucho: biblioeteca. llevo cerca de un año dando vueltas a la idea, programando, haciendo planes de negocio, creando empresa, haciendo promoción, etc. Eso me quita una gran parte del día, pero al final estoy seguro de que se verán los resultados (si conseguimos resistir las vicisitudes iniciales). El caso es que comentándolo con un amigo, me sugirió que crease una entrada en la wikipedia para el servicio. Es algo muy normal que no se piense en wikipedia mientras estás en medio de la vorágine del lanzamiento de un proyecto, pero anoté la sugerencia.

Pasado un tiempo, después de aparecer en numerosos medios de comunicación y de tener una base de usuarios de cerca del millar me animé a escribir la entrada. Es cierto que tenía la cuenta creada como yoprogramo desde hace tiempo (2009), aunque no había participado en ella, sino en la wikipedia en inglés… Porque nunca había considerado interesante nada de lo que podría haber incluido en ella. Así que decidí ir con la verdad por delante y usar mi cuenta para crear la flamante página nueva de BiblioEteca en la Wikipedia… ¿Quién mejor que uno de los fundadores para crear esta página?

Y ahí empezaron las WikiWars…

Primero se calificó el artículo como promocional… Dado que tenía una sección de «BiblioEteca en los medios» y que el lenguaje parecía ser poco adecuado para la wikipedia. Se proponía su borrado por spam. Mi reacción, lógica, fue pedir consejo para mejorar el artículo, completarlo con más referencias y hacer que el lenguaje fuese neutral… En parte lo conseguí, no sin reticencias del bibliotecario que se encargó. Podeis ver la subrealista discusión en estos dos enlaces (si, las discusiones en la wikipedia suceden en las páginas de discusión de los usuarios y sin poder ver el dialogo completo): El malvado bibliotecario( y 2), yo intentando mejorar la página.

El caso es que, finalmente, se convenció de que no merecía el borrado y lo dejó en un cartel de advertencia… Pero eso si, avisó a otro colega (el editor escoba) que se dedicó a cuestionar la relevancia de la página. Según su mismo registro de actividad, este usuario ultimamente se dedica a borrar sin misericordia cosas de la wikipedia. Llegado este punto, intenté razonar sobre la razón por la que es relevante algo como Ballance (un jueguecito de PC desconocido) y no nuestro servicio… Intentos futiles, ya que las comparaciones no son argumentos y esa es la máxima de los wikipedistas en Español (el pasado es pasado y el futuro es lo que yo te diga): las comparaciones no sirven y los argumentos tampoco.

Las razones fueron discutidas por arriba y po debajo, la conclusión es que mi usuario no podía escribir el artículo por estar relacionado con lo que se describía (!!!!) Bueno, pues encarguemos a otro que lo haga… dicho y hecho, el usuario JAEandTheBooks apareció al rescate, utilizando otro ordenador de mi oficina, pero con las mismas ganas de colaborar… Pero tampoco, daba igual la cuenta desde la que se escribia ni lo que se escribía, argumentar es cansino y los wikipedistas ciegos del todo.

Ante el contraataque de JAEandTheBooks, salió otro supuesto usuario (Martinmartin) que, obviamente y al igual que los anteriores no se digna ni poner cual es su nombre… Pero eso si, tiene una opinión más importante que la mia. Solo escribe sobre un tema (difícil que no esté involucrado en él o que sea imparcial) y solo desde un punto de vista… Y además se enfada si le preguntas porqué el si puede hablar de un solo tema sin acusarsele de ser parcial y los demás no podemos. Visto que se queda sin argumentos ni razones para demostrar la irrelevancia del tema, deciden acudir a otro bibliotecario y lanzan una Verificación de usuario sobre yoprogramo y JAEAndTheBooks…

Y el resultado final: La página borrada y los usuarios suspendidos. ¿por qué? por usar la IP de la oficina y por argumentar en contra de la irrelevancia de algo. Encima, el borrado de la página tiene como motivo el «abuso de títeres», ni la irrelevancia ni el spam. Cosas las 3 completamente falsas y, obviamente, subjetivas.

Pero alguien ha vuelto a crear la página de nuevo… Es lo que tiene que sea un wiki.

Como conclusión para mi, ha quedado una sola: La wikipedia en español no es libre, ni permite que se le lleve la contraria a nadie, ni tiene ningún interés en el contenido que alberga, se limitan a darse premios entre ellos y a mantener alejados a todos aquellos que podrían generar contenidos modernos e interesantes y a decidir lo que se publica en base a quien lo publica, no a lo que se cuenta ni a las referencias que tenga… Una decepción para todos aquellos que confiábamos en la iniciativa y una demostración más del fracaso de la internet 1.5. Ni las mafias de meneame, oiga.

Y es que, como me dijo uno de los usuarios censores: «la wikipedia no es una democracia«.

ACTUALIZACIÓN 1: La página que se creó ayer ya ha sido borrado por otro editor poniendo como razón «recreación de una página borrada»… Y yo sigo sin entender cómo un editor me dice que si se espera lo suficiente cualquier otro podrá crear la página más tarde cuando sea relevante y va otro detrás y me borra la página… ¿Será que les dan puntos por quitar información de la enciclopedia?.

ACTUALIZACIÓN 2 : Parte de la discusión sobre la página se ha salvado. Podeis verla en Discusión sobre página BiblioEteca.

ACTUALIZACIÓN 3 : Alguien había vuelto a crear la página y no solo la han borrado sino que la han bloqueado por «vandalismo» promocional. El malvado bibliotecario ataca de nuevo!!!