From 95232a3db9afd0d9116f5420b922e22219c439d4 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Wed, 14 Jan 2026 17:16:13 -0800 Subject: [PATCH 1/4] Upgrade to Spring Boot 4, Spring Framework 7, and Tomcat 11 --- .../org/labkey/api/data/TempTableTracker.java | 126 ++++++++---------- .../labkey/api/util/CheckedInputStream.java | 61 ++++++--- .../org/labkey/api/util/ExceptionUtil.java | 6 + 3 files changed, 106 insertions(+), 87 deletions(-) diff --git a/api/src/org/labkey/api/data/TempTableTracker.java b/api/src/org/labkey/api/data/TempTableTracker.java index 3ce1c067499..4dc5a2bbfa3 100644 --- a/api/src/org/labkey/api/data/TempTableTracker.java +++ b/api/src/org/labkey/api/data/TempTableTracker.java @@ -23,28 +23,24 @@ import org.labkey.api.util.FileUtil; import org.labkey.api.util.ShutdownListener; -import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; +import java.lang.ref.Cleaner; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; -import java.util.concurrent.atomic.AtomicBoolean; /** * User: Matthew * Date: May 4, 2006 * Time: 7:27:50 PM */ -public class TempTableTracker extends WeakReference +public class TempTableTracker { private static final Logger _log = LogManager.getLogger(TempTableTracker.class); private static final String LOGFILE = "CPAS_sqlTempTables.log"; private static final Map createdTableNames = new TreeMap<>(); - private static final ReferenceQueue cleanupQueue = new ReferenceQueue<>(); + private static final Cleaner cleaner = Cleaner.create(); private static RandomAccessFile tempTableLog = null; @@ -55,14 +51,60 @@ public class TempTableTracker extends WeakReference private boolean deleted = false; + private static class CleanupState implements Runnable + { + private final DbSchema schema; + private final String tableName; + private final String qualifiedName; + private final String schemaName; + private boolean deleted = false; + + private CleanupState(DbSchema schema, String tableName, String qualifiedName, String schemaName) + { + this.schema = schema; + this.tableName = tableName; + this.qualifiedName = qualifiedName; + this.schemaName = schemaName; + } + + @Override + public void run() + { + if (delete()) + { + _log.error("finalizing undeleted TempTableTracker: " + qualifiedName); + } + } + + private synchronized boolean delete() + { + if (deleted) + return false; + + _log.debug("Deleting table " + schema.getName() + "." + tableName); + schema.dropTableIfExists(tableName); + + deleted = true; + untrack(qualifiedName, schemaName, tableName); + return true; + } + + private synchronized void markDeleted() + { + deleted = true; + } + } + + private final CleanupState state; private TempTableTracker(DbSchema schema, String tableName, Object ref) { - super(ref, cleanupQueue); this.schema = schema; this.schemaName = schema.getName(); this.tableName = tableName; this.qualifiedName = this.schemaName + "." + this.tableName; + this.state = new CleanupState(schema, tableName, qualifiedName, schemaName); + cleaner.register(ref, state); } @@ -84,8 +126,6 @@ public static void init() initialized = true; synchronizeLog(true); purgeTempSchema(); - tempTableThread.setDaemon(true); - tempTableThread.start(); } } } @@ -132,44 +172,33 @@ public synchronized void delete() if (deleted) return; + state.markDeleted(); sqlDelete(); deleted = true; - untrack(); + untrack(qualifiedName, schemaName, tableName); } private boolean sqlDelete() { - DbSchema schema = getSchema(); _log.debug("Deleting table " + schema.getName() + "." + tableName); schema.dropTableIfExists(tableName); return true; } - @Override - protected void finalize() throws Throwable - { - if (!deleted) - _log.error("finalizing undeleted TempTableTracker: " + qualifiedName); - super.finalize(); - } - - - private void untrack() + private static void untrack(String qualifiedName, String schemaName, String tableName) { _log.debug("untrack(" + qualifiedName + ")"); synchronized(createdTableNames) { - var ttt = createdTableNames.remove(qualifiedName); + createdTableNames.remove(qualifiedName); appendToLog("-" + schemaName + "\t" + tableName + "\n"); if (createdTableNames.isEmpty() || System.currentTimeMillis() > lastSync + CacheManager.DAY) synchronizeLog(false); - - ttt.clear(); } } @@ -285,47 +314,12 @@ else if (s.charAt(0) == '-') static final TempTableThread tempTableThread = new TempTableThread(); - static class TempTableThread extends Thread implements ShutdownListener + public static class TempTableThread implements ShutdownListener { - AtomicBoolean _shutdown = new AtomicBoolean(false); - - TempTableThread() - { - super("Temp table cleanup"); - setDaemon(true); - } - @Override - public void run() + public String getName() { - while (true) - { - try - { - Reference r = _shutdown.get() ? cleanupQueue.poll() : cleanupQueue.remove(); - if (_shutdown.get() && r == null) - return; - //noinspection RedundantCast - TempTableTracker t = (TempTableTracker)(Object)r; - t.delete(); - } - catch (InterruptedException x) - { - _log.debug("interrupted"); - } - catch (Throwable x) - { - _log.error("unexpected error", x); - } - } - } - - - @Override - public void shutdownPre() - { - _shutdown.set(true); - interrupt(); + return "Temp table cleanup"; } @Override @@ -335,16 +329,12 @@ public void shutdownStarted() { for (TempTableTracker ttt : createdTableNames.values()) { + ttt.state.markDeleted(); ttt.sqlDelete(); ttt.deleted = true; } } - try - { - join(5000); - } - catch (InterruptedException ignored) {} synchronizeLog(false); } } diff --git a/api/src/org/labkey/api/util/CheckedInputStream.java b/api/src/org/labkey/api/util/CheckedInputStream.java index 523732a62c3..ecd50b70ee0 100644 --- a/api/src/org/labkey/api/util/CheckedInputStream.java +++ b/api/src/org/labkey/api/util/CheckedInputStream.java @@ -16,11 +16,11 @@ package org.labkey.api.util; import org.apache.logging.log4j.LogManager; -import org.jetbrains.annotations.Nullable; import org.labkey.api.miniprofiler.MiniProfiler; import java.io.IOException; import java.io.InputStream; +import java.lang.ref.Cleaner; /** * Verifies that close() was called at some point before finalization; logs an error and creation stack trace if not. @@ -30,32 +30,55 @@ public class CheckedInputStream extends InputStreamWrapper { - @Nullable - private final StackTraceElement[] _creationStackTrace; - private boolean _closed = false; + private static final Cleaner CLEANER = Cleaner.create(); - public CheckedInputStream(InputStream is) + private static class State implements Runnable { - super(is); - _creationStackTrace = MiniProfiler.getTroubleshootingStackTrace(); + private final InputStream _is; + private final StackTraceElement[] _creationStackTrace; + private boolean _closed = false; + + private State(InputStream is, StackTraceElement[] creationStackTrace) + { + _is = is; + _creationStackTrace = creationStackTrace; + } + + @Override + public void run() + { + if (!_closed) + { + LogManager.getLogger(CheckedInputStream.class).error("InputStream was not closed. Creation stacktrace:" + ExceptionUtil.renderStackTrace(_creationStackTrace)); + try + { + _is.close(); + } + catch (IOException e) + { + LogManager.getLogger(CheckedInputStream.class).error("Failed to close InputStream", e); + } + finally + { + _closed = true; + } + } + } } - @Override - public void close() throws IOException + private final Cleaner.Cleanable _cleanable; + + public CheckedInputStream(InputStream is) { - _closed = true; - super.close(); + super(is); + StackTraceElement[] creationStackTrace = MiniProfiler.getTroubleshootingStackTrace(); + State state = new State(is, creationStackTrace); + _cleanable = CLEANER.register(this, state); } @Override - protected void finalize() throws Throwable + public void close() throws IOException { - if (!_closed) - { - LogManager.getLogger(CheckedInputStream.class).error("InputStream was not closed. Creation stacktrace:" + ExceptionUtil.renderStackTrace(_creationStackTrace)); - super.close(); - } - - super.finalize(); + _cleanable.clean(); } } diff --git a/api/src/org/labkey/api/util/ExceptionUtil.java b/api/src/org/labkey/api/util/ExceptionUtil.java index 4e2555cf644..b45f6ab80a9 100644 --- a/api/src/org/labkey/api/util/ExceptionUtil.java +++ b/api/src/org/labkey/api/util/ExceptionUtil.java @@ -1572,6 +1572,12 @@ public void sendRedirect(String s) redirect = s; } + @Override + public void sendRedirect(String s, int i, boolean b) throws IOException + { + redirect = s; + } + @Override public void setDateHeader(String s, long l) { From 0ab14df70bf0726034f836866c3b242a110db079 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Thu, 15 Jan 2026 09:59:32 -0800 Subject: [PATCH 2/4] Simplify cleaning --- .../org/labkey/api/data/TempTableTracker.java | 68 ++++--------------- 1 file changed, 13 insertions(+), 55 deletions(-) diff --git a/api/src/org/labkey/api/data/TempTableTracker.java b/api/src/org/labkey/api/data/TempTableTracker.java index 4dc5a2bbfa3..2cf94d7a06a 100644 --- a/api/src/org/labkey/api/data/TempTableTracker.java +++ b/api/src/org/labkey/api/data/TempTableTracker.java @@ -16,12 +16,12 @@ package org.labkey.api.data; -import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.labkey.api.cache.CacheManager; import org.labkey.api.data.dialect.SqlDialect; import org.labkey.api.util.FileUtil; import org.labkey.api.util.ShutdownListener; +import org.labkey.api.util.logging.LogHelper; import java.io.IOException; import java.io.RandomAccessFile; @@ -37,20 +37,17 @@ */ public class TempTableTracker { - private static final Logger _log = LogManager.getLogger(TempTableTracker.class); + private static final Logger _log = LogHelper.getLogger(TempTableTracker.class, "Manages temp tables and their deletion"); private static final String LOGFILE = "CPAS_sqlTempTables.log"; private static final Map createdTableNames = new TreeMap<>(); private static final Cleaner cleaner = Cleaner.create(); private static RandomAccessFile tempTableLog = null; - private final DbSchema schema; private final String schemaName; private final String tableName; private final String qualifiedName; - private boolean deleted = false; - private static class CleanupState implements Runnable { private final DbSchema schema; @@ -70,28 +67,14 @@ private CleanupState(DbSchema schema, String tableName, String qualifiedName, St @Override public void run() { - if (delete()) + if (!deleted) { - _log.error("finalizing undeleted TempTableTracker: " + qualifiedName); - } - } - - private synchronized boolean delete() - { - if (deleted) - return false; - - _log.debug("Deleting table " + schema.getName() + "." + tableName); - schema.dropTableIfExists(tableName); + _log.debug("Deleting table " + schema.getName() + "." + tableName); + schema.dropTableIfExists(tableName); - deleted = true; - untrack(qualifiedName, schemaName, tableName); - return true; - } - - private synchronized void markDeleted() - { - deleted = true; + deleted = true; + untrack(qualifiedName, schemaName, tableName); + } } } @@ -99,7 +82,6 @@ private synchronized void markDeleted() private TempTableTracker(DbSchema schema, String tableName, Object ref) { - this.schema = schema; this.schemaName = schema.getName(); this.tableName = tableName; this.qualifiedName = this.schemaName + "." + this.tableName; @@ -113,13 +95,13 @@ private TempTableTracker(String schemaName, String tableName, Object ref) this(DbSchema.get(schemaName), tableName, ref); // TODO: Treat as provisioned? } - private static final Object initlock = new Object(); + private static final Object LOCK = new Object(); private static boolean initialized = false; // make sure temp table tracker is initialized public static void init() { - synchronized(initlock) + synchronized(LOCK) { if (!initialized) { @@ -160,31 +142,9 @@ private static TempTableTracker track(TempTableTracker ttt) } } - - private DbSchema getSchema() - { - return schema; - } - - public synchronized void delete() { - if (deleted) - return; - - state.markDeleted(); - sqlDelete(); - - deleted = true; - untrack(qualifiedName, schemaName, tableName); - } - - - private boolean sqlDelete() - { - _log.debug("Deleting table " + schema.getName() + "." + tableName); - schema.dropTableIfExists(tableName); - return true; + state.run(); } @@ -296,7 +256,7 @@ else if (s.charAt(0) == '-') tempTableLog.setLength(0); for (TempTableTracker ttt : createdTableNames.values()) { - if (!ttt.deleted) + if (!ttt.state.deleted) appendToLog("+" + ttt.schemaName + "\t" + ttt.tableName + "\n"); } } @@ -329,9 +289,7 @@ public void shutdownStarted() { for (TempTableTracker ttt : createdTableNames.values()) { - ttt.state.markDeleted(); - ttt.sqlDelete(); - ttt.deleted = true; + ttt.state.run(); } } From f519901dc8a08f5692dc073b367a9af6b2e359f2 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Thu, 15 Jan 2026 10:33:02 -0800 Subject: [PATCH 3/4] Simplify cleaning --- .../org/labkey/api/data/TempTableTracker.java | 9 ++-- .../labkey/api/util/CheckedInputStream.java | 45 ++++++++++--------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/api/src/org/labkey/api/data/TempTableTracker.java b/api/src/org/labkey/api/data/TempTableTracker.java index 2cf94d7a06a..d62b76b4c31 100644 --- a/api/src/org/labkey/api/data/TempTableTracker.java +++ b/api/src/org/labkey/api/data/TempTableTracker.java @@ -47,6 +47,8 @@ public class TempTableTracker private final String schemaName; private final String tableName; private final String qualifiedName; + private final Cleaner.Cleanable cleanable; + private final CleanupState state; private static class CleanupState implements Runnable { @@ -78,15 +80,13 @@ public void run() } } - private final CleanupState state; - private TempTableTracker(DbSchema schema, String tableName, Object ref) { this.schemaName = schema.getName(); this.tableName = tableName; this.qualifiedName = this.schemaName + "." + this.tableName; this.state = new CleanupState(schema, tableName, qualifiedName, schemaName); - cleaner.register(ref, state); + cleanable = cleaner.register(ref, state); } @@ -144,10 +144,9 @@ private static TempTableTracker track(TempTableTracker ttt) public synchronized void delete() { - state.run(); + cleanable.clean(); } - private static void untrack(String qualifiedName, String schemaName, String tableName) { _log.debug("untrack(" + qualifiedName + ")"); diff --git a/api/src/org/labkey/api/util/CheckedInputStream.java b/api/src/org/labkey/api/util/CheckedInputStream.java index ecd50b70ee0..9c37b0edb58 100644 --- a/api/src/org/labkey/api/util/CheckedInputStream.java +++ b/api/src/org/labkey/api/util/CheckedInputStream.java @@ -15,8 +15,9 @@ */ package org.labkey.api.util; -import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.labkey.api.miniprofiler.MiniProfiler; +import org.labkey.api.util.logging.LogHelper; import java.io.IOException; import java.io.InputStream; @@ -27,10 +28,11 @@ * User: adam * Date: 7/2/12 */ - public class CheckedInputStream extends InputStreamWrapper { private static final Cleaner CLEANER = Cleaner.create(); + public static final Logger LOG = LogHelper.getLogger(CheckedInputStream.class, "Utility to ensure InputStreams are closed"); + private final State _state; private static class State implements Runnable { @@ -49,36 +51,39 @@ public void run() { if (!_closed) { - LogManager.getLogger(CheckedInputStream.class).error("InputStream was not closed. Creation stacktrace:" + ExceptionUtil.renderStackTrace(_creationStackTrace)); - try - { - _is.close(); - } - catch (IOException e) - { - LogManager.getLogger(CheckedInputStream.class).error("Failed to close InputStream", e); - } - finally - { - _closed = true; - } + LOG.error("InputStream was not closed. Creation stacktrace:" + ExceptionUtil.renderStackTrace(_creationStackTrace)); + close(); } } - } - private final Cleaner.Cleanable _cleanable; + private void close() + { + try + { + _is.close(); + } + catch (IOException e) + { + LOG.error("Failed to close InputStream", e); + } + finally + { + _closed = true; + } + } + } public CheckedInputStream(InputStream is) { super(is); StackTraceElement[] creationStackTrace = MiniProfiler.getTroubleshootingStackTrace(); - State state = new State(is, creationStackTrace); - _cleanable = CLEANER.register(this, state); + _state = new State(is, creationStackTrace); + CLEANER.register(this, _state); } @Override public void close() throws IOException { - _cleanable.clean(); + _state.close(); } } From 421ff892e9e6b00c334403c980e99854cd444f3c Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Thu, 15 Jan 2026 13:45:17 -0800 Subject: [PATCH 4/4] Stop checking Tomcat version since we embed it --- api/src/org/labkey/api/ApiModule.java | 2 - .../org/labkey/api/module/ModuleLoader.java | 20 --- .../org/labkey/api/module/TomcatVersion.java | 129 ------------------ .../bootstrap/CoreWarningProvider.java | 15 +- 4 files changed, 5 insertions(+), 161 deletions(-) delete mode 100644 api/src/org/labkey/api/module/TomcatVersion.java diff --git a/api/src/org/labkey/api/ApiModule.java b/api/src/org/labkey/api/ApiModule.java index aea66d0ac4a..cd6765adee2 100644 --- a/api/src/org/labkey/api/ApiModule.java +++ b/api/src/org/labkey/api/ApiModule.java @@ -106,7 +106,6 @@ import org.labkey.api.module.ModuleLoader; import org.labkey.api.module.ModuleLoader.StartupPropertyStartupListener; import org.labkey.api.module.ModuleXml; -import org.labkey.api.module.TomcatVersion; import org.labkey.api.query.AbstractQueryUpdateService; import org.labkey.api.query.AliasManager; import org.labkey.api.query.DetailsURL; @@ -522,7 +521,6 @@ public void registerServlets(ServletContext servletCtx) Table.TestCase.class, TableSelectorTestCase.class, TempTableInClauseGenerator.TestCase.class, - TomcatVersion.TestCase.class, URLHelper.TestCase.class, UserManager.TestCase.class, ViewCategoryManager.TestCase.class, diff --git a/api/src/org/labkey/api/module/ModuleLoader.java b/api/src/org/labkey/api/module/ModuleLoader.java index 1f3064b3b06..b487ce09903 100644 --- a/api/src/org/labkey/api/module/ModuleLoader.java +++ b/api/src/org/labkey/api/module/ModuleLoader.java @@ -173,7 +173,6 @@ public class ModuleLoader implements MemTrackerListener, ShutdownListener private static Throwable _startupFailure = null; private static boolean _newInstall = false; - private static TomcatVersion _tomcatVersion = null; private static JavaVersion _javaVersion = null; private static final String BANNER = """ @@ -535,8 +534,6 @@ private void doInit(Execution execution) throws ServletException AppProps.getInstance().setContextPath(_servletContext.getContextPath()); - setTomcatVersion(); - File root = FileUtil.getAbsoluteCaseSensitiveFile(new File(_servletContext.getRealPath(""))).getParentFile(); FileLike labkeyRoot = new FileSystemLike.Builder(root).readwrite().noMemCheck().root(); _webappDir = labkeyRoot.resolveChild("labkeyWebapp"); @@ -1399,23 +1396,6 @@ public JavaVersion getJavaVersion() return _javaVersion; } - /** - * Sets the running Tomcat version, if servlet container is recognized and supported. Otherwise, ConfigurationException is thrown and server fails to start. - *

- * Warnings for deprecated Tomcat versions are handled in CoreWarningProvider. - * - * @throws ConfigurationException if Tomcat version is not recognized or supported - */ - private void setTomcatVersion() - { - _tomcatVersion = TomcatVersion.get(); - } - - public TomcatVersion getTomcatVersion() - { - return _tomcatVersion; - } - /** * Initialize and update the Core module first. We want to change the core tables before we display pages, request * login, check permissions, or initialize any of the other modules. diff --git a/api/src/org/labkey/api/module/TomcatVersion.java b/api/src/org/labkey/api/module/TomcatVersion.java deleted file mode 100644 index 73deb4a0760..00000000000 --- a/api/src/org/labkey/api/module/TomcatVersion.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2017-2018 LabKey Corporation - * - * Licensed 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. - */ -package org.labkey.api.module; - -import org.jetbrains.annotations.NotNull; -import org.junit.Assert; -import org.junit.Test; -import org.labkey.api.util.ConfigurationException; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * Enum that specifies the versions of Apache Tomcat that LabKey supports plus their properties - * - * Created by adam on 5/27/2017. - */ -public enum TomcatVersion -{ - TOMCAT_UNSUPPORTED(-1, true), - TOMCAT_10_1(101, false), - TOMCAT_FUTURE(Integer.MAX_VALUE, true); - - private final int _version; - private final boolean _deprecated; - - TomcatVersion(int version, boolean deprecated) - { - _version = version; - _deprecated = deprecated; - } - - // Should LabKey warn administrators that support for this Tomcat version will be removed soon? - public boolean isDeprecated() - { - return _deprecated; - } - - private static final String APACHE_TOMCAT_SERVER_NAME_PREFIX = "Apache Tomcat/"; - - private final static Map VERSION_MAP = Arrays.stream(values()) - .collect(Collectors.toMap(jv->jv._version, jv->jv)); - - private final static int MAX_KNOWN_VERSION = Arrays.stream(values()) - .filter(v->TOMCAT_FUTURE != v) - .map(v->v._version) - .max(Comparator.naturalOrder()) - .orElseThrow(); - - public static TomcatVersion get() - { - String serverInfo = ModuleLoader.getServletContext().getServerInfo(); - - if (serverInfo.startsWith(APACHE_TOMCAT_SERVER_NAME_PREFIX)) - { - String[] versionParts = serverInfo.substring(APACHE_TOMCAT_SERVER_NAME_PREFIX.length()).split("\\."); - - if (versionParts.length > 1) - { - int majorVersion = Integer.valueOf(versionParts[0]); - int minorVersion = Integer.valueOf(versionParts[1]); - - TomcatVersion tv = get(majorVersion * 10 + minorVersion); - - if (TOMCAT_UNSUPPORTED != tv) - return tv; - } - } - - throw new ConfigurationException("Unsupported Tomcat version: " + serverInfo + ". LabKey Server requires Apache Tomcat 10.1.x."); - } - - private static @NotNull TomcatVersion get(int version) - { - if (version > MAX_KNOWN_VERSION) - { - return TOMCAT_FUTURE; - } - else - { - TomcatVersion tv = VERSION_MAP.get(version); - return null != tv ? tv : TOMCAT_UNSUPPORTED; - } - } - - public static class TestCase extends Assert - { - @Test - public void test() - { - // Good - test(101, TOMCAT_10_1); - - // Future - test(110, TOMCAT_FUTURE); - test(120, TOMCAT_FUTURE); - - // Bad - test(100, TOMCAT_UNSUPPORTED); - test(90, TOMCAT_UNSUPPORTED); - test(85, TOMCAT_UNSUPPORTED); - test(80, TOMCAT_UNSUPPORTED); - test(70, TOMCAT_UNSUPPORTED); - test(60, TOMCAT_UNSUPPORTED); - test(50, TOMCAT_UNSUPPORTED); - test(40, TOMCAT_UNSUPPORTED); - } - - private void test(int version, TomcatVersion expectedVersion) - { - Assert.assertEquals(get(version), expectedVersion); - } - } -} diff --git a/core/src/org/labkey/core/view/template/bootstrap/CoreWarningProvider.java b/core/src/org/labkey/core/view/template/bootstrap/CoreWarningProvider.java index a30729155af..ff03803248c 100644 --- a/core/src/org/labkey/core/view/template/bootstrap/CoreWarningProvider.java +++ b/core/src/org/labkey/core/view/template/bootstrap/CoreWarningProvider.java @@ -16,6 +16,7 @@ package org.labkey.core.view.template.bootstrap; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -296,21 +297,15 @@ public static Set collectAllDeployedApps() private void addTomcatWarnings(Warnings warnings, boolean showAllWarnings) { - if (showAllWarnings || ModuleLoader.getInstance().getTomcatVersion().isDeprecated()) - { - String serverInfo = ModuleLoader.getServletContext().getServerInfo(); - addStandardWarning(warnings, "The deployed version of Tomcat, " + serverInfo + ", is not supported.", "supported", "Supported Technologies page"); - } - try { Set deployedWebapps = new HashSet<>(collectAllDeployedApps()); deployedWebapps.remove(StringUtils.strip(AppProps.getInstance().getContextPath(),"/")); boolean defaultTomcatWebappFound = deployedWebapps.stream().anyMatch(webapp -> - StringUtils.startsWithIgnoreCase(webapp,"docs") || - StringUtils.startsWithIgnoreCase(webapp,"host-manager") || - StringUtils.startsWithIgnoreCase(webapp,"examples") || - StringUtils.startsWithIgnoreCase(webapp,"manager") + Strings.CI.startsWith(webapp,"docs") || + Strings.CI.startsWith(webapp,"host-manager") || + Strings.CI.startsWith(webapp,"examples") || + Strings.CI.startsWith(webapp,"manager") ); if (showAllWarnings || (defaultTomcatWebappFound && !AppProps.getInstance().isDevMode()))