javatomcatjava-platform-module-system

Tomcat JPMS error jakarta.security.auth.message


I try to build jpms embedded tomcat server .

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <scope>compile</scope>
        </dependency>

        <!-- Tomcat -->
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-catalina</artifactId>
            <version>10.1.24</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper</artifactId>
            <version>10.1.24</version>
        </dependency>
    </dependencies>

and this is module-info.java:

module my_custom_module {
    requires org.slf4j;
    requires jakarta.servlet;
    requires org.apache.tomcat.jasper;
    requires org.apache.tomcat.catalina;
}

project compile and run without any problem :

java --module-path target/lib/ -m my_custom_module/a.b.c.module.tomcat.MainClass   

this is my code:

import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.Optional;
import java.util.stream.Stream;

public class HttpContainer {
    public static final HttpContainer instance = new HttpContainer();
    private static final Logger logger = LoggerFactory.getLogger(HttpContainer.class);
    private static final String contextPath = "/api";
    private static final String host = System.getenv("HTTP_SERVER_HOST");
    private static final String port = System.getenv("HTTP_SERVER_PORT");
    private static final String appBase = "/tmp/tomcat";
    private static Tomcat tomcat;

    private HttpContainer() {
        createAppBaseDirectory();
        TomcatURLStreamHandlerFactory.disable();
        tomcat = new Tomcat();
        tomcat.setHostname(Optional.ofNullable(host).orElse("0.0.0.0"));
        tomcat.setPort(Integer.parseInt(Optional.ofNullable(port).orElse("8080")));
        tomcat.setBaseDir(appBase);

        Context context = tomcat.addWebapp(contextPath, appBase);

        tomcat.addServlet(contextPath, "hello", new HelloServlet());
        context.addServletMappingDecoded("/hello", "hello");
    }

    public void start() {
        try {
            tomcat.getConnector();
            tomcat.start();
            logger.info("Tomcat server started");
            tomcat.getServer().await();
        } catch (Exception e) {
            logger.error("Tomcat error", e);
        }
    }

    public void stop() {
        try (Stream<Path> pathStream = Files.walk(Path.of(appBase))) {
            pathStream.sorted(Comparator.reverseOrder())
                    .map(Path::toFile)
                    .forEach(java.io.File::delete);

            tomcat.stop();
            logger.info("Tomcat server stopped");
        } catch (Exception e) {
            logger.error("Tomcat error", e);
        }
    }

    private void createAppBaseDirectory() {
        try {
            Path appBasePath = Path.of(appBase);
            if (!Files.exists(appBasePath)) {
                Files.createDirectory(appBasePath);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

my problem:
when i send http request , server result this error :

SLF4J(W): No SLF4J providers were found.                                                                                                                         
SLF4J(W): Defaulting to no-operation (NOP) logger implementation                                                                                                 
SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.                                                                                  
May 24, 2024 1:59:21 PM org.apache.coyote.AbstractProtocol init                                                                                                  
INFO: Initializing ProtocolHandler ["http-nio-8080"]                                                                                                             
May 24, 2024 1:59:21 PM org.apache.catalina.core.StandardService startInternal                                                                                   
INFO: Starting service [Tomcat]                                                                                                                                  
May 24, 2024 1:59:21 PM org.apache.catalina.core.StandardEngine startInternal                                                                                    
INFO: Starting Servlet engine: [Apache Tomcat/10.1.24]                                                                                                           
May 24, 2024 1:59:21 PM org.apache.catalina.startup.ContextConfig getDefaultWebXmlFragment                                 
INFO: No global web.xml found                                                                                                                                    
May 24, 2024 1:59:22 PM org.apache.jasper.servlet.TldScanner scanJars                                                                                            
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs
 were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
May 24, 2024 1:59:22 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
May 24, 2024 1:59:24 PM org.apache.catalina.core.StandardHostValve invoke
SEVERE: Exception Processing [/api/hello]
java.lang.IllegalAccessError: class jakarta.security.auth.message.config.AuthConfigFactory (in module jakarta.security.auth.message) cannot access class org.apac
he.catalina.authenticator.jaspic.AuthConfigFactoryImpl (in module org.apache.tomcat.catalina) because module jakarta.security.auth.message does not read module o
rg.apache.tomcat.catalina
        at jakarta.security.auth.message@3.0/jakarta.security.auth.message.config.AuthConfigFactory.lambda$getFactory$0(AuthConfigFactory.java:82)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
        at jakarta.security.auth.message@3.0/jakarta.security.auth.message.config.AuthConfigFactory.getFactory(AuthConfigFactory.java:76)
        at org.apache.tomcat.catalina@10.1.24/org.apache.catalina.authenticator.AuthenticatorBase.findJaspicProvider(AuthenticatorBase.java:1268)
        at org.apache.tomcat.catalina@10.1.24/org.apache.catalina.authenticator.AuthenticatorBase.getJaspicProvider(AuthenticatorBase.java:1261)
        at org.apache.tomcat.catalina@10.1.24/org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:473)
        at org.apache.tomcat.catalina@10.1.24/org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
        at org.apache.tomcat.catalina@10.1.24/org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
        at org.apache.tomcat.catalina@10.1.24/org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.tomcat.catalina@10.1.24/org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
        at org.apache.tomcat.coyote@10.1.24/org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389)
        at org.apache.tomcat.coyote@10.1.24/org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
        at org.apache.tomcat.coyote@10.1.24/org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
        at org.apache.tomcat.coyote@10.1.24/org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
        at org.apache.tomcat.coyote@10.1.24/org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
        at org.apache.tomcat.util@10.1.24/org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
        at org.apache.tomcat.util@10.1.24/org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util@10.1.24/org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
        at java.base/java.lang.Thread.run(Thread.java:1583)

how to fix this problem ?


Solution

  • Fixed ! simple problem : Thanks to this question

    only replace :

    Context context = tomcat.addWebapp(contextPath, appBase);
    

    to

    Context context = tomcat.addContext(contextPath, baseDir);