Skip to content

Commit b9ab28b

Browse files
committed
Merge remote-tracking branch 'origin/develop' into fb_mail_transport_via_graph
2 parents 9623f48 + e33d435 commit b9ab28b

4 files changed

Lines changed: 142 additions & 31 deletions

File tree

CLAUDE.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
LabKey Server is a large Java web application platform for biomedical research data management. It uses a modular monolith architecture with 150+ Gradle modules, built on Spring Boot 4 / Spring Framework 7 with embedded Tomcat 11. It targets Java 25 and supports both PostgreSQL and MS SQL Server databases.
8+
9+
## Build Commands
10+
11+
```bash
12+
# Configure IntelliJ IDEA project files
13+
./gradlew ijConfigure
14+
15+
# Select database (populates application.properties from templates)
16+
./gradlew pickPg # PostgreSQL
17+
./gradlew pickMssql # MS SQL Server
18+
19+
# Build and deploy to embedded Tomcat
20+
./gradlew deployApp
21+
22+
# Build a specific module
23+
./gradlew :server:modules:platform:core:build
24+
25+
# Build with a predefined module set
26+
./gradlew -PmoduleSet=community build
27+
28+
# Exclude test modules for faster builds
29+
./gradlew -PexcludeTestModules build
30+
31+
# Build a distribution
32+
./gradlew -PmoduleSet=distributions :distributions:base:dist
33+
```
34+
35+
## Running Tests
36+
37+
**Unit tests** are static `TestCase` inner classes within production source files. They are registered via the module's `getUnitTests()` method and run within the server JVM.
38+
39+
**Integration tests** require a running server and database. They are registered via `getIntegrationTests()`.
40+
41+
**Selenium UI tests** (in `server/testAutomation/`):
42+
```bash
43+
./gradlew :server:testAutomation:initProperties # Generate test.properties
44+
./gradlew :server:testAutomation:uiTests -Psuite=DRT # Run a test suite
45+
```
46+
UI tests require a running LabKey server, a browser driver (ChromeDriver or Geckodriver) on PATH, and configured `test.properties`.
47+
48+
## Architecture
49+
50+
### Module System
51+
52+
Each module lives under `server/modules/` and contains:
53+
- `module.properties` — metadata including `ModuleClass`, `SchemaVersion`, `SupportedDatabases`
54+
- `build.gradle` — uses `org.labkey.build.module` plugin
55+
- A module class extending `SpringModule` (which extends `DefaultModule` implementing `Module`)
56+
57+
Module lifecycle methods in order: `init()``versionUpdate()``afterUpdate()``startup()``startupAfterSpringConfig()``startBackgroundThreads()``destroy()`
58+
59+
In `init()`, modules register controllers via `addController("name", Controller.class)` and set up service implementations. Controllers follow the pattern `*Controller.java`.
60+
61+
### Core Platform Modules (`server/modules/platform/`)
62+
63+
The `api` module provides the core framework (Module interface, SpringModule base class, services, utilities). Other key platform modules: `core` (auth, security, admin), `query` (SQL engine), `experiment`, `study`, `assay`, `pipeline` (job processing), `search`, `audit`, `visualization`.
64+
65+
### Entry Point
66+
67+
`server/embedded/src/org/labkey/embedded/LabKeyServer.java` — a `@SpringBootApplication` that configures embedded Tomcat, SSL/TLS, Content Security Policy, and Log4J2.
68+
69+
### Database
70+
71+
Dual database support (PostgreSQL and MS SQL Server). Configuration lives in `server/configs/application.properties`, populated by `pickPg`/`pickMssql` tasks from `pg.properties`/`mssql.properties` templates. Each module declares its `SchemaVersion` in `module.properties` and manages its own schema migrations.
72+
73+
### Frontend
74+
75+
Mix of JSPs, React (via `@labkey/components`), and ExtJS. Modules with JavaScript/TypeScript have their own `package.json` and use npm builds. Node.js and npm versions are pinned in `gradle.properties` and downloaded during build.
76+
77+
### Distributions
78+
79+
The `distributions/` directory defines 60+ distribution configurations that select which modules to package. Distributions inherit from each other (most inherit from `:distributions:base`). Distribution directory names must not collide with module names.
80+
81+
### Dependency Management
82+
83+
All external library versions are centralized in `gradle.properties` (200+ version properties). The root `build.gradle` forces consistent versions across all modules via `resolutionStrategy`. Always consult before adding, removing, or updating a third-party dependency.
84+
85+
## Coding Conventions
86+
87+
- **Java Streams**: Prefer `Stream` API over traditional for-loops for collection processing.
88+
- **Resources**: Use try-with-resources for automatic resource management.
89+
- **Nullability**: Use `org.jetbrains.annotations.NotNull` and `@Nullable`. Be explicit in public API signatures.
90+
- **Logging**: Use Log4J2. Name the static logger `LOG`, initialized via `LogHelper.getLogger()`:
91+
```java
92+
private static final Logger LOG = LogHelper.getLogger(MyClass.class, "optional description");
93+
```
94+
- **Unit tests**: Create a static `TestCase` inner class extending `Assert` in the same file as production code. Use JUnit 4 annotations (`@Test`). Register new test classes in the owning module's `getUnitTests()`.
95+
- **Selenium tests**: Subclass `BaseWebDriverTest`. Use a `@BeforeClass` for setup and override `doCleanup()` for cleanup. See `SecurityTest` as an example.
96+
- **Formatting**: Follow IntelliJ IDEA project settings in `.idea/codeStyles/Project.xml`.
97+
98+
## Key Build Properties (`gradle.properties`)
99+
100+
- `sourceCompatibility`/`targetCompatibility`: Java 25
101+
- `buildFromSource`: true (build modules from source vs. pulling artifacts)
102+
- `useLocalBuild`: use locally built artifacts
103+
- `moduleSet`: select a predefined set of modules (e.g., `community`, `all`, `distributions`)
104+
- `excludedModules`: comma-separated list of modules to exclude
105+
106+
## Search Tips
107+
108+
When searching for Java method usages, always include `*.jsp` and `*.jspf` files in addition to `*.java`. JSP files contain inline Java code and are significant callers of API methods (especially anything in `JspBase`).
109+
110+
## Pull Request Format
111+
112+
PRs should include sections for: **Rationale** (why the change is needed), **Related Pull Requests**, and **Changes** (notable items).

gradle.properties

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ buildFromSource=true
4444

4545
# The default version for LabKey artifacts that are built or that we depend on.
4646
# override in an individual module's gradle.properties file as necessary
47-
labkeyVersion=26.2-SNAPSHOT
47+
labkeyVersion=26.3-SNAPSHOT
4848
labkeyClientApiVersion=7.1.0
4949

5050
# Version numbers for the various binary artifacts that are included when
@@ -60,7 +60,7 @@ windowsProteomicsBinariesVersion=1.0
6060
artifactoryPluginVersion=5.2.5
6161
gradleNodePluginVersion=7.1.0
6262
gradlePluginsVersion=7.3.0
63-
owaspDependencyCheckPluginVersion=12.1.9
63+
owaspDependencyCheckPluginVersion=12.2.0
6464

6565
# Versions of node and npm to use during the build. If set, these versions
6666
# will be downloaded and used. If not set, the existing local installations will be used
@@ -97,35 +97,35 @@ mockitoVersion=5.14.2
9797

9898
annotationsVersion=15.0
9999

100-
antVersion=1.10.13
100+
antVersion=1.10.15
101101

102102
antlrST4Version=4.3.4
103103

104104
#Unifying version used by DISCVR and Premium
105105
apacheDirectoryVersion=2.1.7
106106
#Transitive dependency of Apache directory: 2.0.18 contains some regressions
107-
apacheMinaVersion=2.2.4
107+
apacheMinaVersion=2.2.5
108108

109109
# Usually matches the version specified as a Spring Boot dependency (see springBootVersion below)
110-
apacheTomcatVersion=11.0.15
110+
apacheTomcatVersion=11.0.18
111111

112112
# (mothership) -> json-path -> json-smart -> accessor-smart
113113
# (core) -> graalvm
114114
# tika
115-
asmVersion=9.9
115+
asmVersion=9.9.1
116116

117117
# Apache Batik -- Batik version needs to be compatible with Apache FOP, but we need to pull in batik-codec separately
118118
batikVersion=1.19
119119

120120
# sync with Tika version (or later)
121-
bouncycastlePgpVersion=1.82
122-
bouncycastleVersion=1.82
121+
bouncycastlePgpVersion=1.83
122+
bouncycastleVersion=1.83
123123

124124
cglibNodepVersion=2.2.3
125125

126-
checkerQualVersion=3.31.0
126+
checkerQualVersion=3.53.0
127127

128-
commonmarkVersion=0.27.0
128+
commonmarkVersion=0.27.1
129129

130130
# the beanutils version is not the default version brought from commons-validator and/or commons-digester
131131
# in the :server:api module but is required for some of our code to compile
@@ -147,9 +147,9 @@ commonsTextVersion=1.15.0
147147
commonsValidatorVersion=1.10.1
148148
commonsVfs2Version=2.10.0
149149

150-
datadogVersion=1.56.3
150+
datadogVersion=1.58.2
151151

152-
dom4jVersion=2.1.4
152+
dom4jVersion=2.2.0
153153

154154
ehcacheCoreVersion=2.6.8
155155
eigenbasePropertiesVersion=1.1.6
@@ -163,10 +163,10 @@ fopVersion=2.11
163163

164164
# Force latest for consistency
165165
googleApiVersion=2.47.0
166-
googleAuthVersion=1.33.0
166+
googleAuthVersion=1.40.0
167167
googleAutoValueAnnotationsVersion=1.10.4
168-
googleErrorProneAnnotationsVersion=2.45.0
169-
googleHttpClientVersion=2.0.2
168+
googleErrorProneAnnotationsVersion=2.46.0
169+
googleHttpClientVersion=2.1.0
170170
googleOauthClientVersion=1.39.0
171171
googleProtocolBufVersion=3.25.8
172172

@@ -176,7 +176,7 @@ googleProtocolBufVersion=3.25.8
176176
# "java.lang.NoSuchMethodError: 'void com.google.gson.internal.ConstructorConstructor.<init>(java.util.Map)'" errors
177177
gsonVersion=2.8.9
178178

179-
grpcVersion=1.77.0
179+
grpcVersion=1.78.0
180180

181181
guavaVersion=33.5.0-jre
182182

@@ -192,8 +192,8 @@ hamcrestVersion=2.2
192192
# Note: if changing this, we might need to match with the picard version in the SequenceAnalysis module build.gradle
193193
htsjdkVersion=4.3.0
194194

195-
httpclient5Version=5.5.1
196-
httpcore5Version=5.3.6
195+
httpclient5Version=5.5.2
196+
httpcore5Version=5.4
197197

198198
# Not used directly, but these are widely used transitive dependencies
199199
httpclientVersion=4.5.14
@@ -202,12 +202,12 @@ httpcoreVersion=4.4.16
202202
intellijKotlinVersion=1.9.10
203203

204204
# Update the three Jackson dependency versions below in tandem, unless one gets a patch release out-of-sync with the others
205-
jacksonVersion=2.20.1
206-
jacksonDatabindVersion=2.20.1
207-
jacksonJaxrsBaseVersion=2.20.1
205+
jacksonVersion=2.21.0
206+
jacksonDatabindVersion=2.21.0
207+
jacksonJaxrsBaseVersion=2.21.0
208208

209209
# Note the inconsistent version numbering for "annotations"... it no longer matches the above
210-
jacksonAnnotationsVersion=2.20
210+
jacksonAnnotationsVersion=2.21
211211

212212
# The Jakarta Activation API version that Angus Activation implements. Keep in sync with angusActivationVersion (above).
213213
jakartaActivationApiVersion=2.1.4
@@ -224,7 +224,7 @@ jaxbOldVersion=2.3.3
224224

225225
# All other direct and indirect uses of JAXB use the current, jakarta-packaged versions
226226
jaxbApiVersion=4.0.4
227-
jaxbVersion=4.0.5
227+
jaxbVersion=4.0.6
228228

229229
jaxrpcVersion=1.1
230230

@@ -240,9 +240,9 @@ jodaTimeVersion=2.14.0
240240
# brought in transitively by Cloud, FileTransfer, SequenceAnalysis, etc. Need to resolve consistently
241241
jsr305Version=3.0.2
242242

243-
orgJsonVersion=20250517
243+
orgJsonVersion=20251224
244244

245-
jsoupVersion=1.21.2
245+
jsoupVersion=1.22.1
246246

247247
junitVersion=4.13.2
248248

@@ -272,8 +272,7 @@ poiVersion=5.4.0
272272

273273
pollingWatchVersion=0.2.0
274274

275-
# Newer versions of the driver have a perf degradation that's important for us. https://github.com/pgjdbc/pgjdbc/issues/3505
276-
postgresqlDriverVersion=42.7.8
275+
postgresqlDriverVersion=42.7.9
277276

278277
quartzVersion=2.5.2
279278

@@ -296,17 +295,17 @@ slf4jLog4jApiVersion=2.0.17
296295
snappyJavaVersion=1.1.10.8
297296

298297
# Also, update apacheTomcatVersion above to match Spring Boot's Tomcat dependency version
299-
springBootVersion=4.0.1
298+
springBootVersion=4.0.2
300299
# This usually matches the Spring Framework version dictated by springBootVersion
301-
springVersion=7.0.2
300+
springVersion=7.0.3
302301
springAiVersion=1.1.2
303302

304303
sqliteJdbcVersion=3.51.1.0
305304

306305
# NLP and SAML bring stax2-api in as a transitive dependency but with very different versions. We force the later version.
307306
stax2ApiVersion=4.2.2
308307

309-
thumbnailatorVersion=0.4.20
308+
thumbnailatorVersion=0.4.21
310309

311310
# used for tika-core in API and tika-parsers in search
312311
tikaVersion=3.2.3

gradle/wrapper/gradle-wrapper.jar

542 Bytes
Binary file not shown.

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

0 commit comments

Comments
 (0)