IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

BIRT Discussion :

[FAQ]Threader la classe générique de génération


Sujet :

BIRT

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Points : 111
    Points
    111
    Par défaut [FAQ]Threader la classe générique de génération
    Bonjour,

    Quelqu'un pourrait-il m'expliquer comment threader la classe générique de génération de rapports présente dans la FAQ ?
    Je n'ai pas envie de faire de bêtises

    Merci.

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Points : 111
    Points
    111
    Par défaut
    J'ai fais ceci. C'est peut-être pas super mais ça marche bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
     
    package utils;
     
    import java.io.File;
    import java.io.OutputStream;
    import java.util.Locale;
    import java.util.Map;
     
    import javax.servlet.http.HttpServletResponse;
     
    import org.eclipse.birt.core.exception.BirtException;
    import org.eclipse.birt.core.framework.Platform;
    import org.eclipse.birt.report.engine.api.EngineConfig;
    import org.eclipse.birt.report.engine.api.EngineException;
    import org.eclipse.birt.report.engine.api.HTMLRenderOption;
    import org.eclipse.birt.report.engine.api.IHTMLRenderOption;
    import org.eclipse.birt.report.engine.api.IRenderOption;
    import org.eclipse.birt.report.engine.api.IRenderTask;
    import org.eclipse.birt.report.engine.api.IReportDocument;
    import org.eclipse.birt.report.engine.api.IReportEngine;
    import org.eclipse.birt.report.engine.api.IReportEngineFactory;
    import org.eclipse.birt.report.engine.api.IReportRunnable;
    import org.eclipse.birt.report.engine.api.IRunTask;
    import org.eclipse.birt.report.engine.api.RenderOption;
     
    /**
     * Cette classe permet la génération dans n'importe quel format
     * de n'importe quelle édition.
     * Il faut d'abord l'instancier, puis l'initialiser et la lancer.
     * Si nécessaire, cette classe peut être threadée facilement.
     * 
     * @author BiM
     *
     */
    public final class Edition {
     
    	private static Edition m_Instance = null;
    	private IReportEngine engine;
    	private String realPath;
    	private IRenderOption option;
    	private IHTMLRenderOption optionHttp;
    	private String etat;
    	private String chemin;
    	private OutputStream httpResponse;
    	private Map<String, Object> parametres;
    	private String format;
    	private Locale langue;
     
    	private int encours = 0;
     
    	/**
             * Constructeur
             * Il configure le moteur BIRT de sorte à ce qu'il puisse retrouver
             * les ressources BIRT mais également les librairies le faisant tourner
             * Il est alors démarrer avec cette configuration.
             * @throws BirtException
             */
    	private Edition(String realpathParam) throws BirtException {
    		this.realPath = realpathParam;
    		EngineConfig config = new EngineConfig();
    		config.setResourcePath(new File(realPath, "WEB-INF/reports/ressources").getAbsolutePath());
    		config.setBIRTHome(new File(realPath, "WEB-INF/ReportEngine").getAbsolutePath());//endroit où se trouvent les librairies du Runtime
    		Platform.startup(config);
    		IReportEngineFactory factory = (IReportEngineFactory) Platform
    			.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
    		engine = factory.createReportEngine(config);
    		option = new RenderOption();
    		optionHttp = new HTMLRenderOption();
    	}
     
    	/**
             * Instanciation du service
             * @return l'instance en cours du service
             * @throws BirtException
             */
    	public static Edition getInstance(String realpathParam) throws BirtException {
    		if (m_Instance == null) {
    			m_Instance = new Edition(realpathParam);
    		}
    		return m_Instance;
    	}
     
    	/**
             * Initialisation
             * @param etat nom du rptdesign
             * @param chemin chemin et nom du fichier de sortie
             * @param httpResponse le flux de sortie en cas d'utilisation dans une servlet
             * @param parametres paramètres à passer à l'état
             * @param format format de sortie (PDF, XLS, DOC, etc.)
             * @param langue langue de l'édition
             */
    	synchronized public void init(String etat, String chemin,OutputStream httpResponse, Map<String, Object> parametres, String format, Locale langue) {
    		if(encours >0){//Inutile de faire le wait s'il n'y a qu'un seul thread
    			try {
    				wait();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    		this.etat = etat;
    		this.chemin = chemin;
    		this.httpResponse = httpResponse;
    		this.parametres = parametres;
    		this.format = format;
    		this.langue = langue;
    		encours++;
    	}
     
    	/**
             * Lancement de l'état
             */
    	synchronized public void run() {
    		try {
     
    			/* Récupération du rptDesign */
    			IReportRunnable design = engine.openReportDesign(new File(realPath, "WEB-INF/reports/etats/" + etat + ".rptdesign").getAbsolutePath());
     
    			/* Exécution */
    			IRunTask runTask = engine.createRunTask(design);
     
    			/* Paramètres */
    			if(parametres != null){
    				for (String clef : parametres.keySet()) {
    					runTask.setParameterValue(clef, parametres.get(clef));
    				}
    			}
     
    			/* Langue */
    			runTask.setLocale(langue);
     
    			runTask.run(chemin+".rptdocument");
     
    			/* Récupération du rptDocument */
    			IReportDocument doc = engine.openReportDocument(chemin+".rptdocument");
     
    			/* Rendu */
    			IRenderTask renderTask = engine.createRenderTask(doc);
     
    			if(httpResponse == null){
    				option.setOutputFileName(chemin);//Nom du fichier de sortie
    				renderTask.setRenderOption(option);//Chargement du fichier
    				option.setOutputFormat(format);//Format du fichier de sortie
    			}
    			else{
    				optionHttp.setOutputStream(httpResponse);//Le flux de sortie vers lequel diriger le fichier générer
    				renderTask.setRenderOption(optionHttp);//Chargement du fichier
    				optionHttp.setOutputFormat(format);//Format du fichier de sortie
    			}
     
     
     
     
    			renderTask.render();//Création du fichier /envoi du document vers le flux renseigné
     
     
    		}
    		catch (EngineException e) {
    			e.printStackTrace();
    		}
    		finally{
    			notifyAll();
    			encours--;
    		}
    	}
     
    	/**
             * Permet de détruire le moteur. Cette fonction n'est
             * jamais utilisée mais pourrait l'être à l'avenir.
             */
    	public void destructeur() {
    		engine.destroy();
    	}
    }


    Le seul truc à peut-être améliorer, c'est lorsque l'utilisateur sur le même navigateur veut générer deux rapports quasi simultanément, l'un étant plus long à construire que l'autre. Etant donné que c'est le même thread, le rapport renvoyé sera le plus rapide à construire. ça c'est normal et ça marche mais j'ai une exception de ce type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    ExceptionConverter: ClientAbortException:  java.net.SocketException: Software caused connection abort: socket write error
    	at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:358)
    	at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:434)
    	at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:293)
    	at org.apache.catalina.connector.OutputBuffer.writeByte(OutputBuffer.java:399)
    	at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:77)
    	at java.io.FilterOutputStream.write(Unknown Source)
    	at java.io.FilterOutputStream.write(Unknown Source)
    	at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
    	at java.io.BufferedOutputStream.write(Unknown Source)
    	at java.io.BufferedOutputStream.write(Unknown Source)
    	at com.lowagie.text.pdf.OutputStreamCounter.write(Unknown Source)
    	at java.io.ByteArrayOutputStream.writeTo(Unknown Source)
    	at com.lowagie.text.pdf.PdfStream.toPdf(Unknown Source)
    	at com.lowagie.text.pdf.PdfIndirectObject.writeTo(Unknown Source)
    	at com.lowagie.text.pdf.PdfWriter$PdfBody.add(Unknown Source)
    	at com.lowagie.text.pdf.PdfWriter$PdfBody.add(Unknown Source)
    	at com.lowagie.text.pdf.PdfWriter$PdfBody.add(Unknown Source)
    	at com.lowagie.text.pdf.PdfWriter.addToBody(Unknown Source)
    	at com.lowagie.text.pdf.TrueTypeFontUnicode.writeFont(Unknown Source)
    	at com.lowagie.text.pdf.FontDetails.writeFont(Unknown Source)
    	at com.lowagie.text.pdf.PdfWriter.addSharedObjectsToBody(Unknown Source)
    	at com.lowagie.text.pdf.PdfWriter.close(Unknown Source)
    	at com.lowagie.text.pdf.PdfDocument.close(Unknown Source)
    	at com.lowagie.text.Document.close(Unknown Source)
    	at org.eclipse.birt.report.engine.emitter.pdf.PDFPageDevice.close(PDFPageDevice.java:141)
    	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.end(PageDeviceRender.java:158)
    	at org.eclipse.birt.report.engine.emitter.pdf.PDFRender.end(PDFRender.java:121)
    	at org.eclipse.birt.report.engine.layout.emitter.PageEmitter.end(PageEmitter.java:61)
    	at org.eclipse.birt.report.engine.layout.pdf.emitter.PDFLayoutEmitter.end(PDFLayoutEmitter.java:100)
    	at org.eclipse.birt.report.engine.layout.pdf.emitter.WrappedPDFLayoutEmitter.end(WrappedPDFLayoutEmitter.java:69)
    	at org.eclipse.birt.report.engine.layout.pdf.emitter.PDFLayoutEmitterProxy.end(PDFLayoutEmitterProxy.java:218)
    	at org.eclipse.birt.report.engine.emitter.CompositeContentEmitter.end(CompositeContentEmitter.java:64)
    	at org.eclipse.birt.report.engine.api.impl.RenderTask$PageRangeRender.render(RenderTask.java:501)
    	at org.eclipse.birt.report.engine.api.impl.RenderTask.render(RenderTask.java:209)
    	at utils.Edition.run(Edition.java:153)
    	at servlets.BirtServlet.doGet(BirtServlet.java:35)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    	at java.lang.Thread.run(Unknown Source)
    Bien que cela n'entrave pas le fonctionnement du programme, j'aimerais éviter cette erreur mais comment faire ?

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Avril 2008
    Messages
    1 143
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 1 143
    Points : 1 353
    Points
    1 353
    Par défaut multi-thread
    Bah... vous avez 2 choix.

    1 : sémaphore.

    2 : vraie parallélisation


    1: en fonction de certains paramètres vous gérez la file d'attente du thread BIRT.

    2 : vous avez plusieurs instances de l'engine BIRT et vous achéminez les rapports en fonction de leur disponibilité.

  4. #4
    BiM
    BiM est déconnecté
    Expert éminent sénior
    Avatar de BiM
    Femme Profil pro
    Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT
    Inscrit en
    Janvier 2005
    Messages
    7 796
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT

    Informations forums :
    Inscription : Janvier 2005
    Messages : 7 796
    Points : 10 765
    Points
    10 765
    Par défaut
    En fait plus simplement, je conseille d'utiliser le mot clef synchronize quand on utilise BIRT. Ca permet d'éviter ce genre de conflit. Une seule génération peut être faite à la fois. Si vous voulez en faire plusieurs, il faut avoir plusieurs moteurs donc plusieurs dossiers Runtime. Parce que les dépendances de BIRT elles mêmes ne peuvent pas gérer les accès concurrentiels.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Points : 111
    Points
    111
    Par défaut
    donc ce que j'ai fais, c'était pas idiot

    Ne voulant pas de parallélisation pure mais seulement empecher que les différentes demandes se bouffent entre elles et les enchainer au fûr et à mesure, je pense que je vais rester comme ça.

  6. #6
    BiM
    BiM est déconnecté
    Expert éminent sénior
    Avatar de BiM
    Femme Profil pro
    Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT
    Inscrit en
    Janvier 2005
    Messages
    7 796
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultante/Formatrice BIRT & Ingénieur Java/J2EE/GWT

    Informations forums :
    Inscription : Janvier 2005
    Messages : 7 796
    Points : 10 765
    Points
    10 765
    Par défaut
    Ah oui pardon je n'avais pas vu.

    Par contre pour éviter l'attente du retour. Tu peux faire un traitement asynchrone. En gros, tu crées une classe avec une file d'attente. Tu ajoutes ton édition à la file d'attente (avec tous ses paramètres (langue, design à utiliser, paramètres, etc.)).

    Une fois que tu as ajouté ton édition à la file d'attente, un message est renvoyé à ton client. Et là, tu peux, par exemple, envoyer ton édition par mail quand elle est finie.

    Après, il existe de multiples solutions plus ou moins efficaces.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 160
    Points : 111
    Points
    111
    Par défaut
    Pas mal comme système, je vais regarder ça.

    Merci BiM !
    (à très bientôt pour une autre question^^)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 18/08/2011, 16h06
  2. Réponses: 15
    Dernier message: 27/02/2009, 10h59
  3. [C# 2.0] Un exemple de classe générique qui ne compile pas.
    Par Pierre8r dans le forum Windows Forms
    Réponses: 4
    Dernier message: 31/05/2006, 11h11
  4. [C#][ADO] Classe Générique ADO
    Par tscoops dans le forum Accès aux données
    Réponses: 2
    Dernier message: 15/11/2005, 14h21
  5. [Generics] Classe générique
    Par norkius dans le forum Langage
    Réponses: 4
    Dernier message: 29/10/2004, 15h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo