+ add protection for NPE seen during constructor initialization. + Javadoc fixes
This commit is contained in:
parent
b571c6a2d3
commit
9df827b802
|
@ -335,9 +335,9 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Alias
|
|||
*
|
||||
* @param virtualHosts Array of virtual hosts that this context responds to. A null/empty array means any hostname is acceptable. Host names may be String
|
||||
* representation of IP addresses. Host names may start with '*.' to wildcard one level of names. Hosts and wildcard hosts may be followed with
|
||||
* '@connectorname', in which case they will match only if the the {@link Connector#getName()} for the request also matches. If an entry is just
|
||||
* '@connectorname' it will match any host if that connector was used. Note - In previous versions if one or more connectorname only entries existed
|
||||
* and non of the connectors matched the handler would not match regardless of any hostname entries. If there is one or more connectorname only
|
||||
* {@code "@connectorname"}, in which case they will match only if the {@link Connector#getName()} for the request also matches. If an entry is just
|
||||
* {@code "@connectorname"} it will match any host if that connector was used. Note - In previous versions if one or more connectorname only entries existed
|
||||
* and none of the connectors matched the handler would not match regardless of any hostname entries. If there is one or more connectorname only
|
||||
* entries and one or more host only entries but no hostname and connector entries we assume the old behavior and will log a warning. The warning
|
||||
* can be removed by removing the host entries that were previously being ignored, or modifying to include a hostname and connectorname entry.
|
||||
*/
|
||||
|
@ -356,9 +356,9 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Alias
|
|||
*
|
||||
* @param virtualHosts Array of virtual hosts that this context responds to. A null/empty array means any hostname is acceptable. Host names may be String
|
||||
* representation of IP addresses. Host names may start with '*.' to wildcard one level of names. Hosts and wildcard hosts may be followed with
|
||||
* '@connectorname', in which case they will match only if the the {@link Connector#getName()} for the request also matches. If an entry is just
|
||||
* '@connectorname' it will match any host if that connector was used. Note - In previous versions if one or more connectorname only entries existed
|
||||
* and non of the connectors matched the handler would not match regardless of any hostname entries. If there is one or more connectorname only
|
||||
* {@code "@connectorname"}, in which case they will match only if the {@link Connector#getName()} for the request also matches. If an entry is just
|
||||
* {@code "@connectorname"} it will match any host if that connector was used. Note - In previous versions if one or more connectorname only entries existed
|
||||
* and none of the connectors matched the handler would not match regardless of any hostname entries. If there is one or more connectorname only
|
||||
* entries and one or more host only entries but no hostname and connector entries we assume the old behavior and will log a warning. The warning
|
||||
* can be removed by removing the host entries that were previously being ignored, or modifying to include a hostname and connectorname entry.
|
||||
*/
|
||||
|
@ -379,8 +379,8 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Alias
|
|||
*
|
||||
* @return list of virtual hosts that this context responds to. A null/empty array means any hostname is acceptable. Host names may be String
|
||||
* representation of IP addresses. Host names may start with '*.' to wildcard one level of names. Hosts and wildcard hosts may be followed with
|
||||
* '@connectorname', in which case they will match only if the the {@link Connector#getName()} for the request also matches. If an entry is just
|
||||
* '@connectorname' it will match any host if that connector was used. Note - In previous versions if one or more connectorname only entries existed
|
||||
* {@code "@connectorname"}, in which case they will match only if the {@link Connector#getName()} for the request also matches. If an entry is just
|
||||
* {@code "@connectorname"} it will match any host if that connector was used. Note - In previous versions if one or more connectorname only entries existed
|
||||
* and none of the connectors matched the handler would not match regardless of any hostname entries. If there is one or more connectorname only
|
||||
* entries and one or more host only entries but no hostname and connector entries we assume the old behavior and will log a warning. The warning
|
||||
* can be removed by removing the host entries that were previously being ignored, or modifying to include a hostname and connectorname entry.
|
||||
|
@ -388,6 +388,8 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Alias
|
|||
@ManagedAttribute(value = "Virtual hosts accepted by the context", readonly = true)
|
||||
public List<String> getVirtualHosts()
|
||||
{
|
||||
if (_vhosts == null)
|
||||
return null;
|
||||
return _vhosts.stream().map(VHost::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
@ -1038,9 +1040,9 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Alias
|
|||
b.append(getDisplayName()).append(',');
|
||||
b.append(getContextPath());
|
||||
b.append(",b=").append(getBaseResource());
|
||||
b.append(",a=").append(_availability.get());
|
||||
b.append(",a=").append(_availability);
|
||||
|
||||
if (!vhosts.isEmpty())
|
||||
if (vhosts != null && !vhosts.isEmpty())
|
||||
{
|
||||
b.append(",vh=[");
|
||||
b.append(String.join(",", vhosts));
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jetty.logging.JettyLevel;
|
||||
import org.eclipse.jetty.logging.JettyLogger;
|
||||
import org.eclipse.jetty.logging.JettyLoggerFactory;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.ILoggerFactory;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
/**
|
||||
* Logger Debug Testing of Handlers
|
||||
*/
|
||||
public class LoggerDebugTest
|
||||
{
|
||||
private CaptureDebugLogging captureDebugLogging = new CaptureDebugLogging(System.err);
|
||||
private PrintStream old = System.err;
|
||||
|
||||
@BeforeEach
|
||||
public void init()
|
||||
{
|
||||
// Add some classes with Loggers that have triggered logging issues in the past
|
||||
captureDebugLogging.capture(ContainerLifeCycle.class);
|
||||
captureDebugLogging.capture(Handler.Wrapper.class);
|
||||
System.setErr(captureDebugLogging);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown()
|
||||
{
|
||||
System.setErr(old);
|
||||
captureDebugLogging.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to ensure that "SLF4J: Failed toString() invocation on an object of type" does not happen with Wrappers.
|
||||
* See https://github.com/jetty/jetty.project/issues/11220
|
||||
*/
|
||||
@Test
|
||||
public void testWrapperNPE()
|
||||
{
|
||||
ContextHandler simpleContextHandler = new ContextHandler(new Handler.Abstract.NonBlocking()
|
||||
{
|
||||
@Override
|
||||
public boolean handle(Request request, Response response, Callback callback)
|
||||
{
|
||||
callback.succeeded();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// verify that there was no exception in System.err from SLF4J (due to bad "this" handling in Wrapper class)
|
||||
assertThat(captureDebugLogging.capture.toString(), not(containsString("SLF4J: Failed toString()")));
|
||||
}
|
||||
|
||||
record OriginalLogger(JettyLogger logger, JettyLevel level) {}
|
||||
|
||||
public static class CaptureDebugLogging extends PrintStream
|
||||
{
|
||||
private final PrintStream out;
|
||||
StringBuilder capture = new StringBuilder();
|
||||
private final JettyLoggerFactory jettyLoggerFactory;
|
||||
private List<OriginalLogger> originalLoggers = new ArrayList<>();
|
||||
|
||||
public CaptureDebugLogging(PrintStream out)
|
||||
{
|
||||
super(out);
|
||||
this.out = out;
|
||||
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
|
||||
JettyLoggerFactory jettyFactory = null;
|
||||
if (loggerFactory instanceof JettyLoggerFactory factory)
|
||||
{
|
||||
jettyFactory = factory;
|
||||
}
|
||||
Assumptions.assumeTrue(jettyFactory != null, "Not using jetty-slf4j-impl");
|
||||
this.jettyLoggerFactory = jettyFactory;
|
||||
}
|
||||
|
||||
public void restore()
|
||||
{
|
||||
for (OriginalLogger originalLogger: originalLoggers)
|
||||
{
|
||||
originalLogger.logger.setLevel(originalLogger.level);
|
||||
}
|
||||
}
|
||||
|
||||
public void capture(Class klass)
|
||||
{
|
||||
capture(klass.getName());
|
||||
}
|
||||
|
||||
public void capture(Object obj)
|
||||
{
|
||||
capture(obj.getClass());
|
||||
}
|
||||
|
||||
public void capture(String loggerName)
|
||||
{
|
||||
JettyLogger jettyLogger = jettyLoggerFactory.getJettyLogger(loggerName);
|
||||
JettyLevel originalLevel = jettyLogger.getLevel();
|
||||
originalLoggers.add(new OriginalLogger(jettyLogger, originalLevel));
|
||||
jettyLogger.setLevel(JettyLevel.DEBUG);
|
||||
}
|
||||
|
||||
private void out(String s)
|
||||
{
|
||||
this.out.print(s);
|
||||
capture.append(s);
|
||||
}
|
||||
|
||||
public void print(String s)
|
||||
{
|
||||
out(s);
|
||||
}
|
||||
|
||||
public void println(String s)
|
||||
{
|
||||
out(s + System.lineSeparator());
|
||||
}
|
||||
|
||||
public void println(Object o)
|
||||
{
|
||||
out(Objects.toString(o) + System.lineSeparator());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue