Rechercher

vendredi 4 février 2011

Debugger avec Maven

Une technique toute simple pour débugger un projet web avec maven 2, celui-ci nécessite tout de même que votre projet comporte le plugin tomcat ou jetty.

lien : http://blog.kadirpekel.com/2009/11/09/debugging-through-maven-tomcat-plugin-by-eclipse/

Pour résumé :

$YOUR_MVN_PRJ_HOME $> echo -e 'export MAVEN_OPTS="-Xdebug 
-Xnoagent -Djava.compiler=NONE 
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000"\nmvn $@' 
> mvn-debug
$YOUR_MVN_PRJ_HOME $> chmod +x mvn-debug
 puis .. 

$YOUR_MVN_PRJ_HOME $> ./mvn-debug tomcat:run
Ou si vous utilisez Jetty :
$YOUR_MVN_PRJ_HOME $> ./mvn-debug jetty:run

Ensuite vous n'avez plus qu'à y attacher votre débugger Eclipse !

mardi 4 janvier 2011

Hudson/Jenkins Tips !

Changer le port d'Hudson après une installation via RPM sur un linux :

En root éditez le $HTTP_PORT dans : /etc/sysconfig/hudson
ou maintenant avec Jenkins : /etc/sysconfig/jenkins

Stopper hudson :


Accédez au manager, puis ajoutez exit à votre chemin : http://jenkins_url/exit
Ceci mettra fin au service jenkins !

lundi 13 décembre 2010

Travailler avec plusieurs projets GWT sous Eclipse

Si vous voulez faire un projet partagé avec plusieurs autres, votre petite API quoi, vous devez forcément en GWT créer deux modules. C'est comme ça que sont faites toutes les apis du type gxt, mosaic, gwt-dnd ..
Voici un petit exemple pour créer deux projets gwt, l'un héritant de l'autre, puis l'upload sur App Engine :

1) Créez un Java Project classique, ce sera le projet "api". Ajoutez le sdk gwt depuis le plugin, puis créez votre module xxx.gwt.xml. Il n'a pas besoin d'entry-point car il n'a pas vocation à être directement intégré à une page html.
Vous pouvez maintenant placer vos widgets ou je ne sais quoi dans un package nommé client.


2) Créez maintenant votre projet à deployer sur app engine, je l’appellerais "app".
Il faut cette fois faire un nouveau projet Web Application, ajoutez lui les sdk gwt et appengine
Le module contenant votre entry-point devra hérité de "api"


Maintenant, c'est un peu ici le piège, le fait d'ajouter votre projet "api" en dépendance dans le build path de "app" fonctionne pour la compilation, mais vous aurez surement une erreur au run-time du type java.lang.NoClassDefFoundError, sur l'une de vos classes provenant de "api".
La technique est de ne pas mettre une dépendance du projet, mais ajouter le dossier "src" de "api" en tant que source de "app".


C'est peut-être optionnel, mais dans les debug configs, vous pouvez ajouter dans l'onglet "classpath" le projet "api" :


Vous pouvez donc maintenant utiliser depuis "app" les widgets et classes de "api", et ceci sans avoir à recompiler et inclure le jar dans les libs.

3) Faites un petit "Hello World" dans votre projet "app" qui utilise du code de votre second projet, et déployez le sur App Engine.
Si vous prenez un "[ERROR] Module has no entry points defined", c'est parce que le plugin va essayer de compiler votre le module "api", or votre "app" en hérite, ce qui est suffisant pour le compilateur.
Il vous faut enlever dans la configuration la compilation du module "api", pour ne garder seulement celui ou ceux de "app" :


Votre projet devrait maintenant compiler correctement et s'installer sur le cloud Google.

lundi 11 octobre 2010

Convertir un fax "image" en pdf "texte" via OCR

Pour un projet client, nous avons  besoin de convertir des fichiers .fax avec une technologie de type OCR afin de pouvoir lire et indexer ces fichiers par un serveur Google Search Appliance.

Après avoir regardé autour des API OCR, nous en avons trouvé des très performantes mais toutes sont payantes et assez onéreuses surtout que nous sommes en phase de test. J'ai réalisé un bout de code JAVA qui lit un fichier FAX ou TIFF, pour le transformer en PDF via l’excellente api iText.
Une fois ce PDF produit je l'upload vers le nuage grâce aux Google Documents List Data API v3.0 pour exploiter la conversion par OCR.
Puis enfin je télécharge le document produit sur mon disque local.
En espérant que cela puisse aider !


public class FaxToPdfToGoogle {

 // Fax To PDF 
 private final String fileToRead = "Document.fax"; // File to read
 private final String fileToExport = "DocumentToUpload.pdf"; // File produced to Google OCR
 private final Rectangle pageSize = PageSize.A4;  // PDF To Upload resolution, a high resolution result in com.google.gdata.util.InvalidEntryException: Could not convert document.

 // PDF To Google
 private final String googleUsername = ""; // Your email of google account
 private final String googlePassword = ""; // your password of google account
 private final String fileNameInGoogle = "DocumentTest-FaxToPdfOcr.pdf"; // File produced to Google OCR
 private final DocsService client = new DocsService("enterprise-FaxToPdf-v1"); // Set here what you want as applicationName
 
 // Google to HD
 private final String fileFinal = "DocumentFinal.pdf"; // File to read

 public FaxToPdfToGoogle() throws Exception {
  
  // ---------------------------------------------
  // --           Produce PDF From Fax          --
  // ---------------------------------------------
  
  File f = new File("./"+fileToExport);
  System.out.println("Doc exist : "+f.exists());
  createPDFFromTiff(f);
  System.out.println("Doc finished");
  

  // ---------------------------------------------
  // --      Upload PDF To Google OCR API       --
  // ---------------------------------------------
  
  System.out.println("Doc upload start");
//  if(!document.isOpen()){
   client.setUserCredentials(googleUsername, googlePassword);
   DocumentListEntry uploadedEntry = uploadFileGApi("./"+fileToExport, fileNameInGoogle);
   
   final String docId = uploadedEntry.getDocId();
   System.out.println("Document now online @ :" + docId);
   System.out.println("Doc upload finished ");
//  }
   

  // ---------------------------------------------
  // -- Download file converted doc from Google --
  // ---------------------------------------------

  System.out.println("Doc download start");
  if(downloadFileGApi("./"+fileFinal, docId))
   System.out.println("Doc download success");
  else 
   System.out.println("Doc download failed");
 }

 private void createPDFFromTiff(File pdf) throws DocumentException, IOException {
  if(!pdf.exists())
   System.out.println("Doc creation : "+pdf.createNewFile());
  
  Document document = new Document(pageSize,0,0,0,0);
  PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdf));
  
  System.out.println("Doc resolution : " + document.getPageSize().toString());
  
  document.open();
  PdfContentByte c = writer.getDirectContent();
  document.add(new Paragraph("Multipages tiff file"));
  
  System.out.println("Read "+fileToRead);
  
  RandomAccessFileOrArray ra = new RandomAccessFileOrArray(fileToRead);
  int pages = TiffImage.getNumberOfPages(ra);
  
  System.out.println("Nombre de pages "+pages);
  
  for(int i = 1; i <= pages; i++){
   Image img = TiffImage.getTiffImage(ra, i);
   img.setAbsolutePosition(0f,0f);
   img.scaleAbsolute(pageSize.getWidth(),pageSize.getHeight());
   c.addImage(img);
   c.getPdfDocument().newPage();
  }

  document.close();
 }

 private DocumentListEntry uploadFileGApi(String filepath, String title)throws IOException, ServiceException{
    File file = new File(filepath);
    System.out.println("Doc to upload exist " + file.exists());
    DocumentListEntry newDocument = new DocumentListEntry();
    String mimeType = DocumentListEntry.MediaType.fromFileName(file.getName()).getMimeType();
    newDocument.setFile(file, mimeType);
    newDocument.setTitle(new PlainTextConstruct(title));
    
    return client.insert(new URL("https://docs.google.com/feeds/default/private/full?ocr=true"), newDocument);
 }
 
 private boolean downloadFileGApi(String filepath, String resourceId) throws IOException, ServiceException{
  
  URL url = new URL("https://docs.google.com/feeds/default/private/full/" + resourceId);
  DocumentListEntry entry = client.getEntry(url, DocumentListEntry.class);

  if( entry != null ){
   
     MediaContent mc = (MediaContent) entry.getContent();
     String fileExtension = mc.getMimeType().getSubType();
     String exportUrl = mc.getUri();
 
     // PDF file cannot be exported in different formats.
     String requestedExtension = filepath.substring(filepath.lastIndexOf(".") + 1);
     if (!requestedExtension.equals(fileExtension)) {
       System.err.println("Warning: " + mc.getMimeType().getMediaType() +
           " cannot be downloaded as a " + requestedExtension + ". Using ." +
           fileExtension + " instead.");
       filepath = filepath.substring(0, filepath.lastIndexOf(".") + 1) + fileExtension;
     }
     downloadFile(exportUrl, filepath);
     return true;
  }
  else 
   return false;
 }
 
 public void downloadFile(String exportUrl, String filepath) throws IOException, MalformedURLException, ServiceException {
    System.out.println("Exporting document from: " + exportUrl);
  
    MediaContent mc = new MediaContent();
    mc.setUri(exportUrl);
    MediaSource ms = client.getMedia(mc);
  
    InputStream inStream = null;
    FileOutputStream outStream = null;
  
    try {
       inStream = ms.getInputStream();
       outStream = new FileOutputStream(filepath);
   
       int c;
       while ((c = inStream.read()) != -1) {
         outStream.write(c);
       }
    } finally {
       if (inStream != null) {
         inStream.close();
       }
       if (outStream != null) {
         outStream.flush();
         outStream.close();
       }
    }
 }
 
 public static void main(String[] args) {
  try{
   FaxToPdfToGoogle simpleImages = new FaxToPdfToGoogle();
  }catch(Exception e){
   System.out.println(e);
  }
 }
}


Voici la liste des api utilisées :

/FaxToPdf/lib/iText-5.0.4.jar
/FaxToPdf/lib/apache-mime4j-0.6.jar
/FaxToPdf/lib/commons-codec-1.3.jar
/FaxToPdf/lib/commons-logging-1.1.1.jar
/FaxToPdf/lib/httpclient-4.0.3.jar
/FaxToPdf/lib/httpcore-4.0.1.jar
/FaxToPdf/lib/httpcore-nio-4.0.1.jar
/FaxToPdf/lib/httpmime-4.0.3.jar
/FaxToPdf/lib/commons-httpclient-3.1.jar
/FaxToPdf/lib/gdata-core-1.0.jar
/FaxToPdf/lib/gdata-client-meta-1.0.jar
/FaxToPdf/lib/gdata-client-1.0.jar
/FaxToPdf/lib/gdata-media-1.0.jar
/FaxToPdf/lib/gdata-docs-meta-3.0.jar
/FaxToPdf/lib/gdata-docs-3.0.jar
/FaxToPdf/lib/guava-r07.jar
/FaxToPdf/lib/mail.jar

lundi 4 octobre 2010

Spring security - récupérer l'utilisateur courant coté serveur

Petit tips pour les débutants comme moi, les choses les plus simple ne sont pas forcément très expliqué !
Voici comment faire pour récupérer l'utilisateur courant coté serveur dans une application intégrée avec Spring-Security Framework.
Ceci permet de ne pas faire confiance aux données qui proviennent du coté client. Si cela peut aider quelqu'un :)


Par exemple dans une transaction hibernate :

final User loggedUser = getHibernateTemplate().execute(new HibernateCallback() {

@Override
public User doInHibernate(Session session) throws HibernateException, SQLException {
final String username = SecurityContextHolder.getContext().getAuthentication().getName();
return (User) session.get(User.class, username);
}

});

lundi 23 août 2010

Update houleux vers Fedora 12 Constantine

L'update de ma Fedora 11 à Fedora 12 Constantine, fait l'objet de mon premier post sur ce blog.
Cela aurait pût commencer mieux, car cette upgrade a mal tourné du fait que mon trop faible espace libre de mon /boot.
Voila donc quelques manipulations qui m'ont étaient très utiles !



Libérer de l'espace dans votre /boot !



Jusque ici, c'est le coup classique, pour y remédier, j'ai suivis la methode 1 "Not enough space in /boot and Free up space" de cet article.

La commande : "df -h /boot" vous permet de rapidement voir le taux de l'espace disque utilisé dans la partition /boot.
L'upgrade nécéssite environ 26Mo.
Si vous avez à faire un peu de place, une solution est de supprimer les versions du kernel anciennements installé mais plus utilisé par votre système.

Vous pouvez connaître les kernels inutiles qui peuvent être supprimé :
curl -O 'http://skvidal.fedorapeople.org/misc/kernel-prune.py'
chmod a+x kernel-prune.py
./kernel-prune.py


Puis les supprimer grâce à yum :

[root@xxx ~]# PKGS=`./kernel-prune.py`
[root@xxx ~]# echo $PKGS
[root@xxx ~]# yum remove $PKGS


Pour laisser propre et libérer encore un peu d'espace , utiliser cette commande (en root) pour voir quel partition contient votre /boot:
[root@xxx ~]# mount | grep "/boot"

Pour moi la réponse est : /dev/sda1 on /boot type ext3 (rw) , ma partition est donc "/dev/sda1"
Nous avons plus que a utiliser la commande "tune2fs" pour libérer des blocks mémoire aloués inutilement dans votre /boot.
[root@xxx ~]# tune2fs -r 0 /dev/sda1

Relancer "df -h /boot", si votre espace libre est supérieure a 26Mo, l'upgrade devrait fonctionner.



J'ai donc relancé "preupgrade", et une fois le téléchargement des paquets terminé, on me propose de rebooter.. , ben allez hein !
En temps normal vous devrez tomber sur Anaconda qui termine la mise à jour en installant les paquets.
Pour ma part, rien n'a était lancé et mon système a démarré comme si de rien n'était, sur mon ancien os.
J'ai donc voulu retenter ma chance, mais apartir de là "preupgrade" plantait, car mon système d'upgrade est bancale.
J'ai donc lancait la version en ligne de commandes, "preupgrade-cli" pour essayer de comprendre ce qui bloque.


[root@xxx ~]# preupgrade-cli "Fedora 12 (Constantine)"
/usr/lib/python2.6/site-packages/yum/__init__.py:203: UserWarning: Use .preconf instead of passing args to _getConfig
warnings.warn('Use .preconf instead of passing args to _getConfig')
Loaded plugins: blacklist, dellsysidplugin2, refresh-packagekit, whiteout
Loaded plugins: dellsysidplugin2, refresh-packagekit
preupgrade-main (mirrorlist)
url: http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-12&arch=$basearch
now: http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-12&arch=i386
preupgrade (mirrorlist)
url: http://mirrors.fedoraproject.org/mirrorlist?path=pub/fedora/linux/releases/12/Fedora/$basearch/os
now: http://mirrors.fedoraproject.org/mirrorlist?path=pub/fedora/linux/releases/12/Fedora/i386/os
preupgrade-google-chrome (baseurl)
url: http://dl.google.com/linux/rpm/stable/i386
now: http://dl.google.com/linux/rpm/stable/i386
[...]
url: https://mirrors.fedoraproject.org/metalink?repo=updates-released-f12&arch=i386
now: https://mirrors.fedoraproject.org/metalink?repo=updates-released-f12&arch=i386
Traceback (most recent call last):
File "/usr/share/preupgrade/preupgrade-cli.py", line 312, in
pu.main(myrelease)
File "/usr/share/preupgrade/preupgrade-cli.py", line 175, in main
self.setup(myrelease)
File "/usr/lib/python2.6/site-packages/preupgrade/__init__.py", line 130, in setup
self.complete_repo_setup()
File "/usr/lib/python2.6/site-packages/preupgrade/__init__.py", line 328, in complete_repo_setup
repo._grabfunc.opts.user_agent = __user_agent__
AttributeError: 'NoneType' object has no attribute 'opts'


Oops,celà ne fonctionne pas non plus. Après quelques recherches je trouve une super commande curative,
[root@xxx ~]# rm -rf /var/cache/yum/preupgrade*

Tadam .. ! Celle-ci vide le repertoire a moitié installer par preupgrade. Je retente ma chance.
[root@xxx ~]# preupgrade-cli "Fedora 12 (Constantine)"

Et ça fonctionne ! Après le téléchargement de quelques 1400 paquets, mon preupgrade a tout l'air d'avoir fonctionné. J'ai rebooté, Anaconda a prit le relais et commence l'installation. Voyant le temps que ça va prendre, j'ai décidé de faire un petit tour, et lors de mon retour .. bizarre, mon pc était éteind. Je l'ai rallumé pour voir dans quel état était il. Et là c'est le drame.., un kernel panic !!


RAMDISK: incomplete write (1337 != 5348)
write error
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)



J'assistai donc à mon premier kernel panic, c'est toujours plus sympas qu'un blue screen Windozien (toutes les leds de mon laptop clignotaient d=P ), surtout quand on arrive a s'en sortir. Alors j'ai sorti mon Live CD Fedora 12, mais cela doit fonctionner avec bien d'autres. Voici la marche à suivre.



Installation d'un kernel via un Live CD




Allez chercher sur internet le kernel actuel et gardait le sur votre disque dur, par exemple :
Kernel de la release:

http://download.fedora.redhat.com/pub/fedora/linux/releases/_version_/Fedora/_votre_build_/os/Packages/_kernel_xx_

Dernier kernel:

http://download.fedora.redhat.com/pub/fedora/linux/updates/_version_/Fedora/_votre_build_/os/Packages/_kernel_xx_


Il faut ensuite monter le dossier /boot de votre os dans le dossier /boot du live cd. Pour ça, il faut les reconnaîtres, pour ma part c'est :
/media/_boot : celui du live cd et
/media/Fedora-11-i686-Live : celui du mon os.
[root@xxx ~]#mount --move /media/_boot /media/Fedora-11-i686-Live/boot

On change ensuite les options de montage :
[root@xxx ~]#mount -o remount,suid,exec,dev /media/Fedora-11-i686-Live
[root@xxx ~]#mount -o remount,suid,exec,dev /media/Fedora-11-i686-Live/boot


On change ensuite le root directory de ce point de montage :
[root@xxx ~]#chroot /media/Fedora-11-i686-Live

Enfin on installe le kernel précédement téléchargé ( --force peut être nécéssaire si il nous signal qu' il est déjà installé ):
[root@xxx ~]#rpm -ivh kernel-xx.fc12.i686rpm –force

Redémarrer, et vous pouvez booter normalement !



Oouf ! Quelques mises à jour de quelques package et mon upgrade est fini !