lunedì 15 novembre 2010

Hibernate: differenza tra get e load

Il metodo get() sollecita immediatamente il database. Cio significa che, non appena avviene la chiamata la get(), Hibernate genera un'istruzione SQL per il database, nel tentativo di recuperare i dati (di solito una riga nel database) per ricostruire l'oggetto persistente richiesto.

Una chiamata load(), invece, non comporta una chiamata immediata al database. Il metodo load() implica la costruzione di un oggetto proxy che rapprensenta l'oggetto persistente. Solo dopo qualche passaggio l'oggetto proxy sollecita la generazione dell'istruzione SQL appropriata per il database e Hibernate costruisce il vero oggetto persistente.

Quando si usa get(), il metodo restituisce null se non viene trovato il dato richiesto.
Poiché il metodo load() non recupera immediatamente l'oggetto, se non viene trovato il dato viene generata una ObjectNotFoundException.
Quindi, se non si è sicuri dell'esistenza dell'oggetto, è preferibile usare la get().

martedì 2 novembre 2010

Monitoraggio e controllo delle applicazioni tramite JMX - Introduzione

JMX (Java Management Extensions) è una tecnologia introdotta nella versione 5.0 di Java che permette il monitoraggio ed il controllo delle applicazioni in maniera standardizzata.

Ogni applicazione, tramite gli MBean (Managed Beans) può esporre all'esterno sia delle proprietà (che possono essere monitorate) che delle operazioni (che si possono eseguire per modificare il comportamento dell'applicazione in runtime). L'applicazione che espone gli MBean può essere vista come un server a cui i client JMX (come, ad esempio, il tool jconsole) possono collegarsi.


La tecnologia JMX offre una maniera semplice e standardizzata per gestire le applicazioni. Il vantaggio per lo sviluppatore è che consente di implementare solo la parte strettamente legata all'applicazione da controllare, mentre fornisce tutta l'infrastruttura per esporre all'esterno le interfacce, gestendo in maniera (quasi) trasparente tutta la parte relativa alla comunicazione tra server e client.

Questa tecnologia è utilizzata anche all'interno della stessa JRE, ad esempio per permettere di controllare l'occupazione della memoria o per invocare su richiesta il garbage collector.


Vediamo un esempio di utilizzo di JMX per il controllo di una semplice applicazione, supponiamo di avere un semplice oggetto Printer che modella la scrittura periodica di una stampa su console:

package it.sinossi.poc.mbeanpoc;

public class Printer {

 private String text;

 private boolean printEnabled = true;

 private int sleepTime = 500;

 private boolean stop = false;

 public Printer(String text) {
  this.text = text;
 }

 public String getText() {
  return text;
 }

 public void setText(String text) {
  if (text != null && !text.isEmpty()) {
   this.text = text;
  } else {
   throw new IllegalArgumentException("text cannot be null or empty");
  }
 }

 public boolean isPrintEnabled() {
  return printEnabled;
 }

 public void setPrintEnabled(boolean printEnabled) {
  this.printEnabled = printEnabled;
 }

 public int getSleepTime() {
  return sleepTime;
 }

 public void setSleepTime(int sleepTime) {
  if (sleepTime >= 100 && sleepTime <= 1000) {
   this.sleepTime = sleepTime;
  } else {
   throw new IllegalArgumentException(Integer.toString(sleepTime) + " is not in range [100, 1000]");
  }
 }

 public void stop() {
  stop = true;
 }

 public boolean shouldStop() {
  return stop;
 }

 public void print() {
  System.out.println(text);
 }

}

La classe permette di modificare alcuni parametri come il testo ed il tempo di attesa, in più si possono eseguire le azioni di pausa, ripresa e stop, notare che i metodi setText e setSleepTime lanciano delle eccezioni nel caso in cui siano invocate con argomenti non validi. Sottolineo come non sia presente in nessuna parte di codice relativa a JMX.

Scriviamo un semplice main che permetta di vedere il codice all'opera

package it.sinossi.poc.mbeanpoc;

public class Main {

 public static void main(String[] args) throws Exception {

  Printer p = new Printer("Ciao");

  int counter = 0;

  while (!p.shouldStop()) {
   if (p.isPrintEnabled()) {
    System.out.print(Integer.toString(counter) + "  ");
    p.print();
   }
   counter++;
   Thread.sleep(p.getSleepTime());
  }
  System.out.println("Exiting");
 }

}

Avviando la classe Main si vedrà in console la stampa periodica della scritta "Ciao".


A questo punto si deve introdurre la componente fondamentale della tecnologia JMX: gli MBean. Gli MBean sono delle normali classi, simili ai java bean, che però devono implementare una interfaccia che sarà appunto quella che definisce i metodi di monitoraggio e controllo esposti all'esterno. Nel nostro caso l'interfaccia si chiamerà PrinterControlMBean e l'implementazione PrinterControl (questo tipo di nomenclatura è obbligatoria, l'interfaccia deve chiamarsi MBean e la relativa implementazione deve chiamarsi ).


package it.sinossi.poc.mbeanpoc;

public interface PrinterControlMBean {

 String getText();

 void setText(String text);

 int getSleepTime();

 void setSleepTime(int millis);

 void pause();

 void resume();

 public void stop();

}


package it.sinossi.poc.mbeanpoc;

public class PrinterControl implements PrinterControlMBean {

 private Printer printer;

 public PrinterControl(Printer printer) {
  this.printer = printer;
 }

 public String getText() {
  return printer.getText();
 }

 public void pause() {
  printer.setPrintEnabled(false);
 }

 public void resume() {
  printer.setPrintEnabled(true);
 }

 public void stop() {
  printer.stop();
 }

 public void setText(String text) {
  printer.setText(text);
 }

 public int getSleepTime() {
  return printer.getSleepTime();
 }

 public void setSleepTime(int millis) {
  printer.setSleepTime(millis);
 }

}

L'interfaccia PrinterControlMBean definisce le funzionalità della nostra classe Printer che vogliamo siano controllabili dall'esterno, in questo caso l'implementazione di questa interfaccia è molto semplice in quanto tutti i metodi delegano all'oggetto Printer, passato nel costruttore. Ancora una volta non è presente codice relativo alle API JMX.

Ora che abbiamo una classe che vogliamo sia gestita dall'esterno (Printer) e l'MBean che determina le funzionalità esposte all'esterno (PrinterControlMBean, PrinterControl), dobbiamo completare con la registrazione sul sistema del nostro MBean in modo che questo venga esposto all'esterno.

Questo verrà fatto nella classe Main, in cui viene istanziato l'MBean e viene registrato nell'MBean Server, che è il componente fornito dal sistema che si occupa di esporre all'esterno gli MBean.

public class Main {

 public static void main(String[] args) throws Exception {

  Printer p = new Printer("Ciao");

  registerMBean(p);

  int counter = 0;

  [...]
 }

 private static void registerMBean(Printer p) throws Exception {
  PrinterControl mbean = new PrinterControl(p);
  ObjectName objectName = new ObjectName("printercontrol:type=printer,name=console_printer");
  MBeanServer server = ManagementFactory.getPlatformMBeanServer();
  server.registerMBean(mbean, objectName);
 }

}

Ogni MBean viene registrato in associazione ad un'istanza di ObjectName, questo permette l'identificazione univoca della risorsa gestita dall'MBean. L'ObjectName è costruito con una stringa che codifica un dominio (in questo caso il dominio è "printercontrol") più delle coppie chiave=valore (type = printer, name = console_printer); gli spazi presenti nella stringa non vengono eliminati, quindi meglio che non ce ne siano.

A questo punto non resta che far pratire l'applicazione e successivamente avviamo jconsole.





Connettiamoci alla JVM relativa al nostro progetto.
Dal tab MBeans si possono vedere e controllare tutti gli MBeans registrati sul sistema, il nostro si trova sotto il dominio it.sinossi.
Jconsole permette di vedere e modificare gli attributi e di invocare i metodi esposti.



Proviamo a mettere in pausa, modificare la stringa che viene stampata, riattivare la stampa e poi stoppare il programma. Nella console si può vedere come le azioni svolte si ripercuotono sul comportamento del programma.


Ricordiamo che la classe Printer permette di impostare uno sleepTime compreso tra 100 e 1000 millisecondi, nel caso in cui si inserisca un valore non valido viene lanciata un'eccezione. Per vedere come si comporta il sistema proviamo ad impostare il valore 10. Il risultato è quello che si vede in figura: l'eccezione impedisce di impostare il valore non corretto, questo senza influire sul regolare funzionamento dell'applicazione che continua a girare senza accorgersi di niente.



See also:
Sorgenti del progetto su github
JMX Home Pape
Java Tutorial on JMX
JMX Best Practices
Java theory and practice: Instrumenting applications with JMX

martedì 19 ottobre 2010

Secure ssh: from password to public key authentication

Disabling ssh access with password authentication is an easy way to make more secure your system.
The alternative to password is authentication with public/private key pair. This prevents some security holes like sending the password over the net or brute force attacks.
First of all generate a pair of key in the client:
ssh-keygen -t rsa
you will be prompted for files where store the keys (default is ~/.ssh/id_rsa for private key and ~/.ssh/id_rsa.pub for public key) and for a pass-phrase to protect the private key (you will be prompted for every time you try to log to a remote host with public key authentication).
Next, upload the public key in the remote host, from the client host launch
ssh-copy-id remote-user@remote_host
This command installs the public key in the ~/.ssh/authorized_keys file of the remote-user on the remote_host. Now the client host can log in on remote_host as remote-user without typing the password, the authentication is done automatically under the hood.
Verify the correct execution of the command logging in to the remote host:
ssh remote-user@remote_host
no password should be asked.
The public key of the client can be upload to every user/host where you want to be authenticated without password.
The last step is to disable password authentication on remote_host. This is done editing /etc/ssh/sshd_config (as root user); the following lines must be present
PasswordAuthentication no
RSAAuthentication yes
PubkeyAuthentication yes
Then reload the ssh configuration
/etc/init.d/ssh reload
Verify that password authentication is disabled trying to log in from another client which has not setup public key authentication. The user should be refused, on my machine the message is:
Permission denied (publickey)

venerdì 15 ottobre 2010

giovedì 7 ottobre 2010

Caratteri speciali HTML

Tra l' & e il codice non ci va lo spazio.

Spazio = & nbsp;
" = & quot;
& = & amp;
< = & lt;
> = & gt;
© = & copy;
® = & reg;
´ = & acute;
« = & laquo;
» = & raquo;
¡ = & iexcl;
¿ = & iquest;
À = & Agrave;
à = & agrave;
Á = & Aacute;
á = & aacute;
 = & Acirc;
â = & acirc;
à = & Atilde;
ã = & atilde;
Ä = & Auml;
ä = & auml;
Å = & Aring;
å = & aring;
Æ = & AElig;
æ = & aelig;
Ç = & Ccedil;
ç = & ccedil;
Ð = & ETH;
ð = & eth;
È = & Egrave;
è = & egrave;
É = & Eacute;
é = & eacute;
Ê = & Ecirc;
ê = & ecirc;
Ë = & Euml;
ë = & euml;
Ì = & Igrave;
ì = & igrave;
Í = & Iacute;
í = & iacute;
Î = & Icirc;
î = & icirc;
Ï = & Iuml;
ï = & iuml;
Ñ = & Ntilde;
ñ = & ntilde;
Ò = & Ograve;
ò = & ograve;
Ó = & Oacute;
ó = & oacute;
Ô = & Ocirc;
ô = & ocirc;
Õ = & Otilde;
õ = & otilde;
Ö = & Ouml;
ö = & ouml;
Ø = & Oslash;
ø = & oslash;
Ù = & Ugrave;
ù = & ugrave;
Ú = & Uacute;
ú = & uacute;
Û = & Ucirc;
û = & ucirc;
Ü = & Uuml;
ü = & uuml;
Ý = & Yacute;
ý = & yacute;
ÿ = & yuml;
Þ = & THORN;
þ = & thorn;
ß = & szlig;
§ = & sect;
¶ = & para;
µ = & micro;
¦ = & brvbar;
± = & plusmn;
· = & middot;
¨ = & uml;
¸ = & cedil;
ª = & ordf;
º = & ordm;
¬ = & not;
_ = & shy;
¯ = & macr;
° = & deg;
¹ = & sup1;
² = & sup2;
³ = & sup3;
¼ = & frac14;
½ = & frac12;
¾ = & frac34;
× = & times;
÷ = & divide;
¢ = & cent;
£ = & pound;
¤ = & curren;
¥ = & yen;

martedì 5 ottobre 2010

How to show editable location bar in nautilus

From Ubuntu 10.04 the location bar is displayed by default in "breadcrumbs mode". Clicking on breadcrumbs buttons does not more switch the location bar in the edit mode.
This can be done using the shortcut CTRL+L (or from the menù Go > Location).
With ESC is possible to go back to the breadcrumbs mode.

Rar files support in Ubuntu's Archive Manager

By default Ubuntu's Archive Manager doesn't support opening files in rar format. The unrar package provides this functionality, it can be installed with the command

sudo apt-get install unrar