Filtrare pubblicità con linux e un raspberry, bricolage per nerds

Sempre più tracciati, osservati e, alcune volte, anche perseguiti.

Se ci capita di cercare un prodotto su Amazon, ebay o chi per esso quante volte notiamo l’annuncio dello stesso prodotto quasi ovunque? Andiamo sul sito di un giornale, anche straniero ed eccolo lì, l’annuncio dello spazzolino elettrico che cercavo. Mi perseguiterà almeno per un mese.

Oppure vado su un giornale qualsiasi ed ecco gli annunci di incontri, compra casa, acquista auto e via dicendo.

Usando un computer ci si può difendere con adblock (anche se di recente hanno aperto un “servizio”, a pagamento naturalmente, per consenstire alcune pubblicità), ghostery, ublock origin e altri.

Molto peggio con i telefoni, tablet o smart tv dove (che casualità!) non si possono installare i plugin summenzionati se non con limitatissime funzionalità.

Naturalmente nessun governo ha ancora deciso di legiferare in materia quindi tocca fare da sè.

Sfruttando un’idea che esiste da tempo e ispirato da progetti interessanti ho deciso di mettere il cappellino da nerd e dedicarmi al bricolage digitale per risolvere, o quanto meno ridurre, il fastidio.

L’idea è in giro da tempo, si tratta di scaricare una lista di domini conosciuti per l’advertising e filtrarli a livello DNS, ridirezionando la richiesta ad un server locale che restituirà un’immagine GIF trasparente di 1 pixel.

Armato quindi di un raspberry (ma si può usare un qualsiasi PC con linux) mi sono dedicato a scrivere i passi necessari e relativo software per monitorare le statistiche, trovate tutto su un mio repo in github con le dovute istruzioni.

Fatto tutto si ottengono risultati davvero buoni. Interessante notare come in un giorno soltanto ci siano circa 2000 richieste DNS che vanno ad advertisers. Navigando in due persone.

total_ads_day

Ora però la domanda sorge spontanea.

Com’è possibile che, da solo ed in pochi giorni e con un device da 76€ (spedizione inclusa), riesca a filtrare quasi 2000 richieste di advertisers al giorno mentre il mio modem/router da quasi 200€ non può farlo?

Non mi piace pensare ai complotti e non giro per casa con un cappello d’alluminio ma non riesco a non ricordare che “pensare male è peccato, ma spesso ci si azzecca”.

advertising_gone

libGDX, un framework di sviluppo giochi in Java

LibgdxChi non è mai stato tentato di sviluppare un gioco? Purtroppo, specie in ambito Java, ci si scontra con quella che è la dura realtà di questa piattaforma, ovvero la difficoltà nel mettere in piedi qualcosa che, sfruttando le librerie grafiche di base, sia veloce e bello da vedere.

Grazie a libGDX questo problema si risolve dandoci il supporto a librerie di input, audio, video (OpenGL compresa), un engine fisico con dei wrapper per la conosciuta Box2D e, dulcis in fundo, persino la possibilità di sviluppare in ambito multipiattaforma su Windows, Linux, Mac, Android, iOS e WebGL.

Continue reading libGDX, un framework di sviluppo giochi in Java

Continuous Integration con Code Coverage e Code Quality, gratis. Troppo bello per essere vero.

travis_codecov_codacySpesso capita di vedere, ancora oggi, lo sviluppo del software affidato a sistemi di versioning (per così dire) del tutto improvvisati come una cartella di rete dove sono depositati una serie di eseguibili con nomi nel rango di:

  • application.jar, 2014/05/01 12:00
  • application_FIX.jar, 2014/05/02 12:30
  • application_FIX_NON_TOCCARE.jar, 2014/05/02 12:31
  • application_FIX_PRODUZIONE_PORCA_PUTT.jar, 2014/05/03 03:31

Da questo si evince anche che la prassi di testing, in questo caso, è:

Fai il deploy in produzione e vedi che succede

Analizziamo un attimo ciò che sembra essere successo in questo caso.

application.jar è stata ultimata e nemmeno mezz’ora dopo abbiamo già un nuovo deploy per un qualche bug, nemmeno un minuto dopo ecco una nuova versione FIX_NON_TOCCARE, evidentemente il fix ha introdotto una regressione, prontamente sistemata. Successivamente alle tre e passa del mattino capita il classico “fix in produzione”. Alzi la mano chi non si è mai trovato in scenari simili. A me personalmente è capitato diverse volte in passato.

Cosa è successo qui? Andiamo per ordine:

  • il primo fix è sintomo di un qualche corner case non individuato in precedenza o anche semplicemente una svista.
  • il fix FIX_NON_TOCCARE è sintomo di mancanza di test (JUnit ad esempio) perchè il fix precedente ha semplicemente rotto i contratti o la business logic.
  • per ultimo, il FIX_PRODUZIONE_PORCA_PUTT capita spesso a causa di test d’integrazione deboli, se non del tutto assenti, con i componenti che poi interagiscono in produzione.

Come possiamo ovviare, o almeno mitigare, tutti i rischi di questo ciclo?

  • Versioning prima di tutto usando SVN, Git, CVS o chi per esso.
  • test unitari e comportamentali durante lo sviluppo, in ambito Java possono essere JUnit e JBehave ad esempio.
  • Continuous Integration, con questi sistemi (ad. es. Jenkins) siamo sicuri che il codice introdotto ad ogni merge non “rompa” la build.
  • Test Coverage per assicurarci che i test coprano correttamente il codice.
  • Code Quality, spesso una semplice analisi statica del codebase è sufficiente per inviduare bug, bad practices o peggio, come ad esempio risorse non rilasciate o flussi di controllo che portano a stati instabili.

Versioning

Non mi addentrerò in modo particolare su questo tema, in rete è disponibile una vasta pletora di articoli, tra i miei preferiti riporto questo. In breve si tratta di usare le rame di feature per le nuove funzionalità. Quando queste vengono ultimate si esegue un merge verso “develop” (preferibilmente con pull request e code review) per poi finalmente far confluire tutti i cambi di develop a “master” e poter così procedere ad una release di una nuova versione.

Testing

Inizialmente scrivere i test unitari può sembrare una sciocchezza. Perchè scrivere un test di un POJO che ad esempio non può accettare un parametro con valore null? È ovvio che non arriverà mai null e nel resto dei componenti farò in modo che non accada mai.

Tutto vero, fino a quando non succede. A volte può succedere perchè non si sono individuati tutti i corner case in fase di stesura del test, altre volte può succedere perchè cambiano le condizioni al contorno quali, ad esempio, il cambio dell’ora legale in un server remoto.

Un altro grosso vantaggio dei test è quando si riprende in mano una codebase per estenderla a distanza di settimane se non mesi. Dopo tutto quel tempo è difficile introdurre cambi e spesso si finisce per rompere funzionalità già esistenti, introducendo quello che in gergo di ingegneria del software si chiama “regressione”.

Un valido punto di partenza per TDD (Test Driven Development) e BDD (Behavioural Driven Development) è lo stub di wikipedia.

Per quanto riguarda il test coverage, in ambito Java, abbiamo vari plugin maven, uno su tutti è Jacoco. Spesso anche gli IDE consentono di valutare la copertura del codice.

Continuous Integration

Il modello di sviluppo con Git, dove ciascun sviluppatore lavora nella propria rama, fa in modo che si possa parallelizare il più possibile lo sviluppo. Successivamente i cambi verranno integrati (attraverso il merge) in una singola branch (develop). Qui viene in aiuto il Continuous Integration (CI).

Il grosso vantaggio del CI è quello che ci evita portarci in locale i cambi delle altre branch in locale per eseguire una build (ad. es. con maven), se invece portiamo tutti i cambi in una singola branch il CI si occuperà di eseguire tutti i test (ed i cambi della codebase) che le varie branch si portano dietro. Nel caso i test siano tutti ok (green in gergo) si può anche procedere successivamente a migrare la rama master con develop e rilasciare una nuova versione (release) con tutti i cambi.

Normalmente per avere un CI è necessario avere in loco una istanza di Jenkins o simili. Oggi però abbiamo anche servizi sulla nuvola e persino free per codice open source quali ad esempio Travis CI. Per una carrellata di altri servizi si può partire da GitHub.

L’utilizzo di Travis è veramente semplice. Si tratta di loggarsi con la propria utenza GitHub ed aggiungere i repo che si vogliono includere nel ciclo di continuous integration. Per questo è sufficiente copiare un file di nome .travis.yml:

sudo: false
language: java
jdk:
  - oraclejdk8

A questo punto basta un commit e push del proprio branch per vedere i risultati nelle console di travis. L’esempio sopra informa travis semplicemente che il linguaggio è java e che va usato l’Oracle JDK.

Tests run: 25, Failures: 0, Errors: 0, Skipped: 0

[INFO] 
[INFO] --- jacoco-maven-plugin:0.7.5.201505241946:report (report) @ life-game ---
[INFO] Analyzed bundle 'life-game' with 18 classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.086 s
[INFO] Finished at: 2015-12-27T19:38:51+00:00
[INFO] Final Memory: 19M/344M
[INFO] ------------------------------------------------------------------------

Travis offre molte opzioni di configurazione per l’esecuzione dei test, possiamo avere ad esempio un’istanza mysql, un virtual framebuffer per le applicazioni con GUI e persino firefox se si vogliono svolgere frontend test con selenium. La documentazione è ricchissima e vi invito a leggerla. RTFM, sempre. 🙂

Code Coverage

Come detto prima ci sono molti tool che consentono di valutare la copertura dei test, sia in fase di build che dentro il proprio IDE. Alcuni tool però ci consentono di andare un po’ oltre e producono analisi e suggerimenti su dove intervenire.

Uno di questi strumenti, del tutto gratuito per software open source, è Codecov. Come per Travis CI l’installazione è triviale. Si tratta di collegarsi con il proprio profilo di GitHub e associare i vari repo e successivamente potremo avere i report sul code coverage dopo ogni commit o durante una pull request verso master o develop. Qui vediamo alcune schermate:

codecovcodecov_suggPer far si che il codice sia analizzato basta aggiungere qualche riga al nostro .travis.yml:

sudo: false
language: java

jdk:
  - oraclejdk8

before_script:
  - pip install --user codecov

after_success:
  - codecov

Una feature molto pratica è che codecov-io inserisce un commento in fase di pull request indicando i cambi nel code coverage per la PR. Qui vediamo un merge particolarmente riuscito 🙂

codecov_commentQuesti due tool, di per se, sono già un validissimo complemento per evitare lo scenario iniziale ma ci resta ancora un’arma.

Code Quality e Code Review

Tutti commettiamo errori mentre programmiamo, nessuno escluso. In questo molti compilatori ci aiutano con analisi statiche del codice direttamente dall’IDE o con strumenti esterni come FindBugs o il sempre verde SonarQube.

Ma oltre a commettere errori a volte siamo anche distratti e ci dimentichiamo di eseguire un check. Altre volte il tempo non ci permette di analizzare il codice e altre volte ancora gli errori arrivano a develop perché non si fanno le code review per mille ragioni, spesso per motivi di tempo, è sempre difficile concordare con il management uno slot di tempo dove chiudere quattro developer in una stanza per una code review. I developer vedono un’ora, un manager vede 4 ore/uomo “sprecate”.

In ogni caso, per chi non vuole limitarsi alla semplice analisi statica del codice dall’IDE (che comunque spesso trascura molti errori ovvi) ci sono strumenti che ci consentono di scrutinare il nostro codebase in maniera automatica ed asincrona. Per il momento mi sto affidando a Codacy.

Ancora una volta la configurazione è abbastanza triviale, si tratta di loggarsi con il proprio profilo di GitHub e iniziare ad associare i repo che si vogliono analizzare.codacyPer ogni repo possiamo configurare parametri quali tipi di issue da ignorare, altre da abilitare, cartelle da trascurare (ad esempio non vogliamo “inquinare” i nostri risultati con i problemi di altre librerie quali bootstrap, jquery, etc).

Anche qui possiamo vedere tutta una serie di statistiche per ogni commit, quali file sorgente presentano problemi e persino ottenere un “voto” (come a scuola) 🙂 per ciascun repo fino all’atomicità di un voto per commit.

codacy_commitConclusioni

Abbiamo visto una veloce carrellata di strumenti che consentono di migliorare notevolmente il processo e la qualità del codice, tutto con strumenti gratuiti e online, senza quindi dover installare server o software (oltre a git!) sulla propria macchina.

Naturalmente gli strumenti di cui sopra si possono usare con molti altri linguaggi e per alcuni di essi ci sono alternative più valide, come scritto prima un ottimo punto di partenza è la pagina di integrazioni su GitHub.

Buon coding!

Spark, un interessante java micro framework

Ultimamente sto lavorando parecchio con API REST e per una prototipazione rapida sono comodi alcuni micro framework Java, uno dei più interessanti a mio parere è Spark (da non confondersi con Apache Spark, forse la scelta del nome non è delle più felici).

La documentazione non è delle più esaurienti e gli esempi disponibili non sono molti ma per un programmatore più o meno navigato il suo utilizzo è semplice.

Se vi siete stufati di Spring e usare JEE a volte è come usare una BFG9000 per aprire noci date uno sguardo a Spark, ha i suoi pregi.

JitPack, come usare maven e github

Integrare un progetto GitHub con Maven ora é diventato facilissimo, basta andare su JitPack e cercare il git repo che si vuole includere, successivamente si tratta di aggiungere poche righe al proprio pom.xml. 

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>

e successivamente:

<dependency>
    <groupId>com.github.User</groupId>
    <artifactId>Repo name</artifactId>
    <version>Release tag</version>
</dependency>

Come indicato nello stesso sito, se il progetto non ha nessuna release si può applicare uno specifico commit id.

Java su Synology

A volte può essere comodo avere Java sul proprio NAS Synology e provare piccoli sviluppi software java o magari su tomcat o jetty.

Un bel post su PC Load Letter illustra le operazioni da fare. E’ importante conoscere quale CPU monta il proprio NAS. Funziona perfettamente sul mio DS110J ma non aspettatevi prestazioni da brivido per la JVM, in fondo si tratta di un NAS di 5 anni fa.

Non ho provato ad installare Glassfish o JBoss perché già Tomcat sembra essere al limite su questo NAS, sicuramente con i Synology più recenti la situazione sarà migliore. Onestamente non saprei nemmeno dire se gli application server prima elencati possano funzionare con Java SE Embedded, ma poter avere un Tomcat è una buona cosa.

Java e servizi Windows

Prima o poi capita la necessità di dover creare un’applicazione e dover renderla un servizio per sistemi Windows.

In questi casi o si decide di programmare (e compilare) in linguaggi della piattaforma Microsoft oppure, ad esempio nel mio caso, si rende necessario ricorrere ad altre soluzioni per poter utilizzare Java.

In rete si trovano molti wrapper per Java, ad esempio Java Service Wrapper di Tanuki Software, Launch4j, JSmooth, l’elenco e lungo e basta cercare “windows java wrapper”. Personalmente mi sono fermato su Procrun, demone distrubuito da Apache Commons.

Vediamo nel dettaglio come utilizzarlo. Continue reading Java e servizi Windows

Patents and Intellectual Property, Oracle vs Google

Oracle vs Google, capitolo finale.

Oracle accusa Google di aver infranto, consapevolmente, una serie di copyright relativi a Java, originariamente depositati da Sun Microsystems, ma che dal gennaio 2010 fanno parte della vastissima collezione personale di Oracle.

Continue reading Patents and Intellectual Property, Oracle vs Google

Glassfish upgrade 3.1.2, qualche rogna di troppo

Recentemente mi è capitato di aggiornare un paio di server dalla 3.1.1 a 3.1.2, il passaggio però non è stato dei più fluidi, oltretutto trattandosi di una minor release.

Il primo problema arriva da updatetool. Durante lo scaricamento dei pacchetti ci troviamo un bel timeout quando si arriva all’upgrade di metro. Dopo qualche ricerca su google il problema sembra essere al default timeout dell’updatetool che è poco coerente con la dimensione di alcuni pacchetti, la soluzione è impostare una variabile d’ambiente prima di lanciare updatetool:

> export PKG_CLIENT_LOWSPEED_TIMEOUT=300
> ./updatetool

Secondo problema, l’avvio del dominio non va a buon fine. Infatti dal log si legge:

[#|2012-04-04T10:39:06.145+0200|SEVERE|glassfish3.1.2|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadI
D=10;_ThreadName=Thread-2;|Startup service failed to start : com.sun.enterprise.security.admin.cli.SecureAdminStartupChe
ck|#]

[#|2012-04-04T10:39:06.166+0200|INFO|glassfish3.1.2|javax.enterprise.system.tools.admin.com.sun.enterprise.v3.admin|_Thr
eadID=15;_ThreadName=Thread-2;|Server shutdown initiated|#]

La soluzione non è proprio delle più semplici, è necessario ricreare i certficati, io mi sono limitato a creare un nuovo dominio e brutalmente copiare i file *.jks dal nuovo dominio al vecchio:

> asadmin create-domain domain2
> cd domain2/config
> copy *.jks ../../domain1/config
> asadmin delete-domain domain2

Ora non ci resta che aggiornare il domain

> asadmin start-domain --upgrade

Finalmente parte tutto, purtroppo non si riesce più ad entrare nella console di amministrazione, ci restituisce un bel “Secure login is not enabled”. Di nuovo tocca mettere mano nel server con asadmin.

> asadmin --host [host] --port [port] enable-secure-admin
> asadmin stop-domain
> asadmin start-domain

Ovviamente [host] e [port] vanno rimpiazzati con valori opportuni, ad esempio indirizzo IP e porta 4848 nel mio caso, il restart è necessario per leggere le nuove impostazioni.

Tutto sommato un upgrade non proprio dei più lisci.

Java, Sun, Oracle, Canonical, solita stronzata

In data ancora da destinarsi il Sun JDK/JRE verrà rimosso. La motivazione è presto detta, Oracle ha semplicemente ritirato la licenza di distribuzione per il Sun(Oracle) JDK, rendendo de facto OpenJDK come standard. Canonical è andata un po’ oltre e, attraverso un pacchetto di aggiornamento vuoto, rimuoverà eventuali Sun JDK presenti nel sistema. O si installa OpenJDK oppure si installa manualmente la Sun JDK. L’annuncio ufficiale è qui, le motivazioni mi sembrano valide per sistemi desktop, un po’ meno valide per sistemi server che difficilemente avranno un browser con il plugin java installato.

Il problema è che molte cose ancora non girano bene con OpenJDK, ad esempio i più diffusi application server come JBoss, ed in misura minore Glassfish. Se avete quindi dei server con tali piattaforme su release ubuntu server vi consiglio caldamente, fin da ora, di rimuovere i pacchetti canonical partner e procedere all’installazione manuale del JDK.