diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index de518fcb72..b4a956513f 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -77,7 +77,11 @@ import static java.util.logging.Level.*; * @author Kohsuke Kawaguchi */ public class WebAppMain implements ServletContextListener { - private final RingBufferLogHandler handler = new RingBufferLogHandler() { + + // use RingBufferLogHandler class name to configure for backward compatibility + private static final int DEFAULT_RING_BUFFER_SIZE = SystemProperties.getInteger(RingBufferLogHandler.class.getName() + ".defaultSize", 256); + + private final RingBufferLogHandler handler = new RingBufferLogHandler(DEFAULT_RING_BUFFER_SIZE) { @Override public synchronized void publish(LogRecord record) { if (record.getLevel().intValue() >= Level.INFO.intValue()) { super.publish(record); diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index 50e071ef98..66e57ba76e 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -56,6 +56,7 @@ import jenkins.security.MasterToSlaveCallable; import jenkins.slaves.EncryptedSlaveAgentJnlpFile; import jenkins.slaves.JnlpSlaveAgentProtocol; import jenkins.slaves.systemInfo.SlaveSystemInfo; +import jenkins.util.SystemProperties; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; import org.kohsuke.stapler.HttpRedirect; @@ -541,7 +542,7 @@ public class SlaveComputer extends Computer { // it'll have a catastrophic impact on the communication. channel.pinClassLoader(getClass().getClassLoader()); - channel.call(new SlaveInitializer()); + channel.call(new SlaveInitializer(DEFAULT_RING_BUFFER_SIZE)); SecurityContext old = ACL.impersonate(ACL.SYSTEM); try { for (ComputerListener cl : ComputerListener.all()) { @@ -804,11 +805,19 @@ public class SlaveComputer extends Computer { /** * This field is used on each agent to record logs on the agent. */ - static final RingBufferLogHandler SLAVE_LOG_HANDLER = new RingBufferLogHandler(); + static RingBufferLogHandler SLAVE_LOG_HANDLER; } private static class SlaveInitializer extends MasterToSlaveCallable { + final int ringBufferSize; + + public SlaveInitializer(int ringBufferSize) { + this.ringBufferSize = ringBufferSize; + } + public Void call() { + SLAVE_LOG_HANDLER = new RingBufferLogHandler(ringBufferSize); + // avoid double installation of the handler. JNLP slaves can reconnect to the master multiple times // and each connection gets a different RemoteClassLoader, so we need to evict them by class name, // not by their identity. @@ -867,5 +876,8 @@ public class SlaveComputer extends Computer { } } + // use RingBufferLogHandler class name to configure for backward compatibility + private static final int DEFAULT_RING_BUFFER_SIZE = SystemProperties.getInteger(RingBufferLogHandler.class.getName() + ".defaultSize", 256); + private static final Logger LOGGER = Logger.getLogger(SlaveComputer.class.getName()); } diff --git a/core/src/main/java/hudson/util/RingBufferLogHandler.java b/core/src/main/java/hudson/util/RingBufferLogHandler.java index dc51e2c694..89d0b124d7 100644 --- a/core/src/main/java/hudson/util/RingBufferLogHandler.java +++ b/core/src/main/java/hudson/util/RingBufferLogHandler.java @@ -23,7 +23,6 @@ */ package hudson.util; -import jenkins.util.SystemProperties; import java.util.AbstractList; import java.util.List; import java.util.logging.Handler; @@ -36,12 +35,17 @@ import java.util.logging.LogRecord; */ public class RingBufferLogHandler extends Handler { - private static final int DEFAULT_RING_BUFFER_SIZE = SystemProperties.getInteger(RingBufferLogHandler.class.getName() + ".defaultSize", 256); + private static final int DEFAULT_RING_BUFFER_SIZE = Integer.getInteger(RingBufferLogHandler.class.getName() + ".defaultSize", 256); private int start = 0; private final LogRecord[] records; private volatile int size = 0; + /** + * This constructor is deprecated. It can't access system properties with {@link jenkins.util.SystemProperties} + * as it's not legal to use it on remoting agents. + */ + @Deprecated public RingBufferLogHandler() { this(DEFAULT_RING_BUFFER_SIZE); } diff --git a/core/src/main/java/jenkins/util/SystemProperties.java b/core/src/main/java/jenkins/util/SystemProperties.java index 794e956b1a..cadda5250b 100644 --- a/core/src/main/java/jenkins/util/SystemProperties.java +++ b/core/src/main/java/jenkins/util/SystemProperties.java @@ -32,6 +32,8 @@ import java.util.logging.Logger; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; + +import jenkins.util.io.OnMaster; import org.apache.commons.lang.StringUtils; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -65,7 +67,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; */ //TODO: Define a correct design of this engine later. Should be accessible in libs (remoting, stapler) and Jenkins modules too @Restricted(NoExternalUse.class) -public class SystemProperties implements ServletContextListener { +public class SystemProperties implements ServletContextListener, OnMaster { // this class implements ServletContextListener and is declared in WEB-INF/web.xml /** @@ -88,7 +90,7 @@ public class SystemProperties implements ServletContextListener { * Called by the servlet container to initialize the {@link ServletContext}. */ @Override - @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Currently Jenkins instance may have one ond only one context") public void contextInitialized(ServletContextEvent event) { theContext = event.getServletContext();