Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 8, 2026

  • Investigate CI logs to confirm the issue exists in CI environment
  • Confirm that CI is also getting HTTP 500 errors (the workflow doesn't fail because it doesn't enforce the check)
  • Analyze web.xml for missing <jsp-config> / taglib declarations
  • Run mvn dependency:tree -Dverbose for hidden transitive conflicts
  • Fix: Add explicit JSTL TLD declarations to web.xml (treebase-web)
  • Fix: Extract TLD files from jakarta.servlet.jsp.jstl-1.2.6.jar to WEB-INF/tld/ (treebase-web)
  • Fix: Update CI workflow to fail on HTTP 500 errors
  • Fix: Add unzip to Dockerfile.dev for WAR extraction
  • Fix: Add maven-war-plugin 3.3.1 to oai-pmh_data_provider for Java 17 compatibility
  • Fix: Copy DTD files to /tmp/dtd in Docker entrypoint for validator configuration
  • Fix: Add spring-security-taglibs dependency and security.tld for Spring Security tags
  • Fix: Apply same JSTL fix to data_provider_web module
    • Added common/taglibs.jsp with JSTL core, fmt, and SiteMesh taglib declarations
    • Added common/messages.jsp for error/success message display
    • Added <jsp-config> section to web.xml mapping both JSTL 1.0 and 1.1+ URIs
    • Copied c.tld and fmt.tld to WEB-INF/tld/
  • Verify fix in CI

Analysis Summary

Why Docker Worked But CI Failed

  • Docker only deploys treebase-web, which had the fix applied
  • CI tests both treebase-web AND data_provider_web
  • data_provider_web was missing the same JSTL configuration

Fix Applied (commit 93204e1)

The data_provider_web JSP files referenced /common/taglibs.jsp which didn't exist. This caused ClassNotFoundException: org.apache.jsp.index_jsp when the JSP container tried to compile the index.jsp.

Created:

  • common/taglibs.jsp - declares JSTL core, fmt, and SiteMesh page/decorator taglibs
  • common/messages.jsp - displays error/success messages
  • WEB-INF/tld/c.tld and fmt.tld - TLD files for JSTL
  • <jsp-config> section in web.xml - maps both JSTL 1.0 URIs (used by existing JSPs) and JSTL 1.1+ URIs to the TLD files
Original prompt

There is a problem that keeps arising despite our best efforts across multiple PRs. It is vital that this is resolved but it requires careful analysis, apparently. The symptoms are as follows:

  • it manifests always, whenever we attempt to open the homepage of treebase-web, i.e. http://localhost:8080/treebase-web/
  • it looks like a race condition where either one or another stack trace appears instead of the web page
  • it looks like a race condition between two conflicting versions of a dependency, whose loading order is undefined
  • the beginning of the stack trace is in the same location each time, namely org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
  • the two distinct traces (where either one or the other appears) are given below

Either this trace appears:

org.apache.jasper.JasperException: org.apache.jasper.JasperException: java.lang.ClassNotFoundException: org.apache.jsp.index_jsp
	org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:561)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:397)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:349)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:300)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

Or this one:

org.apache.jasper.JasperException: org.apache.jasper.JasperException: /index.jsp (line: [1], column: [1]) The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be resolved in either web.xml or the jar files deployed with this application
	org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:561)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:397)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:349)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:300)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

Reloading the page switches between these traces in an unpredictable manner.

To reiterate, this has kept bugging us despite numerous attempts to fix this, so it requires meticulous, comprehensive, and holistic analysis. Our thinking thus far is that it might be that two conflicting versions of one of the classes in the trace are being loaded, and the switching between them is because of the indeterminate order in which versions of this class are being loaded.

Probably, this means going through the entire dependency graph and identifying which competing versions of which class are being loaded. Then, we need to figure out (transitively), who is depending on these classes. This might be in the project's dependency graph itself, or in tomcat.

What we've tried so far is to exclude various transitively loaded packages from the project dependency graph. However, this has never worked. Therefore, other paths to resolution must also be considered. Including changing the version of tomcat itself.

Start out with an analysis that includes multiple, distinct hypotheses for what might be going on. From these, work out multiple, distinct resolution pathways. Do not immediately choose on of these paths. Rather, present the options and allow me to decide.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@rvosa rvosa marked this pull request as ready for review January 8, 2026 14:53
Copilot AI changed the title [WIP] Fix race condition on homepage loading Analysis: HTTP 500 on homepage - JSTL/JSP race condition investigation Jan 8, 2026
Copilot AI requested a review from rvosa January 8, 2026 15:08
@rvosa
Copy link
Contributor

rvosa commented Jan 8, 2026

@copilot

Hypotheses 1 and 2 seem unlikely because the problem persists rather than presenting only on first launch. I am unsure, but it seems unlikely that it is a minor version mismatch either in tomcat or JSTL (hypotheses 3 and 5), given that in both cases the differences are only in the third, smallest numbers. Assuming that semantic versioning is followed correctly, those should only differ in bug fixes. It is conceivable that hypothesis 4 is happening because we have been doing a lot of upgrades without ever testing the web UI so maybe it appeared during one of those upgrades without us having noticed (after all, the CI kept passing). Perhaps the web.xml now needs more configuration than in older versions of the dependency stack. Therefore, please start with an analysis of web.xml for missing <jsp-config> / taglib declarations. But please also run mvn dependency:tree -Dverbose to check for hidden transitive conflicts.

….xml

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot

Hypotheses 1 and 2 seem unlikely because the problem persists rather than presenting only on first launch. I am unsure, but it seems unlikely that it is a minor version mismatch either in...

Completed analysis and fix in commit 77e3b51.

web.xml Analysis: Found the web.xml was missing a <jsp-config> section with taglib declarations. The Jakarta JSTL 1.2.6 JAR contains TLD files in META-INF/, but the JSP container's TLD scanner wasn't reliably discovering them.

Dependency Tree Analysis: No conflicting JSTL/servlet/JSP JARs found. The dependency graph is clean.

Fix Applied:

  1. Added explicit <jsp-config> section to web.xml mapping JSTL URIs to local TLD files
  2. Extracted c.tld, fmt.tld, and fn.tld from jakarta.servlet.jsp.jstl-1.2.6.jar to WEB-INF/tld/
  3. Updated CI workflow to fail on HTTP 500 errors (was silently passing)

This ensures reliable TLD discovery regardless of classloader behavior.

@rvosa
Copy link
Contributor

rvosa commented Jan 8, 2026

@copilot I think you are on the right track, given what I'm seeing in the CI. It appears we are only getting the error ClassNotFoundException: org.apache.jsp.index_jsp, but no longer the other one. This suggests that your fix in commit 77e3b51 resolved the other error (The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be resolved). However, I can't replicate this in the Docker version locally because unzip is missing:

treebase-web-dev   | ========================================
treebase-web-dev   | TreeBASE Development Container Starting
treebase-web-dev   | ========================================
treebase-web-dev   | Waiting for PostgreSQL to be ready...
treebase-web-dev   | postgres:5432 - accepting connections
treebase-web-dev   | PostgreSQL is ready!
treebase-web-dev   | WAR file already exists, skipping build...
treebase-web-dev   | Extracting WEB-INF from WAR file...
treebase-web-dev   | /entrypoint.sh: line 44: unzip: command not found

Please fix that!

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot I think you are on the right track, given what I'm seeing in the CI. It appears we are only getting the error ClassNotFoundException: org.apache.jsp.index_jsp, but no longer the other one. ...

Added unzip to the Dockerfile.dev package installation in commit a49ca53. The development container should now be able to extract the WEB-INF directory from the WAR file.

@rvosa
Copy link
Contributor

rvosa commented Jan 8, 2026

@copilot there is now a problem building the data_provider_web in the Docker:

treebase-web-dev   | [INFO] --- maven-war-plugin:2.2:war (default-war) @ data_provider_web ---
treebase-web-dev   | [WARNING] Error injecting: org.apache.maven.plugin.war.WarMojo
treebase-web-dev   | com.google.inject.ProvisionException: Unable to provision, see the following errors:
treebase-web-dev   | 
treebase-web-dev   | 1) Error injecting constructor, java.lang.ExceptionInInitializerError: Cannot access defaults field of Properties
treebase-web-dev   |   at org.apache.maven.plugin.war.WarMojo.<init>(Unknown Source)
treebase-web-dev   |   while locating org.apache.maven.plugin.war.WarMojo
treebase-web-dev   | 
treebase-web-dev   | 1 error
treebase-web-dev   |     at com.google.inject.internal.InternalProvisionException.toProvisionException (InternalProvisionException.java:226)
treebase-web-dev   |     at com.google.inject.internal.InjectorImpl$1.get (InjectorImpl.java:1097)
treebase-web-dev   |     at com.google.inject.internal.InjectorImpl.getInstance (InjectorImpl.java:1131)
treebase-web-dev   |     at org.eclipse.sisu.space.AbstractDeferredClass.get (AbstractDeferredClass.java:48)
treebase-web-dev   |     at com.google.inject.internal.ProviderInternalFactory.provision (ProviderInternalFactory.java:85)
treebase-web-dev   |     at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision (InternalFactoryToInitializableAdapter.java:57)
treebase-web-dev   |     at com.google.inject.internal.ProviderInternalFactory$1.call (ProviderInternalFactory.java:66)
treebase-web-dev   |     at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision (ProvisionListenerStackCallback.java:112)
treebase-web-dev   |     at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision (ProvisionListenerStackCallback.java:127)
treebase-web-dev   |     at com.google.inject.internal.ProvisionListenerStackCallback.provision (ProvisionListenerStackCallback.java:66)
treebase-web-dev   |     at com.google.inject.internal.ProviderInternalFactory.circularGet (ProviderInternalFactory.java:61)
treebase-web-dev   |     at com.google.inject.internal.InternalFactoryToInitializableAdapter.get (InternalFactoryToInitializableAdapter.java:47)
treebase-web-dev   |     at com.google.inject.internal.InjectorImpl$1.get (InjectorImpl.java:1094)
treebase-web-dev   |     at org.eclipse.sisu.inject.Guice4$1.get (Guice4.java:162)
treebase-web-dev   |     at org.eclipse.sisu.inject.LazyBeanEntry.getValue (LazyBeanEntry.java:81)
treebase-web-dev   |     at org.eclipse.sisu.plexus.LazyPlexusBean.getValue (LazyPlexusBean.java:51)
treebase-web-dev   |     at org.codehaus.plexus.DefaultPlexusContainer.lookup (DefaultPlexusContainer.java:263)
treebase-web-dev   |     at org.codehaus.plexus.DefaultPlexusContainer.lookup (DefaultPlexusContainer.java:255)
treebase-web-dev   |     at org.apache.maven.plugin.internal.DefaultMavenPluginManager.getConfiguredMojo (DefaultMavenPluginManager.java:520)
treebase-web-dev   |     at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:124)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:370)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
treebase-web-dev   |     at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:298)
treebase-web-dev   |     at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
treebase-web-dev   |     at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
treebase-web-dev   |     at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
treebase-web-dev   |     at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
treebase-web-dev   |     at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
treebase-web-dev   |     at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
treebase-web-dev   |     at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
treebase-web-dev   |     at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
treebase-web-dev   |     at java.lang.reflect.Method.invoke (Method.java:569)
treebase-web-dev   |     at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:283)
treebase-web-dev   |     at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:226)
treebase-web-dev   |     at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:407)
treebase-web-dev   |     at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:348)
treebase-web-dev   | Caused by: java.lang.ExceptionInInitializerError: Cannot access defaults field of Properties
treebase-web-dev   |     at com.thoughtworks.xstream.converters.collections.PropertiesConverter.<clinit> (PropertiesConverter.java:46)
treebase-web-dev   |     at com.thoughtworks.xstream.XStream.setupConverters (XStream.java:647)
treebase-web-dev   |     at com.thoughtworks.xstream.XStream.<init> (XStream.java:445)
treebase-web-dev   |     at com.thoughtworks.xstream.XStream.<init> (XStream.java:385)
treebase-web-dev   |     at com.thoughtworks.xstream.XStream.<init> (XStream.java:342)
treebase-web-dev   |     at org.apache.maven.plugin.war.util.WebappStructureSerializer.<clinit> (WebappStructureSerializer.java:47)
treebase-web-dev   |     at org.apache.maven.plugin.war.AbstractWarMojo.<init> (AbstractWarMojo.java:316)
treebase-web-dev   |     at org.apache.maven.plugin.war.WarMojo.<init> (WarMojo.java:49)
treebase-web-dev   |     at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0 (Native Method)
treebase-web-dev   |     at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:77)
treebase-web-dev   |     at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:45)
treebase-web-dev   |     at java.lang.reflect.Constructor.newInstanceWithCaller (Constructor.java:500)
treebase-web-dev   |     at java.lang.reflect.Constructor.newInstance (Constructor.java:481)
treebase-web-dev   |     at com.google.inject.internal.DefaultConstructionProxyFactory$ReflectiveProxy.newInstance (DefaultConstructionProxyFactory.java:126)
treebase-web-dev   |     at com.google.inject.internal.ConstructorInjector.provision (ConstructorInjector.java:114)
treebase-web-dev   |     at com.google.inject.internal.ConstructorInjector.access$000 (ConstructorInjector.java:32)
treebase-web-dev   |     at com.google.inject.internal.ConstructorInjector$1.call (ConstructorInjector.java:98)
treebase-web-dev   |     at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision (ProvisionListenerStackCallback.java:112)
treebase-web-dev   |     at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision (ProvisionListenerStackCallback.java:127)
treebase-web-dev   |     at com.google.inject.internal.ProvisionListenerStackCallback.provision (ProvisionListenerStackCallback.java:66)
treebase-web-dev   |     at com.google.inject.internal.ConstructorInjector.construct (ConstructorInjector.java:93)
treebase-web-dev   |     at com.google.inject.internal.ConstructorBindingImpl$Factory.get (ConstructorBindingImpl.java:306)
treebase-web-dev   |     at com.google.inject.internal.InjectorImpl$1.get (InjectorImpl.java:1094)
treebase-web-dev   |     at com.google.inject.internal.InjectorImpl.getInstance (InjectorImpl.java:1131)
treebase-web-dev   |     at org.eclipse.sisu.space.AbstractDeferredClass.get (AbstractDeferredClass.java:48)
treebase-web-dev   |     at com.google.inject.internal.ProviderInternalFactory.provision (ProviderInternalFactory.java:85)
treebase-web-dev   |     at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision (InternalFactoryToInitializableAdapter.java:57)
treebase-web-dev   |     at com.google.inject.internal.ProviderInternalFactory$1.call (ProviderInternalFactory.java:66)
treebase-web-dev   |     at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision (ProvisionListenerStackCallback.java:112)
treebase-web-dev   |     at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision (ProvisionListenerStackCallback.java:127)
treebase-web-dev   |     at com.google.inject.internal.ProvisionListenerStackCallback.provision (ProvisionListenerStackCallback.java:66)
treebase-web-dev   |     at com.google.inject.internal.ProviderInternalFactory.circularGet (ProviderInternalFactory.java:61)
treebase-web-dev   |     at com.google.inject.internal.InternalFactoryToInitializableAdapter.get (InternalFactoryToInitializableAdapter.java:47)
treebase-web-dev   |     at com.google.inject.internal.InjectorImpl$1.get (InjectorImpl.java:1094)
treebase-web-dev   |     at org.eclipse.sisu.inject.Guice4$1.get (Guice4.java:162)
treebase-web-dev   |     at org.eclipse.sisu.inject.LazyBeanEntry.getValue (LazyBeanEntry.java:81)
treebase-web-dev   |     at org.eclipse.sisu.plexus.LazyPlexusBean.getValue (LazyPlexusBean.java:51)
treebase-web-dev   |     at org.codehaus.plexus.DefaultPlexusContainer.lookup (DefaultPlexusContainer.java:263)
treebase-web-dev   |     at org.codehaus.plexus.DefaultPlexusContainer.lookup (DefaultPlexusContainer.java:255)
treebase-web-dev   |     at org.apache.maven.plugin.internal.DefaultMavenPluginManager.getConfiguredMojo (DefaultMavenPluginManager.java:520)
treebase-web-dev   |     at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:124)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:370)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
treebase-web-dev   |     at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
treebase-web-dev   |     at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:298)
treebase-web-dev   |     at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
treebase-web-dev   |     at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
treebase-web-dev   |     at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
treebase-web-dev   |     at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
treebase-web-dev   |     at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
treebase-web-dev   |     at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
treebase-web-dev   |     at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
treebase-web-dev   |     at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
treebase-web-dev   |     at java.lang.reflect.Method.invoke (Method.java:569)
treebase-web-dev   |     at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:283)
treebase-web-dev   |     at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:226)
treebase-web-dev   |     at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:407)
treebase-web-dev   |     at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:348)
treebase-web-dev   | [INFO] ------------------------------------------------------------------------
treebase-web-dev   | [INFO] Reactor Summary:
treebase-web-dev   | [INFO] 
treebase-web-dev   | [INFO] Treebase 1.0-SNAPSHOT .............................. SUCCESS [  0.031 s]
treebase-web-dev   | [INFO] treebase-core 1.0-SNAPSHOT ......................... SUCCESS [  6.594 s]
treebase-web-dev   | [INFO] treebase-web 1.0-SNAPSHOT .......................... SUCCESS [  7.248 s]
treebase-web-dev   | [INFO] oai-pmh_data_provider 0.0.1-SNAPSHOT ............... SUCCESS [  0.001 s]
treebase-web-dev   | [INFO] data_provider_web 0.0.1-SNAPSHOT ................... FAILURE [  0.356 s]
treebase-web-dev   | [INFO] ------------------------------------------------------------------------
treebase-web-dev   | [INFO] BUILD FAILURE
treebase-web-dev   | [INFO] ------------------------------------------------------------------------
treebase-web-dev   | [INFO] Total time:  14.317 s
treebase-web-dev   | [INFO] Finished at: 2026-01-08T20:16:42Z
treebase-web-dev   | [INFO] ------------------------------------------------------------------------
treebase-web-dev   | [ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project data_provider_web: Execution default-war of goal org.apache.maven.plugins:maven-war-plugin:2.2:war failed: Unable to load the mojo 'war' in the plugin 'org.apache.maven.plugins:maven-war-plugin:2.2' due to an API incompatibility: org.codehaus.plexus.component.repository.exception.ComponentLookupException: Cannot access defaults field of Properties
treebase-web-dev   | [ERROR] -----------------------------------------------------
treebase-web-dev   | [ERROR] realm =    plugin>org.apache.maven.plugins:maven-war-plugin:2.2
treebase-web-dev   | [ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
treebase-web-dev   | [ERROR] urls[0] = file:/root/.m2/repository/org/apache/maven/plugins/maven-war-plugin/2.2/maven-war-plugin-2.2.jar
treebase-web-dev   | [ERROR] urls[1] = file:/root/.m2/repository/org/apache/maven/reporting/maven-reporting-api/2.0.6/maven-reporting-api-2.0.6.jar
treebase-web-dev   | [ERROR] urls[2] = file:/root/.m2/repository/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-7/doxia-sink-api-1.0-alpha-7.jar
treebase-web-dev   | [ERROR] urls[3] = file:/root/.m2/repository/commons-cli/commons-cli/1.0/commons-cli-1.0.jar
treebase-web-dev   | [ERROR] urls[4] = file:/root/.m2/repository/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-4/plexus-interactivity-api-1.0-alpha-4.jar
treebase-web-dev   | [ERROR] urls[5] = file:/root/.m2/repository/org/apache/maven/maven-archiver/2.5/maven-archiver-2.5.jar
treebase-web-dev   | [ERROR] urls[6] = file:/root/.m2/repository/org/codehaus/plexus/plexus-io/2.0.2/plexus-io-2.0.2.jar
treebase-web-dev   | [ERROR] urls[7] = file:/root/.m2/repository/org/codehaus/plexus/plexus-archiver/2.1/plexus-archiver-2.1.jar
treebase-web-dev   | [ERROR] urls[8] = file:/root/.m2/repository/org/codehaus/plexus/plexus-interpolation/1.15/plexus-interpolation-1.15.jar
treebase-web-dev   | [ERROR] urls[9] = file:/root/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar
treebase-web-dev   | [ERROR] urls[10] = file:/root/.m2/repository/com/thoughtworks/xstream/xstream/1.3.1/xstream-1.3.1.jar
treebase-web-dev   | [ERROR] urls[11] = file:/root/.m2/repository/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar
treebase-web-dev   | [ERROR] urls[12] = file:/root/.m2/repository/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.jar
treebase-web-dev   | [ERROR] urls[13] = file:/root/.m2/repository/org/apache/maven/shared/maven-filtering/1.0-beta-2/maven-filtering-1.0-beta-2.jar
treebase-web-dev   | [ERROR] Number of foreign imports: 1
treebase-web-dev   | [ERROR] import: Entry[import  from realm ClassRealm[maven.api, parent: null]]
treebase-web-dev   | [ERROR] 
treebase-web-dev   | [ERROR] -----------------------------------------------------
treebase-web-dev   | [ERROR] -> [Help 1]

…tibility

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot there is now a problem building the data_provider_web in the Docker:

...

The error was caused by the default maven-war-plugin 2.2 being incompatible with Java 17. The "Cannot access defaults field of Properties" error occurs because Java 17 has stricter module access controls. Fixed by adding maven-war-plugin 3.3.1 to oai-pmh_data_provider/pom.xml in commit 7ae0f39.

@rvosa
Copy link
Contributor

rvosa commented Jan 8, 2026

@copilot the next Docker building error has manifested:

treebase-web-dev   | 08-Jan-2026 20:25:13.688 INFO [main] java.util.ArrayList.forEach Name = TreebaseDB Ignoring unknown property: value of "The JNDI DataSource for the TreeBASE postgres instance." for "description" property
treebase-web-dev   | 08-Jan-2026 20:25:13.741 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars 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.
treebase-web-dev   | 20:25:15.280 [main] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
treebase-web-dev   | org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validatorFactory' defined in ServletContext resource [/WEB-INF/treebase-validation.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
treebase-web-dev   | PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'validationConfigLocations' threw exception; nested exception is org.springframework.beans.FatalBeanException: Unable to read validation configuration due to IOException.; nested exception is java.io.FileNotFoundException: /tmp/dtd/validator_1_3_0.dtd (No such file or directory)
treebase-web-dev   |    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1744) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1452) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:209) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) ~[spring-context-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:591) ~[spring-context-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:399) ~[spring-web-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:278) [spring-web-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103) [spring-web-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.cipres.treebase.web.listeners.StartupListener.contextInitialized(StartupListener.java:46) [classes/:?]
treebase-web-dev   |    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4047) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4489) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:597) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:569) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:608) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:677) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1836) [catalina.jar:9.0.113]
treebase-web-dev   |    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
treebase-web-dev   |    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
treebase-web-dev   |    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82) [tomcat-util.jar:9.0.113]
treebase-web-dev   |    at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123) [?:?]
treebase-web-dev   |    at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:572) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:463) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1576) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:389) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:336) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:774) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:726) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1201) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1191) [catalina.jar:9.0.113]
treebase-web-dev   |    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
treebase-web-dev   |    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82) [tomcat-util.jar:9.0.113]
treebase-web-dev   |    at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) [?:?]
treebase-web-dev   |    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:747) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:209) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:410) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:872) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) [catalina.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.startup.Catalina.start(Catalina.java:736) [catalina.jar:9.0.113]
treebase-web-dev   |    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
treebase-web-dev   |    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
treebase-web-dev   |    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
treebase-web-dev   |    at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[?:?]
treebase-web-dev   |    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342) [bootstrap.jar:9.0.113]
treebase-web-dev   |    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473) [bootstrap.jar:9.0.113]
treebase-web-dev   | Caused by: org.springframework.beans.PropertyBatchUpdateException: Failed properties: Property 'validationConfigLocations' threw exception; nested exception is org.springframework.beans.FatalBeanException: Unable to read validation configuration due to IOException.; nested exception is java.io.FileNotFoundException: /tmp/dtd/validator_1_3_0.dtd (No such file or directory)
treebase-web-dev   |    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:135) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:79) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1740) ~[spring-beans-5.3.39.jar:5.3.39]
treebase-web-dev   |    ... 55 more
treebase-web-dev   | 08-Jan-2026 20:25:15.300 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
treebase-web-dev   | 08-Jan-2026 20:25:15.301 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal Context [/treebase-web] startup failed due to previous errors

…ration

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot the next Docker building error has manifested:

...

The error occurred because the validation.xml file references ./dtd/validator_1_3_0.dtd using a relative path. When Tomcat starts with /tmp as the working directory, Spring tries to resolve this as /tmp/dtd/validator_1_3_0.dtd. Fixed by copying DTD files to /tmp/dtd/ in the Docker entrypoint script in commit 5a2b26d. This matches the workaround already used in the CI workflow.

@rvosa
Copy link
Contributor

rvosa commented Jan 8, 2026

@copilot the build and deploy now has no errors in the Docker version, but when I access the web page I get an error 500 without a stack trace:

Screenshot 2026-01-08 at 21 36 54

This makes further debugging difficult. How should we proceed? Do we check the error log in the container?

Copy link
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot the build and deploy now has no errors in the Docker version, but when I access the web page I get an error 500 without a stack trace:

<img width="883" height="662" alt="Screenshot 2026-01...

Yes, checking the container logs is the right approach. Run:

docker logs treebase-web-dev 2>&1 | tail -100

Or for the Tomcat catalina.out log specifically:

docker exec treebase-web-dev cat /usr/local/tomcat/logs/catalina.out | tail -200

The blank error page is likely because error-500.jsp itself uses JSTL taglibs (<c:url>, <fmt:message>). If the JSP/JSTL issue is occurring, the error page can't render either - creating a catch-22.

Please share the log output and I'll investigate further.

@rvosa
Copy link
Contributor

rvosa commented Jan 8, 2026

@copilot this is from the localhost log in the Docker:

08-Jan-2026 20:35:47.670 SEVERE [http-nio-8080-exec-5] org.apache.catalina.core.StandardHostValve.custom Exception Processing [ErrorPage[exceptionType=java.lang.Exception, location=/WEB-INF/pages/errors/uncaughtException.jsp]]
        org.apache.jasper.JasperException: org.apache.jasper.JasperException: /WEB-INF/pages/errors/uncaughtException.jsp (line: [1], column: [1]) The absolute uri: [http://www.springframework.org/security/tags] cannot be resolved in either web.xml or the jar files deployed with this application
                at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:561)
                at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:397)
                at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:349)
                at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:300)
                at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:197)
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
                at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:619)
                at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:401)
                at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:338)
                at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:283)
                at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:392)
                at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:277)
                at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
                at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:643)
                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
                at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
                at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
                at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:939)
                at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1831)
                at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
                at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
                at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
                at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
                at java.base/java.lang.Thread.run(Thread.java:840)
        Caused by: org.apache.jasper.JasperException: /WEB-INF/pages/errors/uncaughtException.jsp (line: [1], column: [1]) The absolute uri: [http://www.springframework.org/security/tags] cannot be resolved in either web.xml or the jar files deployed with this application
                at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:29)
                at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:265)
                at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:88)
                at org.apache.jasper.compiler.Parser.processIncludeDirective(Parser.java:334)
                at org.apache.jasper.compiler.Parser.parseIncludeDirective(Parser.java:364)
                at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:455)
                at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1353)
                at org.apache.jasper.compiler.Parser.parse(Parser.java:132)
                at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:240)
                at org.apache.jasper.compiler.ParserController.parse(ParserController.java:103)
                at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:186)
                at org.apache.jasper.compiler.Compiler.compile(Compiler.java:359)
                at org.apache.jasper.compiler.Compiler.compile(Compiler.java:337)
                at org.apache.jasper.compiler.Compiler.compile(Compiler.java:323)
                at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:585)
                at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:371)
                ... 25 more

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot this is from the localhost log in the Docker:

...

The error shows http://www.springframework.org/security/tags taglib URI cannot be resolved. This is the same type of issue as the JSTL tags - the TLD files aren't being discovered by the JSP container.

Fixed in commit eb2a61b by:

  1. Adding the missing spring-security-taglibs dependency to pom.xml
  2. Extracting security.tld from the JAR to WEB-INF/tld/
  3. Adding explicit taglib declaration in web.xml for the Spring Security tags URI

@rvosa
Copy link
Contributor

rvosa commented Jan 8, 2026

@copilot the Docker deployment is now FULLY working! This is great! I can see the web app. However, the CI is still failing. So look carefully how the CI and the Docker differ and apply the fixes from the Docker to the CI.

… files, and jsp-config

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot the Docker deployment is now FULLY working! This is great! I can see the web app. However, the CI is still failing. So look carefully how the CI and the Docker differ and apply the fixes from...

Applied the same JSTL fix to data_provider_web in commit 93204e1. The CI was failing because data_provider_web had the same missing configuration:

  1. Created common/taglibs.jsp and common/messages.jsp (referenced by JSP files but didn't exist)
  2. Added <jsp-config> section to web.xml with both JSTL 1.0 and 1.1+ URI mappings (data_provider_web uses the old JSTL 1.0 URIs)
  3. Copied c.tld and fmt.tld to WEB-INF/tld/

The Docker deployment worked because it only deploys treebase-web, not data_provider_web.

@rvosa rvosa merged commit b714e64 into master Jan 8, 2026
3 checks passed
@rvosa rvosa deleted the copilot/fix-homepage-race-condition branch January 8, 2026 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants