https://bz.apache.org/bugzilla/show_bug.cgi?id=60940

            Bug ID: 60940
           Summary: "unpackWARs=false" causes different behavior of
                    classloader
           Product: Tomcat 8
           Version: 8.0.42
          Hardware: PC
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: vw_aluc...@t-online.de
  Target Milestone: ----

Hi all,

when I try to run my JSF 2.2 application which uses Richfaces on a Tomcat 8
with "unpackWARs=false" some parts of Richfaces/JSF will not be loaded during
startup. This is caused by a different behavior of the classloader when the app
cannot be unpacked by the server. 

During JSF startup is searches for all Jar files which include a "META-INF/"
folder. This is done by calling getResources("META-INF/") on the classloader.
In all found resources it searches for taglibs and faces config extensions. The
problem now is, that the calssloader returns a different number of resources
when the app is unpacked and when the app is deployed a zip file. 

This is caused by a the way the classloader deals with JarWarRessources. When
the app is unpacked the server uses direct jar file access und searches in the
zip file for the folder. In this case every jar with a "META-INF/" folder is
found. When the app is a war file which cannot be unpacked by the server the
"JarWarRessourceSet" uses a "JarInputStream" to read and cache the jar files
content. But this input stream skips the "META-INF/" folder by default:

JarFileInputStream.java

...

    public JarInputStream(InputStream in, boolean verify) throws IOException {
        super(in);
        this.doVerify = verify;

        // This implementation assumes the META-INF/MANIFEST.MF entry
        // should be either the first or the second entry (when preceded
        // by the dir META-INF/). It skips the META-INF/ and then
        // "consumes" the MANIFEST.MF to initialize the Manifest object.
        JarEntry e = (JarEntry)super.getNextEntry();
        if (e != null && e.getName().equalsIgnoreCase("META-INF/"))
            e = (JarEntry)super.getNextEntry();
        first = checkManifest(e);
    }

... 

This will cause the issues with the app because some parts(taglibs and faces
config extensions) cannot be loaded. 

You can reproduce the issue with the richfaces sample project which can be
generated via maven:

mvn archetype:generate -DarchetypeGroupId=org.richfaces.archetypes
-DarchetypeArtifactId=richfaces-archetype-simpleapp
-DarchetypeVersion=4.5.17.Final -DgroupId=org.docs.richfaces
-DartifactId=new_project

Replace the sample projects pom by this one (sorry I'm not able to upload files
from this workstation):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd";>

    <modelVersion>4.0.0</modelVersion>

    <groupId>org.docs.richfaces</groupId>
    <artifactId>new_project</artifactId>
    <name>RichFaces 4 Application</name>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <url>http://jboss.org/richfaces</url>

    <repositories>
        <!-- You should seriously consider using a repository manager or
declare repositories in your settings.xml.
        See
http://www.sonatype.com/people/2009/02/why-putting-repositories-in-your-poms-is-a-bad-idea/
  -->
        <repository>
            <id>jboss-public-repository-group</id>
            <name>JBoss Public Maven Repository Group</name>
           
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
            <layout>default</layout>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </releases>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>jboss-public-repository-group</id>
            <name>JBoss Public Maven Repository Group</name>
           
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
            <layout>default</layout>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </releases>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.6</maven.compiler.source>
        <maven.compiler.target>1.6</maven.compiler.target>
        <!-- Setting this property using archetype-metadata.xml
requiredPorperty
            so that generated project uses correct version of richfaces.
        -->
        <org.richfaces.version>4.5.17.Final</org.richfaces.version>
        <version.jsp-api>2.1</version.jsp-api>
        <version.jstl-api>1.2</version.jstl-api>
        <version.servlet-api>3.0.1</version.servlet-api>
        <version.el-api>2.2</version.el-api>
    </properties>

    <build>
        <finalName>new_project</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <warName>${project.artifactId}</warName>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.richfaces</groupId>
                <artifactId>richfaces-cache-bom</artifactId>
                <type>pom</type>
                <version>${org.richfaces.version}</version>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.richfaces</groupId>
                <artifactId>richfaces-build</artifactId>
                <type>pom</type>
                <version>${org.richfaces.version}</version>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.richfaces</groupId>
            <artifactId>richfaces</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.faces</groupId>
            <artifactId>javax.faces-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.faces</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${version.servlet-api}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>el-api</artifactId>
            <version>${version.el-api}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
        </dependency>


        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>jee6</id>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-war-plugin</artifactId>
                        <configuration>
                           
<webappDirectory>${project.build.directory}/${project.build.finalName}-jee6</webappDirectory>
                            <classifier>jee6</classifier>
                        </configuration>
                    </plugin>
                </plugins>
            </build>

            <dependencies>
                <dependency>
                    <groupId>javax.faces</groupId>
                    <artifactId>javax.faces-api</artifactId>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>org.glassfish</groupId>
                    <artifactId>javax.faces</artifactId>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>javax.transaction</groupId>
                    <artifactId>jta</artifactId>
                    <version>1.1</version>
                    <scope>provided</scope>
                </dependency>
            </dependencies>
        </profile>
        <profile>
            <id>release</id>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-war-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>jee6</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>war</goal>
                                </goals>

                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>


Set " <Host appBase="webapps" autoDeploy="false" name="localhost"
unpackWARs="false">" in the server.xml of the tomcat. 

1) copy the applications war file to the webapps folder and start the tomcat.
When accessing the index.xhtml you can see that richfaces is not loaded
correctly. 

2) copy a the unzipped war file to the webapps folder an start the server.When
accessing the index.xhtml you can see that richfaces is loaded correctly. 

To make the difference more clear you can add a "<a4j:log/>" to the
index.xhtml. 

Regards,
Vincent

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to