Hi Team ,

We planned to upgrade both guacamole and apache tomcat from 1.5.2 and
9.75.0 to 1.5.3 and 10.1.13 respectively , then came to know that there is
a significant change  from Tomcat 9.0.x and Tomcat 10.0.x. The Java package
used by the specification APIs has changed from javax to jakarta.
The problem arises here in guacamole where it still uses Javax servlets and
other libraries which only support javax.

*What we tried :-*
We tried to migrate Guacamole using the  Apache Tomcat migration tool for
Jakarta EE <https://tomcat.apache.org/download-migration.cgi> , moreover
made changes in pom.xml and web.xml files in guacamole.war files to make
the guacamole compatible with Jakarta. But still the errors occur due to
mismatch in the configurations with Tomcat Jakarta Servlets and Guacamole.

*Errors we got:*

   1. java.lang.NoClassDefFoundError:javax/servlet/ServletContextListener
   2. java.lang.NoSuchMethodError: 'void
   jakarta.servlet.http.HttpServletResponse.setStatus(int, java.lang.String)'
   at
   
org.glassfish.jersey.servlet.internal.ResponseWriter.writeResponseStatusAndHeaders(ResponseWriter.java:147)

Were able to fix the first error after making changes in pom.xml and using
the tomcat migration tool for Jakarta,but the second error still exists
even after we changed the versions of all including *jersey server and
client*.

pom.xml and web.xml files are attached for reference.
<?xml version="1.0" encoding="UTF-8"?>
<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
-->
<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/maven-v4_0_0.xsd";>

    <modelVersion>4.0.0</modelVersion>
    <groupId>org.apache.guacamole</groupId>
    <artifactId>guacamole</artifactId>
    <packaging>war</packaging>
    <version>1.5.3</version>
    <name>guacamole</name>
    <url>http://guacamole.apache.org/</url>

    <parent>
        <groupId>org.apache.guacamole</groupId>
        <artifactId>guacamole-client</artifactId>
        <version>1.5.3</version>
        <relativePath>../</relativePath>
    </parent>

    <description>
        The Guacamole web application, providing authentication and an HTML5
        remote desktop client.
    </description>

    <!-- All applicable licenses -->
    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
        </license>
    </licenses>

    <!-- Git repository -->
    <scm>
        <url>https://github.com/apache/guacamole-client</url>
        <connection>scm:git:https://git.wip-us.apache.org/repos/asf/guacamole-client.git</connection>
    </scm>

    <build>
        <plugins>

            <!-- Build AngularJS portion of application using NPM -->
            <plugin>
                <groupId>com.github.eirslett</groupId>
                <artifactId>frontend-maven-plugin</artifactId>
                <version>1.11.3</version>
                <configuration>
                    <workingDirectory>src/main/frontend</workingDirectory>
                    <installDirectory>${project.build.directory}</installDirectory>
                </configuration>
                <executions>
                    <execution>
                        <id>install-node-and-npm</id>
                        <goals>
                            <goal>install-node-and-npm</goal>
                        </goals>
                        <configuration>
                            <nodeVersion>v14.16.0</nodeVersion>
                        </configuration>
                    </execution>
                    <execution>
                        <id>npm-ci</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <configuration>
                            <arguments>ci</arguments>
                        </configuration>
                    </execution>
                    <execution>
                        <id>npm-build</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <configuration>
                            <arguments>run build</arguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- Copy automatically-generated set of NPM module dependencies for
                later use by LICENSE generator -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-npm-dependency-list</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${dependency.list.directory}</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>src/main/frontend/dist</directory>
                                    <includes>
                                        <include>npm-dependencies.txt</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- Automatically generate LICENSE and NOTICE -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>generate-license-files</id>
                        <phase>generate-resources</phase>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>
                <configuration>

                    <webResources>

                        <!-- Add frontend folder to war package ... -->
                        <resource>
                            <directory>src/main/frontend/dist</directory>
                            <excludes>
                                <exclude>translations/*.json</exclude>
                                <exclude>index.html</exclude>
                                <exclude>verifyCachedVersion.js</exclude>
                            </excludes>
                        </resource>

                        <!-- ... but filter index.html and translation strings -->
                        <resource>
                            <directory>src/main/frontend/dist</directory>
                            <filtering>true</filtering>
                            <includes>
                                <include>translations/*.json</include>
                                <include>index.html</include>
                                <include>verifyCachedVersion.js</include>
                            </includes>
                        </resource>

                        <!-- Include all licenses within META-INF -->
                        <resource>
                            <directory>${project.build.directory}/licenses</directory>
                            <targetPath>META-INF</targetPath>
                        </resource>

                    </webResources>

                    <!-- Add files from guacamole-common-js -->
                    <overlays>
                        <overlay>
                            <groupId>org.apache.guacamole</groupId>
                            <artifactId>guacamole-common-js</artifactId>
                            <type>zip</type>
                        </overlay>
                    </overlays>
            
                </configuration>
                <executions>
                    <execution>
                        <id>default-cli</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>exploded</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

    <dependencies>

        <!-- Jakarta servlet API -->
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jakarta.servlet.jsp</groupId>
            <artifactId>jakarta.servlet.jsp-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jakarta.inject</groupId>
            <artifactId>jakarta.inject-api</artifactId>
        </dependency>
        <dependency>
            <groupId>jakarta.el</groupId>
            <artifactId>jakarta.el-api</artifactId>
            <version>5.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- Jakarta WebSocket API -->
        <dependency>
            <groupId>jakarta.websocket</groupId>
            <artifactId>jakarta.websocket-api</artifactId>
            <version>2.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <exclusions>

                <!-- Exclude optional dependency on JavaMail -->
                <exclusion>
                     <groupId>com.sun.mail</groupId>
                     <artifactId>jakarta.mail</artifactId>
                </exclusion>

            </exclusions>
        </dependency>

        <!-- Guacamole Extension API -->
        <dependency>
            <groupId>org.apache.guacamole</groupId>
            <artifactId>guacamole-ext</artifactId>
            <version>1.5.3</version>
        </dependency>

        <!-- Guacamole JavaScript API -->
        <dependency>
            <groupId>org.apache.guacamole</groupId>
            <artifactId>guacamole-common-js</artifactId>
            <version>1.5.3</version>
            <type>zip</type>
            <scope>runtime</scope>
        </dependency>

        <!-- Jetty 8 servlet API (websocket)  -->
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-websocket</artifactId>
            <version>8.1.1.v20120215</version>
            <scope>provided</scope>
        </dependency>

        <!-- Jetty 9.0 servlet API (websocket)  -->
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-parent</artifactId>
            <version>20</version>
            <scope>provided</scope>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>websocket-api</artifactId>
            <version>9.0.7.v20131107</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>websocket-servlet</artifactId>
            <version>9.0.7.v20131107</version>
            <scope>provided</scope>
        </dependency>

        <!-- Tomcat servlet API (websocket)  -->
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-catalina</artifactId>
            <version>7.0.37</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-coyote</artifactId>
            <version>7.0.37</version>
            <scope>provided</scope>
        </dependency>

        <!-- Guice - Dependency Injection -->
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>7.0.0</version>
        </dependency>
        <dependency>
            <groupId>ru.vyarus.guice.jakarta</groupId>
            <artifactId>guice</artifactId>
            <version>5.1.0-rc.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.inject.extensions</groupId>
            <artifactId>guice-assistedinject</artifactId>
            <version>7.0.0</version>
        </dependency>
        <dependency>
            <groupId>ru.vyarus.guice.jakarta</groupId>
            <artifactId>guice-assistedinject</artifactId>
            <version>5.1.0-rc.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.inject.extensions</groupId>
            <artifactId>guice-servlet</artifactId>
            <version>7.0.0</version>
        </dependency>
        
        <!-- Jersey Implementation -->
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.inject</groupId>
            <artifactId>jersey-hk2</artifactId>
            <version>3.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.hk2</groupId>
            <artifactId>guice-bridge</artifactId>
            <version>3.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>listenablefuture</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- jakarta annotations -->
        <dependency>
            <groupId>jakarta.annotation</groupId>
            <artifactId>jakarta.annotation-api</artifactId>
            <version>2.1.1</version>
        </dependency>
        
        <!-- Guava Base Libraries -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </dependency>

        <!-- Force use of version 1.2.2 (transitive dependencies of
            jersey-media-json-jackson disagree on 1.2.1 vs. 1.2.2) -->
        <dependency>
            <groupId>jakarta.activation</groupId>
            <artifactId>jakarta.activation-api</artifactId>
            <version>2.0.1</version>
        </dependency>      

    </dependencies>

</project>
<?xml version="1.0" encoding="UTF-8"?>
<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
-->
<web-app version="6.0"
         xmlns="https://jakarta.ee/xml/ns/jakartaee";
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                             https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd";>

    <!-- Basic config -->
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <!-- Request that the browser always revalidate its cached copy of index.html -->
    <filter>
        <filter-name>cacheRevalidationFilter</filter-name>
        <filter-class>org.apache.guacamole.CacheRevalidationFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>cacheRevalidationFilter</filter-name>
        <url-pattern>/index.html</url-pattern>
    </filter-mapping>

    <!-- Route all requests through Guice -->
    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <listener>
        <listener-class>org.apache.guacamole.GuacamoleServletContextListener</listener-class>
    </listener>

    <!-- Audio file mimetype mappings -->
    <mime-mapping>
        <extension>mp3</extension>
        <mime-type>audio/mpeg</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>ogg</extension>
        <mime-type>audio/ogg</mime-type>
    </mime-mapping>

</web-app>

Reply via email to