Posté le par Olivier | Lien permanent | Commentaires | Posté dans Uncategorized


Je travaille avec des applicatifs java possédant deux arborescences distinctes :

  • le répertoire de la webapp contenant le cœur de l'applicatif : web.xml, context spring, jsp, images, css, ...
  • un répertoire avec des jsp générées par un CMS

La solution précédente mettait en œuvre des symlink entre ces deux répertoires pour qu'un Tomcat puisse servir l'ensemble des jsp. N'aimant pas beaucoup cette solution (nombreux symblink, problème sous windows, dans quel sens faire le symlink ?, ...) , je me suis mis à la recherche d'une solution plus élégante.

Avec Tomcat, on peut spécifier seulement un seul docBase par context, c'est un peu limitatif. Apache permet de faire des AliasMatch, Alias, ...

Voici un fichier classique de configuration Tomcat : conf/server.xml

    <Host name="myhost" appBase="NO_WEBAPPS">
        <Context path="" allowLinking="true" docBase="/path/to/my/webapp" override="true" reloadable="false">
          </Context>
    </Host>

L'idée est de créer une extension à Tomcat, la technique consiste à ajouter des docbases supplémentaires.

Dans l'idéal, le fichier conf/server.xml serait de la forme :

<Host name="myhost" appBase="NO_WEBAPPS">
    <Context path="" allowLinking="true" docBase="/path/to/my/webapp" override="true" reloadable="false">
        <Resources className="com.xxx.xxx.MultipleDirContext" virtualDocBase="/path/to/another/docbase" />
    </Context> 
</Host>

Cette configuration permet d'ajouter un ou des docbases supplémentaires en plus de celui défini. En fait, contrairement à ce que je pouvais penser au départ, cette idée est assez facile en mettre en place. Il suffit de créer une classe MultipleDirContext héritant d'une classe tomcat FileDirContext.

/**
 * Add some DocBase in tomcat. VirtualDocBase separator is ';'. 
 */
public class MultipleDirContext extends FileDirContext {    
  private String seperator = ";";
  private String virtualDocBase;
  private LinkedHashSet<FileDirContextAdapter> virtualContexts = new LinkedHashSet<FileDirContextAdapter>();
  public MultipleDirContext() {
    super();
  } 
  public MultipleDirContext(Hashtable env) {
    super(env); 
  }
  public void setVirtualDocBase(String virtualDocBase) {
      this.virtualDocBase = virtualDocBase;
      StringTokenizer parser = new StringTokenizer(virtualDocBase, ",");
      while (parser.hasMoreTokens()) {
          FileDirContextAdapter currentContext = new FileDirContextAdapter();
          currentContext.setDocBase(parser.nextToken());
          virtualContexts.add(currentContext); 
     }
  }
  public String getVirtualDocBase() { 
     return virtualDocBase; 
  }  
  public String getSeperator() {
      return seperator;  
  }
  public void setSeperator(String seperator) {
    this.seperator = seperator;
  }
  protected File file(String arg0) {
    File file = super.file(arg0);
    if (file == null) {
        for (FileDirContextAdapter virtualContext : virtualContexts) {
          file = virtualContext.file(arg0);
          if (file != null) {
            return file;
          }
       }
    }
     return file;
  }

  public void setDocBase(String arg0) {
    super.setDocBase(arg0); 
 }
  public void release() {
    super.release();        
    for (FileDirContextAdapter virtualContext : virtualContexts) {
      virtualContext.release();
    }
  }
  public void allocate() {
    super.allocate();
    for (FileDirContextAdapter virtualContext : virtualContexts) {
      virtualContext.setCached(this.isCached());
      virtualContext.setCacheTTL(this.getCacheTTL());
      virtualContext.setCacheMaxSize(this.getCacheMaxSize());
      virtualContext.setCaseSensitive(this.isCaseSensitive());
      virtualContext.setAllowLinking(this.getAllowLinking());
      virtualContext.allocate();
    }
  }
}


public class FileDirContextAdapter extends FileDirContext {
  public FileDirContextAdapter() {
  }
  public FileDirContextAdapter(Hashtable env) {
    super(env);
  }
  protected File file(String arg0) {
    return super.file(arg0);
  }
}



Avec cette extension, si la ressource n'est pas trouvée dans le docbase par défaut, on itère sur les docbases supplémentaires. Une fois le MultipleDirContext.jar créé, le placer dans apache-tomcat-6.0.14/lib. Cette technique dévrait fonctionner avec tomcat 5.5.x, mais je n'ai pas testé, je travaille que sur tomcat 6 :)

Cette technique est utilisée en production depuis plus d'un an, sans overhead, sur ces sites publiques à fort trafic.

Qu'en pensez vous ?


Posté le par Olivier | Lien permanent | Commentaires | Posté dans Uncategorized

Taggé avec:


Articles similaires

How to create Oracle function (trunc, decode, ...) in H2 ?
Mapper un arbre III
Drivers Oracle et Maven
Mapper un arbre II
Mapper un arbre I

Commentaires

blog comments powered by Disqus