giovedì 30 maggio 2013

Capire dal .class la java version

I compilati Java, con estensione .class, hanno una struttura iniziale che ci consente di capire con quale java version sono stati compilati.
Tutti i .class iniziano con la sequenza 0xCAFEBABE, detto magic number, il numero esadecimale che consente di capire il formato del file.
Sulla storia di questo magic number sono raccontate in rete storie divertenti, secondo Wikipedia inglese pare che tutto venga da un caffè frequentato dai Grateful Dead (http://en.wikipedia.org/wiki/Java_class_file).
Dopo il magic number c'è l'identificativo di versione major e minor.
I valori del major identificano la versione e sono i seguenti:
46 -> java 1.2
47-> java 1.3
48-> java 1.4
49-> java 1.5
50 -> java 1.6
51-> java 1.7

Di seguito incollo il testo di una classe Java che dato un file .class restituisce la versione Java.


package it.test;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
public class CheckCompiledVersion {
 static Map myMap=null;
 private static CheckCompiledVersion istanza;
 private CheckCompiledVersion(){
  
 }
 public static CheckCompiledVersion getInstance(){
  if(istanza==null){
   istanza=new CheckCompiledVersion();
  }
  return istanza;
 }
 static
 {

      myMap=new HashMap();
      myMap.put(46, "Java 1.2");
      myMap.put(47, "Java 1.3");
      myMap.put(48, "Java 1.4");
      myMap.put(49, "Java 1.5");
      myMap.put(50, "Java 1.6");
      myMap.put(51, "Java 1.7");
 }
 public static void main(String[] args) throws IOException {
  System.out.println(CheckCompiledVersion.getInstance().checkClassVersion("out/Myfile.class"));
 }

 public String checkClassVersion(String filename)
         throws IOException
     {
         DataInputStream in = new DataInputStream(new FileInputStream(filename));
         int magic = in.readInt();
         if(magic != 0xcafebabe) {
           return filename + " non è un .class";
         }
         int minor = in.readUnsignedShort();
         int major = in.readUnsignedShort();
         System.out.println(filename + ": " + major + " . " + minor);
         in.close();
         return myMap.get(major);
     }
}


sabato 18 maggio 2013

UDDI

L'UDDI (acronimo di Universal Description Discovery and Integration) è un registry (ovvero una base dati ordinata e indicizzata), basato su XML e indipendente dalla piattaforma hardware, che permette alle aziende la pubblicazione dei propri dati e dei servizi offerti su internet. (cit. wikipedia)

  UDDI include un  XML Schema che descrive 4 tipi di informazioni principali:
  • businessEntity (include informazioni sul business name,la descrizione etc);
  • businessService (include informazioni sui web service)
  • bindingTemplate (include informazioni su come e dove accedere il web service)
  • tModel (Technical model, include descrizioni o puntatori a specifiche tecniche esterne oppure a tassonomie).
UDDI può avere come identificativo di un servizio un numero detto Dun & Bradstreet D-U-N-S® Number, un numero di nove cifre codificato secondo un certo standard (vedi qui ).

 Vediamo degli esempi:

businessEntity



<businessEntity
businessKey="0076b468-eb27-42e5-ac09-9955cff462a3"
operator="Microsoft Corporation" authorizedName="Martin Kohlleppel">
<name>Microsoft Corporation</name>
<description xml:lang="en">Empowering people through great software
- any time, any place and on any device is Microsoft's vision. As the
worldwide leader in software for personal and business computing, we
strive to produce innovative products and services that meet our
customer's...
</description>
<contacts>
<contact useType="Corporate Addresses and telephone">
<description xml:lang="en">Corporate Mailing Addresses</
description>
<personName />
<phone useType="Corporate Headquarters">(425) 882-8080</phone>
<address sortCode="~" useType="Corporate Headquarters">
<addressLine>Microsoft Corporation</addressLine>
<addressLine>One Microsoft Way</addressLine>
<addressLine>Redmond, WA 98052-6399</addressLine>
<addressLine>USA</addressLine>
</address>
</contact>
<contact useType="Technical Contact - Corporate UD">
<description xml:lang="en">World Wide Operations</description>
<personName>Martin Kohlleppel</personName>
<email>martink@microsoft.com</email>
</contact>
</contacts>
<identifierBag>
<keyedReference
tModelKey="uuid:8609c81e-ee1f-4d5a-b202-3eb13ad01823"
keyName="D-U-N-S" keyValue="08-146-6849" />
</identifierBag>
<categoryBag>
<keyedReference
tModelKey="uuid:c0b9fe13-179f-413d-8a5b-5004db8e5bb2"
keyName="NAICS: Software Publisher" keyValue="51121" />
</categoryBag>
</businessEntity>


business service / binding Template


<businessService
serviceKey="d5921160-3e16-11d5-98bf-002035229c64"
businessKey="ba744ed0-3aaf-11d5-80dc-002035229c64">
<name>XMethods Delayed Stock Quotes</name>
<description xml:lang="en">20-minute delayed stock quotes</description>
<bindingTemplates>
<bindingTemplate
serviceKey="d5921160-3e16-11d5-98bf-002035229c64"
bindingKey="d594a970-3e16-11d5-98bf-002035229c64">
<description xml:lang="en">
SOAP binding for delayed stock quotes service
</description>
<accessPoint URLType="http">
http://services.xmethods.net:80/soap
</accessPoint>
<tModelInstanceDetails>
<tModelInstanceInfo
tModelKey="uuid:0e727db0-3e14-11d5-98bf-002035229c64" />
</tModelInstanceDetails>
</bindingTemplate>
</bindingTemplates>
</businessService>


tModel 


<tModel
tModelKey="uuid:0e727db0-3e14-11d5-98bf-002035229c64"
operator="www.ibm.com/services/uddi" authorizedName="0100001QS1">
<name>XMethods Simple Stock Quote</name>
<description xml:lang="en">Simple stock quote interface</description>
<overviewDoc>
<description xml:lang="en">wsdl link</description>
<overviewURL>
www.it-ebooks.info
Web Services Essentials
144
http://www.xmethods.net/tmodels/SimpleStockQuote.wsdl
</overviewURL>
</overviewDoc>
<categoryBag>
<keyedReference
tModelKey="uuid:c1acf26d-9672-4404-9d70-39b756e62ab4"
keyName="uddi-org:types" keyValue="wsdlSpec" />
</categoryBag>
</tModel>


Quindi esiste una API per interfacciare UDDI che si divide in 2 macro aree:
  • Inquiry API;
  • Publisher API.
La prima per ricercare servizi UDDI e la seconda invece per pubblicarli o aggiornarli o rimuoverli.
Questa API è basata su SOAP e comprende una serie di funzioni, essitono quindi librerie declinate nel linguaggio di specifico interesse che consentono di effettuare le chiamate al registro UDDI.

Inquiry API

find_binding cerca bindings associati ad uno specifico servizio
find_business cerca un tipo di business che rispetti il criterio specificato
find_service cerca i servizi associati a quello specifico business
find_tModel cerca i technical model che rispettano il criterio specificato
get_bindingDetail per ottenere un completo binding detail
get_businessDetail per ottenere un completo record di una businessEntity
get_serviceDetail per ottenere un completo record di un servizio
get_tModelDetail per ottenere un completo record di un tmodel

Publishing API

get_authToken : richiede un token di autenticazione. Il token verrà richiesto anche per tutte le successive invocazioni
discard_authToken: invalida il token
save_binding Inserisce o aggiorna un bindingTemplate record.
save_business Inserisce o aggiorna un businessEntity record.
save_service Inserisce o aggiorna un businessService record.
save_tModel Inserisce o aggiorna un tModel record.
delete_binding Cancella il  bindingTemplate record specificato dalla bindingKey.
delete_business Cancella il businessEntity record specificato dallabusinessKey.
delete_service Cancella il  businessService record specificagto dalla serviceKey.
delete_tModel nasconde il tModel record specificato dalla tModelKey (non si possono cancellare tModel)



mercoledì 15 maggio 2013

PrimeFaces gestire messaggi di tipo p:growl e p:messages

Dalla versione 3.3 di prime faces è possibile condizionare la comparsa di messaggi in formato tradizionale (p:messages) oppure a scomparsa temporale (p:growl).
Nel mio caso avevo il seguente scenario.
Un form con un p:messages dichiarato e al suo interno un p:dialog.
Quando si verificava un errore di validazione nel p:dialog doveva comparirmi un p:message (interno al dialog) più a livello di pagina un p:growl (per comodità dell'utente).
Quindi non doveva essere visibile il p:messages standard della pagina che doveva gestire casistiche di errore relative al form e non al dialog.
Nel p:dialog ho definito il p:message interno così:


<p:messages  for="erroreFascicolo"  showDetail="true" autoUpdate="true" closable="true" escape="false" />  


Nel caso di errore di validazione lato java inserisco l'errore in questo modo:

FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR,"errore di validazione","");
FacesContext.getCurrentInstance().addMessage("erroreFascicolo", msg);


Sulla pagina invece ho definito i miei messaggi così:

<p:messages id="messages" globalOnly="true" showDetail="true" autoUpdate="true" closable="true" />  
<p:growl id="growl" for="erroreFascicolo" showDetail="true" autoUpdate="true" escape="false" life="15000"/>

L'attributo globalOnly="true" (di default è pari a false) significa che quel messaggio sarà visualizzato solo nel caso di messaggi aggiunti al contesto jsf senza id.
Quindi tutti i messaggi aggiunti genericamente sono gestiti dal p:messages mentre il p:growl si gestisce soltanto gli errori con id "erroreFascicolo".

martedì 14 maggio 2013

Problemi installazione Tomcat 7 come servizio su Windows 7 (64 bit)

Installando Tomcat 7 come servizio nella consueta maniera (utilizzando il service.bat) avevo il seguente errore allo start up del servizio:

"Windows could not start the Crowd (Apache Tomcat) on Local Computer. For more information, review the System Event Log. If this is a non-Microsoft service, contact the service vendor, and refer to service-specific error code 0."

Ho provato a seguire le istruzione contenute qui ma non sono riuscito a farlo funzionare.
Allora ho confrontato il servizio con un servizio a 32 bit già installato, utilizzando la modalità vista qui

Ho notato che mancavano i seguenti parametri sul tab Java:

Java Virtual Machine

Java ClassPath

Ho quindi inserito a mano sulla console del servizio i parametri:

Java Virtual Machine: C:\Program Files\Java\jdk1.6.0_20\jre\bin\server\jvm.dll
Java Classpath:  D:\apache-tomcat-7.0.39\bin\bootstrap.jar;D:\apache-tomcat-7.0.39\bin\tomcat-juli.jar;D:\apache-tomcat-7.0.39\bin\tomcat-juli.jar

Come nell'immagine sottostante


A questo punto il servizio è ripartito correttamente.

domenica 12 maggio 2013

sabato 11 maggio 2013

Web service REST, non ereditarietà annotation

Nei servizi Web di tipo REST le annotazioni della superclasse valgono nella sottoclasse soltanto se quest'ultima a sua volta non ha annotazioni.
Quindi in questo caso:


public interface Itest
{
@GET@Produces("application/atom+xml")
int mioMetodo();
}
@Path("qwqwqw")
public class MyService implemets Itest
{
@Produces("application/atom+xml")
public int mioMetodo()
{
....
}

}


Le due annotazioni @GET e @Produces dell'interfaccia Itest non sono ereditate dalla classe implementante.