HOAB

History of a bug

Java ne fonctionne pas avec Firefox

Rédigé par gorki Aucun commentaire

Le problème :

Un plugin Java obsolète, désinstallation, réinstallation, pas de java dans le navigateur.

Solution :

Réponse rapide : si vous avez un Java 64 bits, alors il vous faut un Firefox 64 bits, sinon la solution conseillée est d'installer une JRE 32 bits.

Désinstallation de plugin :

  1. désintaller le programme associé (Java, flash, VLC, etc...)
  2. savoir où est le plugin :  about:plugins dans la barre d'adresse de Firefox
  3. les plugins peuvent être
    • dans le répertoire plugins de Firefox : <home firefox>/plugins
    • inscrits dans la base de registre :
      • HKEY_CURRENT_USER\Software\MozillaPlugins (32 bits)
      • HKEY_LOCAL_MACHINE\SOFTWARE\MozillaPlugins (32 bits)
      • HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MozillaPlugins (64 bits)

Comme les plugins sont des DLLs intégrées dans Firefox, il semble donc qu'un programme 32 bits ne peut pas charger des DLL 64 bits (confirmé ici , Quote:

"While running a fully 64-bit Windows system sounds great,
the reality is that you'll very likely need to run Win32
code for a while. Towards that end, x64 versions of Windows
include the WOW64 subsystem that lets Win32 and Win64
processes run side-by-side on the same system. However,
loading your 32-bit DLL into a 64-bit process, or vice
versa, isn't supported."
)

@EJB @Asynchronous ExceptionExecution

Rédigé par gorki Aucun commentaire

Le problème :

La récupération des résultats des EJB asynchrone.

La technique de base pour déclencher un traitement asynchrone :

  1. créer une méthode taggué "@Asynchronous", la méthode retourne un Future<?>
  2. l'appeler
  3. attendre le retour

Souvent, on déclenche X fois la méthode, le tout passe dans une boucle :

  1. Pour toutes les tâches
    1. créer une méthode taggué "@Asynchronous", la méthode retourne un Future<?>
    2. l'appeler
    3. stocker le Future
  2. attendre que tous les Futures soit terminés
  3. récupérer les résultats

On part du principe que la méthode asynchone gère correctement ses erreurs à son niveau (un try/catch Exception avec un retour Future correct).

Seulement, certaines exceptions peuvent être remontées par le container : transaction timeout, erreur lors du commit, etc... sous forme d'ExecutionException. Et là, si le code est mal fait, on peut avoir des surprises et ne pas savoir dire ce qui s'est passé exactement

Solution :

Il faut donc penser lors de la récupération des résultats à :

  1. prévoir un try/catch d'ExecutionException / CancellationException / InterruptedException pour les Future.get()
  2. bien le mettre PAR Future, puisque chaque Future.get() va pouvoir lancer sa propre exception. (Certaines tâches peuvent provoquer une erreur au commit et pas d'autre)
  3. gérer un état global de récupération du résultat (est-ce que le code est correct si seulement une partie des tâches ont réussi ?)
  4. la gestion de traces et d'erreurs associés pour permettre de retrouver les tâches en erreur.

Exemple :

  • ici, le résultat est retourné dans une map
  • sinon le bean lui-même est retourné avec l'exception, il contient des maps pour stocker les erreurs et les futures
  • la gestion de traces et d'erreur est faite par l'appelant, les informations nécessaires pour décrire le contexte métier du Future sont dans un bean "FutureDescription"
// Attributs : 
private Map<Future<R>, FutureDescription> futures = new ConcurrentHashMap<Future<R>, FutureDescription>();
private Map<Future<R>, Exception> futureException = new ConcurrentHashMap<Future<R>, Exception>();

...

public Map<Future<R>, R> extractResultsMap(boolean throwException) throws MultiThreadException {

Map<Future<R>, R> results = new HashMap<Future<R>, R>();

// parcours de chaque Future pour récupérer son résultat d'exécution
for (Future<R> future : futures.keySet()) {
   try {
         results.put(future, future.get());
   } catch (InterruptedException | ExecutionException e) {
         futureException.put(future, e);
   }
}
if (throwException && (futureException.size() > 0)) {
    throw new MultiThreadException(ErrorCode.TECHNICAL_GLOBAL, "Erreur pendant la recuperation des resultats", this);
}
return results;

}

 

 

Couplés avec :

  • une classe qui fait du monitor pour tracer l'avancement des threads
  • une classe qui stocke les Future, leur résultats, leurs exceptions
  • des méthodes utilitaires

Cela donne les outils nécessaire pour gérer facilement l'asynchronisme.

@EJB @Singleton et ConcurrencyManagement

Rédigé par gorki Aucun commentaire

Le problème :

Un EJB singleton qui sert de cache remonte une erreur avec JBoss 7.1.1 :

EJB Invocation failed on component XXXX for method public java.lang.Object:
javax.ejb.EJBTransactionRolledbackException: JBAS014373: EJB 3.1 PFD2 4.8.5.5.1
concurrent access timeout on org.jboss.invocation.InterceptorContext$Invocation@398e7b17 
- could not obtain lock within 5000MILLISECONDS

Solution :

Tout est déjà écrit bien sur, encore aurait-il fallu le lire :)
Par défaut les EJB @Singleton sont

  1. @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)

  2. protégés par un @Lock(LockType.WRITE)

donc les méthodes sont synchronisés par le container. On peut

  • soit passer la méthode ou la classe en LockType.READ,
  • soit passer en Bean-managed (@ConcurrencyManagement(ConcurrencyManagementType.BEAN)). Là c'est vous qui gérer le tout.

Pour reproduire systématiquement, il suffit de mettre un sleep de 6s dans la méthode problématique.

Note:

  • Si le pool des ejb n'est pas assez grand on a un permit timeout et non un concurrent ascess timeout.
  • Le timeout sous JBoss est configuré dans cette section très intéressante :
<subsystem xmlns="urn:jboss:domain:ejb3:1.2">
            <session-bean>
                <stateless>
                    <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
                </stateless>
                <stateful default-access-timeout="5000" cache-ref="simple"/>
                <singleton default-access-timeout="5000"/>
            </session-bean>
            <pools>
                <bean-instance-pools>
                    <strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
                    <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
                </bean-instance-pools>
            </pools>
            <caches>
                <cache name="simple" aliases="NoPassivationCache"/>
                <cache name="passivating" passivation-store-ref="file" aliases="SimpleStatefulCache"/>
            </caches>
            <passivation-stores>
                <file-passivation-store name="file"/>
            </passivation-stores>
            <async thread-pool-name="default"/>
            <timer-service thread-pool-name="default">
                <data-store path="timer-service-data" relative-to="jboss.server.data.dir"/>
            </timer-service>
            <remote connector-ref="remoting-connector" thread-pool-name="default"/>
            <thread-pools>
                <thread-pool name="default">
                    <max-threads count="10"/>
                    <keepalive-time time="100" unit="milliseconds"/>
                </thread-pool>
            </thread-pools>
        </subsystem>

 

 

Fil RSS des articles de ce mot clé