Tomcat 9 Valve导致服务器启动失败 [英] Tomcat 9 Valve Causing Server Start Failure

查看:221
本文介绍了Tomcat 9 Valve导致服务器启动失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了一个自定义的tomcat阀来解析HTTP标头并使用它们进行身份验证.该阀通过扩展AuthenticatorBase来工作.我编译了它,并将其放在$ CATALINA_HOME/lib中.这是代码:

I have written a custom tomcat valve to parse HTTP headers and use them to authenticate. The valve works by extending AuthenticatorBase. I compiled it and placed it in $CATALINA_HOME/lib. Here is code:


    public class TomcatLogin extends AuthenticatorBase {

        private String[] roleNames = null;
        private String ivcreds = null;
        private String ivuser = null;
        private String ivgroups = null;
        private GenericPrincipal principal = null;

        // Constructor defers to super class (Authenticator base)
        public TomcatLogin(){
            super();
        }

        protected boolean doAuthenticate(Request request, HttpServletResponse response)
        {
            List<String> groupsList = null;

            System.out.println("Obtaining Headers from Request");
            try {
                ivuser = request.getHeader("iv-user");
                ivcreds = request.getHeader("iv-creds");
                ivgroups = request.getHeader("iv-groups");
            } catch(Exception e) {
                e.printStackTrace();
            }

            // Require all header credentials for proper authentication
            if(ivuser == null || ivcreds == null || ivgroups == null)
                return false;

            // Split ivgroups by comma seporated value
            // Then remove head and tail quotation marks
            roleNames = ivgroups.split(",");
            for(int i=0; i<roleNames.length; i++){
                roleNames[i] = roleNames[i].substring(1, roleNames[i].length()-1 );
                groupsList.add(roleNames[i]);
            }

            principal = new GenericPrincipal(ivuser, ivcreds, groupsList);
            request.setUserPrincipal(principal);

            return true;
        }

        public String getAuthMethod() {
            return "HTTPAuthenticator";
        }

    }

然后我告诉Tomcat使用server.xml中的阀门. 文档用于扩展AuthenticatorBase表示使用此类时,其所属的上下文(或层次结构中的父容器)必须具有关联的领域,该领域可用于验证用户并枚举已分配给他们的角色.我以为我已经正确配置了它,但是它抛出了错误并且Tomcat无法启动.这是server.xml配置:

I then tell Tomcat to use the valve in the server.xml. The documentation for extending AuthenticatorBase says When this class is utilized, the Context to which it is attached (or a parent Container in a hierarchy) must have an associated Realm that can be used for authenticating users and enumerating the roles to which they have been assigned. I thought I had configured it correctly, but it throws and error and Tomcat fails to start. Here is the server.xml config:


    <?xml version="1.0" encoding="UTF-8"?>
    ...
      <Server>
        <Service name="Catalina">
          <Engine name="Catalina" defaultHost="localhost">
            <Realm className="org.apache.catalina.realm.LockOutRealm">
              <Realm className="org.apache.catalina.realm.UserDatabaseRealm" 
                     resourceName="UserDatabase"/>
            </Realm>

            <!-- Here is my valve -->
            <Valve className="package.of.my.custom.valve.TomcatLogin" />

            <Host ... >
               ...
            </Host>
          </Engine>
        </Service>
      </Server>

这是我收到的错误消息:

And here is the Error message I am getting:

10-Jan-2019 10:11:03.576 SEVERE [main] org.apache.tomcat.util.digester.Digester.endElement End event threw exception
 java.lang.reflect.InvocationTargetException
... A bunch of useless stacktrace
Caused by: java.lang.IllegalArgumentException: Configuration error:  Must be attached to a Context at org.apache.catalina.authenticator.AuthenticatorBase.setContainer(AuthenticatorBase.java:278)
at org.apache.catalina.core.StandardPipeline.addValve(StandardPipeline.java:335)
at org.apache.catalina.core.ContainerBase.addValve(ContainerBase.java:1133)
    ... 27 more

10-Jan-2019 10:11:03.579 WARNING [main] org.apache.catalina.startup.Catalina.load Catalina.start using conf/server.xml: Error at (107, 82) : Configuration error:  Must be attached to a Context
10-Jan-2019 10:11:03.579 SEVERE [main] org.apache.catalina.startup.Catalina.start Cannot start server. Server instance is not configured.

我认为我的阀门是正确编写的,所以我想问题出在配置中.不知道为什么它没有附加上下文.有什么想法吗?

I think my valve is written correctly, so my guess is that the issue is in the configuration. Not sure why it is not getting a context to attach to. Any ideas?

修改: 我尝试将阀门放入应用程序的META-INF/context.xml中(因为一开始就没有一个阀门,所以我必须制造一个阀门).在这里:

I tried putting the valve in my app's META-INF/context.xml (I had to make one since there wasn't one to begin with). Here it is:

<?xml version="1.0"?>
<Context>
    <Valve className="package.of.my.custom.valve.TomcatLogin" />
</Context>

服务器随后启动,但是它无法部署任何应用程序.我收到了与IBM阀门类似的错误,该阀门最初是我试图在此自定义实现中使用的,在那里它无法从catalina.jar找到AuthenticatorBase类.这是我遇到的SEVERE错误:

The server then start, but it fails to deploy any of the applications. I am getting similar error to an IBM valve which I originally tried to use over this custom implementation where it cannot find the AuthenticatorBase class from catalina.jar. Here are the SEVERE errors I am getting:

    10-Jan-2019 15:34:06.673 SEVERE [main] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
    org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/sample-DB]]
...
Stacktrace info
...
        at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:441)
    Caused by: java.lang.ExceptionInInitializerError
        at org.apache.tomcat.util.digester.Digester.startDocument(Digester.java:1102)
    Caused by: java.lang.NullPointerException
        at java.nio.charset.Charset.put(Charset.java:538)
...
Stacktrace
...
    10-Jan-2019 15:34:06.688 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/fmac/deploy/sample.war] has finished in [11] ms
    10-Jan-2019 15:34:06.689 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/fmac/deploy/sample-auth.war]
    10-Jan-2019 15:34:06.692 SEVERE [main] org.apache.tomcat.util.digester.Digester.startElement Begin event threw error
    java.lang.NoClassDefFoundError: org/apache/catalina/authenticator/AuthenticatorBase
...
Stacktrace
The Error Below is the most confusing one. How can it not find this class?
...
    Caused by: java.lang.ClassNotFoundException: org.apache.catalina.authenticator.AuthenticatorBase
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
...
Stacktrace
...
    10-Jan-2019 15:34:13.823 SEVERE [https-jsse-nio2-8443-exec-3] org.apache.coyote.http11.Http11Processor.service Error processing request
    java.lang.NoClassDefFoundError: Could not initialize class
org.apache.tomcat.util.buf.B2CConverter
        at org.apache.catalina.connector.CoyoteAdapter.convertURI(CoyoteAdapter.java:1072)

推荐答案

所以我终于能够找出问题所在.我们有一个自定义的tomcat实现,其中一部分涉及在java命令中附加类路径.由于某些原因,某些正在使用的数据库驱动程序导致Tomcat无法在CATALINA_HOME/lib中找到任何库.我在Docker容器中运行,这是VM版本中的一些旧痕迹.我们最终不得不扔那些 赶走.

So I was finally able to find out what the issues were. We have a custom tomcat implementation, part of which involves appending the classpath in the java command. For some reason, some of the database drivers that were being used caused the Tomcat to fail to find any of the libraries in CATALINA_HOME/lib. I'm running inside a Docker container and this was some old vestigial stuff from a VM version. We ended up just having to toss those drivers out.

不太确定为什么它们会完全覆盖基本的lib/目录,但是至少在离开时会出现这些错误,并且我实际上能够使用我拥有的预制身份验证器,而不必微调此自定义身份验证器.

Not really sure why they would completely override the base lib/ directory, but at least these errors when away and I was actually able to use the pre-built authenticator I had instead of fine tuning this custom one.

这篇关于Tomcat 9 Valve导致服务器启动失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆