Compare commits

..

137 commits

Author SHA1 Message Date
1476c9b19f Merge branch 'main' into renovate/major-jetty-packages
All checks were successful
Build / build (push) Successful in 35s
2025-05-27 17:55:54 +00:00
df28d40645 Update dependency gradle to v8.14.1
All checks were successful
Build / build (push) Successful in 33s
2025-05-25 15:39:15 +00:00
29f7ca5ae3 Merge branch 'main' into renovate/major-jetty-packages
All checks were successful
Build / build (push) Successful in 8s
2025-05-25 15:37:13 +00:00
3f2bf9c3dc
Simplify repository workflows
All checks were successful
Build / build (push) Successful in 31s
* Use deploy workflow for staging, too
* Reduce deploy.sh script
2025-05-25 17:05:05 +02:00
f9bc64d1ed
Merge remote-tracking branch 'origin/main' into renovate/major-jetty-packages 2025-05-24 21:41:38 +02:00
f6668636a9 Replace hard-coded hostname with input 2025-05-24 19:25:08 +00:00
1001b3b503 Replace hard-coded hostname with input 2025-05-24 19:14:30 +00:00
96ceb1d5f3
Merge branch 'main' into renovate/major-jetty-packages 2025-05-24 15:39:44 +02:00
27cdc5104b
Reorganize and refurbish .gitignore file 2025-04-11 20:51:55 +02:00
745ce5bfca
Merge branch 'main' into renovate/major-jetty-packages 2025-04-11 13:22:10 +02:00
c4abd27ac7
Make deploy script executable
All checks were successful
Build / build (push) Successful in 11s
2025-04-11 12:41:44 +02:00
6b88318bcd
Fix regression of Java sources not being processed before compiling
All checks were successful
Build / build (push) Successful in 11s
2025-04-11 11:48:32 +02:00
0cf9cf7af2
Merge remote-tracking branch 'origin/main' into renovate/major-jetty-packages
All checks were successful
Build / build (push) Successful in 10s
2025-04-10 23:32:50 +02:00
96f2dce50f
Add launch configuration for debugging Helma
All checks were successful
Build / build (push) Successful in 34s
2025-04-08 12:05:54 +02:00
f786b40961
Rename the modules project to prevent VSC from renaming the main project to helma_
Does not work, unfortunately
2025-04-08 12:04:55 +02:00
8caf790529
Remove custom configuration of Gradle sourceSets
Using the sources in build creates a lot of confusion in VSC
2025-04-08 12:04:54 +02:00
e6c974120b
Update .gitigore file for VSC settings 2025-04-08 12:04:53 +02:00
6723df912e
Resolve FIXME but without fixing the issue
All checks were successful
Build / build (push) Successful in 19s
I tried to make this work but it might need a more thorough rewrite that I just cannot do.

The worst that can happen is stopping and starting Helma apps adding redundant ServletContextHandlers to the ContextHandlerCollection until Helma is restarted.
2025-04-07 17:16:59 +02:00
436862e87a
Remove setting of “empty” base resource
Fingers crossed it won’t be missed
2025-04-07 17:16:58 +02:00
36a12effb2
Bump Jetty versions to 12.0.19 2025-04-07 17:16:57 +02:00
2994a4becc
Disable Jetty’s session cookies
This remediates the exception “Shared scheduler not started” and restores the functionality of enabling an app in apps.properties – see #103 (comment)
2025-04-07 17:16:53 +02:00
99e8b204fd
Bump Java version 2025-04-07 17:05:43 +02:00
c42c0a7a17
Update repo URL 2025-04-07 17:05:43 +02:00
b7543cf615
Bump year of copyright notice 2025-04-07 17:05:42 +02:00
fc084f6e52
Escape HTML elements in commit messages 2025-04-07 17:05:41 +02:00
6fc73d2320
Add release notes generated with git-cliff 2025-04-07 17:05:40 +02:00
9b5cc988dd
Run the build workflow when itself has changed 2025-04-07 17:05:40 +02:00
04b210b464
Leave aside compiling for different Java versions for now 2025-04-07 17:05:39 +02:00
4c011f1e1b
Gradle is installed on the runner 2025-04-07 17:05:38 +02:00
bc7894ecc1
Use fully qualified URL for setup-java action 2025-04-07 17:05:38 +02:00
a3fbf72f38
Initial commit 2025-04-07 17:05:37 +02:00
de2150693f
Add deploy script usable with rsync and a restricted SSH key 2025-04-07 17:05:36 +02:00
38181e8e00
Update repo URL 2025-03-01 19:32:20 +01:00
8adbd23569
Bump year of copyright notice 2025-03-01 19:32:06 +01:00
e3a7732837
Escape HTML elements in commit messages 2025-03-01 19:21:42 +01:00
d9d3c9b863
Add release notes generated with git-cliff
All checks were successful
Release / release (push) Successful in 31s
2025-03-01 16:57:02 +01:00
808bc48ab9
Run the build workflow when itself has changed
All checks were successful
Build / build (push) Successful in 23s
2025-02-28 22:15:00 +01:00
6ebdd6aa31
Leave aside compiling for different Java versions for now 2025-02-28 22:15:00 +01:00
2ff29317e5
Gradle is installed on the runner 2025-02-28 22:09:55 +01:00
84333d05cd
Use fully qualified URL for setup-java action 2025-02-28 22:04:48 +01:00
3a8997ca5c
Initial commit
Some checks failed
Build / build (11) (push) Failing after 0s
Build / build (17) (push) Failing after 0s
Build / build (21) (push) Failing after 0s
2025-02-28 21:58:08 +01:00
8212600d40
Add deploy script usable with rsync and a restricted SSH key 2025-02-28 21:43:19 +01:00
cd8baa4ac1
Merge branch 'main' into renovate/major-jetty-packages 2025-02-15 20:43:32 +01:00
1bb5a093da
Re-enable creating the release at Github after install of gh client
All checks were successful
Release / build (push) Successful in 26s
2025-02-15 19:49:13 +01:00
2c6dd96cd7
Merge branch 'main' into renovate/commons-codec-commons-codec-1.x 2025-02-15 18:39:26 +01:00
6f6ea55b7b Update dependency com.google.code.gson:gson to v2.12.1 2025-02-15 17:36:51 +00:00
b1a14ad87b Update dependency commons-logging:commons-logging to v1.3.5 2025-02-15 17:36:40 +00:00
d1ead6e081 Update Jetty packages to v9.4.57.v20241219 2025-02-15 17:36:29 +00:00
94557dd28e Update dependency gradle to v8.12.1 2025-02-15 17:35:46 +00:00
5bfcd0b6ea
Distinguish the (currently bogus) GitHub release workflows by name
All checks were successful
Release / build (push) Successful in 26s
2025-02-15 16:43:05 +01:00
70337bda40
Add a custom name for the release workflow 2025-02-15 16:43:05 +01:00
ff4b4b0f07
Set the release title to today’s date as formatted string 2025-02-15 16:43:05 +01:00
156db3ee98
Try Forgejo action to create a release 2025-02-15 15:25:36 +01:00
45adacd5cd
Use name and URL of actual production environment 2025-02-15 15:25:13 +01:00
dd9e473310
Fix botched test of required Java version 2025-02-09 13:23:21 +01:00
e2e67cf2cc Update dependency commons-codec:commons-codec to v1.18.0 2025-01-27 18:13:44 +00:00
11b226b272
Merge branch 'main' into origin/renovate/major-jetty-packages
# Conflicts:
#	build.gradle
2025-01-10 20:09:53 +01:00
f7add5ec47
Looks like setting the LOG_LEVEL variable in the env section does not work
Setting it before the npx command does
2025-01-03 16:20:01 +01:00
0fc7d91348
Always save the Renovate log 2025-01-03 16:16:27 +01:00
1341c241bd
Replace Renovate autodiscovery with explicitly setting the repository 2025-01-03 16:16:27 +01:00
6d355fc5bd
Allow manual trigger of Renovate workflow 2025-01-03 15:55:49 +01:00
d18513fb76
Downgrade upload-artifact action again
v4 causes an error
2025-01-03 15:55:09 +01:00
d10f8d6d90
Replace elaborate checks for Java version with single one for Java 11 2025-01-03 15:54:42 +01:00
66fa98353e
Add the actual version string to helma.main.Server again 2025-01-03 15:54:42 +01:00
c2b37a8243
Update workflows for Forgejo runner 2025-01-03 13:35:33 +01:00
0c9b00dbb1 Merge pull request 'Update actions/upload-artifact action to v4' (#122) from renovate/major-github-artifact-actions into helma-🐜
Reviewed-on: #122
2025-01-03 12:01:15 +00:00
c1e9371f6b Update .github/workflows/renovate.yml 2025-01-03 11:59:50 +00:00
3284a1ca19 Update actions/upload-artifact action to v4 2025-01-03 11:57:30 +00:00
cbb6599ce0 Add Renovate workflow 2025-01-03 11:46:46 +00:00
49c1be97bb
Merge pull request #75 from antville/renovate/org.mozilla-rhino-1.x
Update dependency org.mozilla:rhino to v1.8.0
2025-01-03 11:08:53 +01:00
31bdcc6c27
Merge remote-tracking branch 'origin/renovate/org.mozilla-rhino-1.x' into renovate/org.mozilla-rhino-1.x 2025-01-03 11:01:24 +01:00
bdd4f7e280
Merge remote-tracking branch 'origin/helma-🐜' into helma-🐜 2025-01-03 10:49:14 +01:00
154a4a916a
Merge pull request #117 from antville/renovate/gradle-8.x
Update dependency gradle to v8.12
2025-01-03 10:44:22 +01:00
renovate[bot]
28887aaccd
Update dependency org.mozilla:rhino to v1.8.0 2025-01-03 09:32:00 +00:00
a00e2f730a
Merge pull request #118 from antville/renovate/jetty-packages
Update Jetty packages to v9.4.56.v20240826
2025-01-03 10:31:18 +01:00
9c2c603d4a
Merge pull request #110 from antville/renovate/com.github.jk1.dependency-license-report-2.x
Update plugin com.github.jk1.dependency-license-report to v2.9
2025-01-03 10:24:46 +01:00
b0260259ea
Merge pull request #111 from antville/renovate/commons-net-commons-net-3.x
Update dependency commons-net:commons-net to v3.11.1
2025-01-03 10:18:45 +01:00
renovate[bot]
d3098c892f
Update dependency commons-net:commons-net to v3.11.1 2025-01-03 09:12:13 +00:00
a5fa58dc3d
Merge pull request #119 from antville/renovate/commons-logging-commons-logging-1.x
Update dependency commons-logging:commons-logging to v1.3.4
2025-01-03 10:11:30 +01:00
20ea2a8fb9
Merge pull request #120 from antville/renovate/commons-codec-commons-codec-1.x
Update dependency commons-codec:commons-codec to v1.17.1
2025-01-03 10:09:28 +01:00
de34e49fc0
Merge pull request #121 from antville/renovate/gradle-actions-4.x
Update gradle/actions action to v4
2025-01-03 10:03:26 +01:00
f7fe09a294
Switch to rhino-all.jar, Helma needs the full Rhino experience 2025-01-03 09:53:53 +01:00
renovate[bot]
4ebbcb01ae
Update dependency org.mozilla:rhino to v1.8.0 2025-01-03 08:07:29 +00:00
renovate[bot]
e93c501149
Update dependency gradle to v8.12 2024-12-20 17:56:06 +00:00
renovate[bot]
3809198380
Update Jetty packages to v9.4.56.v20240826 2024-09-03 19:04:35 +00:00
renovate[bot]
65ac2df0ba
Update dependency commons-logging:commons-logging to v1.3.4 2024-08-19 14:24:50 +00:00
renovate[bot]
12e7f298ad
Update plugin com.github.jk1.dependency-license-report to v2.9 2024-08-15 18:27:04 +00:00
3365a2ef58
Fix ExecReload setting in service configuration 2024-08-08 23:00:08 +02:00
44f2375749
Update URL of stage environment 2024-08-08 19:35:22 +02:00
renovate[bot]
a975930192
Update gradle/actions action to v4 2024-08-03 22:55:47 +00:00
renovate[bot]
a54b27c4aa
Update dependency commons-codec:commons-codec to v1.17.1 2024-07-16 02:34:32 +00:00
608fd695c4
Switch to tasks.register() to define custom tasks 2024-06-15 23:08:45 +02:00
87675fd6cd
Fix deprecation warning for Java plugin conventions 2024-06-15 23:01:45 +02:00
efb7ad89b3
Add static fields for build date and commit hash 2024-06-15 22:43:26 +02:00
5de4616df0
Use main website as environment 2024-06-15 21:37:17 +02:00
bd70d2fb62
Disable automatic deployment 2024-06-15 21:37:17 +02:00
0f8bace3dd
Keep the lib/ext directory around 2024-06-15 21:37:17 +02:00
c1ad40ef72
Remove over-complicated launch and tasks configuration in favor of Gradle plugin
Starting run/debug tasks with the plugin works out of the box;
one just has to avoid the default “Run and Debug” button.
2024-06-15 21:37:17 +02:00
6b694a83ed
Add setup for Gradle debugging in VS Codium 2024-06-15 21:37:16 +02:00
79b7e8092b
Decouple update task from install
Now that Gradle runs Helma with the configured dependencies, updating the installation directory has become less crucial
2024-06-15 21:37:16 +02:00
196794cd93
Reorder the tasks 2024-06-15 21:37:16 +02:00
ed56cf72f7
Slightly modify the version string (still a date representation) 2024-06-15 21:37:16 +02:00
3a9c14898b
Update run configuration to always use the correct dependencies 2024-06-15 21:37:16 +02:00
82c32bb448
Slightly modify the format of the build date 2024-06-15 21:37:16 +02:00
1925916220
Bump required minimum Java version to 17 2024-06-15 18:27:30 +02:00
b1296fb093
Merge branch 'helma-🐜' into renovate/major-jetty-packages
# Conflicts:
#	.github/workflows/release.yml
2024-06-15 18:18:25 +02:00
51bc14c3a4
Remove over-complicated launch and tasks configuration in favor of Gradle plugin
Starting run/debug tasks with the plugin works out of the box;
one just has to avoid the default “Run and Debug” button.
2024-06-15 18:01:30 +02:00
3e5af064b0
Add setup for Gradle debugging in VS Codium 2024-06-15 18:00:59 +02:00
6401300189
Decouple update task from install
Now that Gradle runs Helma with the configured dependencies, updating the installation directory has become less crucial
2024-06-15 13:02:11 +02:00
45b19e3217
Reorder the tasks 2024-06-15 12:38:04 +02:00
ffb259a01c
Slightly modify the version string (still a date representation) 2024-06-15 12:37:16 +02:00
84abcde037
Update run configuration to always use the correct dependencies 2024-06-15 12:34:51 +02:00
9e870e6cd3
Slightly modify the format of the build date 2024-06-15 12:34:50 +02:00
def303c069
Define Java versions in a more general way 2024-06-15 12:19:28 +02:00
64bcb63e4a
Merge pull request #116 from antville/revert-112-renovate/gradle-8.x
Revert "Update dependency gradle to v8.8"
2024-06-14 23:01:39 +02:00
55dbc0359c
Revert "Update dependency gradle to v8.8" 2024-06-14 23:00:48 +02:00
f2feef4332
Use generic name for the staging server 2024-06-01 22:28:24 +02:00
14ccdf0691
Add deployment workflow 2024-06-01 20:54:35 +02:00
4ae840d3c9
Add reusable workflow for setting up SSH agent 2024-06-01 20:21:36 +02:00
1e32c8eb89
Merge remote-tracking branch 'origin/helma-🐜' into renovate/major-jetty-packages 2024-05-30 19:22:11 +02:00
9143faf35e
Add release action 2024-05-30 19:10:13 +02:00
79d83389f2
Use canonical paths when creating static contexts 2024-05-25 18:28:43 +02:00
90e45c9115
Migrate to Apache file upload API 2 w/ Jakarta 2024-05-25 18:28:43 +02:00
3dbcd792a6
Migrate to Jakarte servlet API 5 2024-05-25 18:28:42 +02:00
973b3493cb
Prevent java.lang.IllegalArgumentException: Resource String is invalid 2024-05-25 18:28:42 +02:00
441d952b35
Prevent incompatible types: ServletContextHandler cannot be converted to Handler 2024-05-25 18:28:42 +02:00
d67d0235bd
Prevent java.lang.IllegalStateException: Shared scheduler not started 2024-05-25 18:28:41 +02:00
fa59a27858
Fix creation of protected context 2024-05-25 18:28:41 +02:00
304ea4e456
Fix creation of app context 2024-05-25 18:28:40 +02:00
0165e7c80e
Fix setup of static resource 2024-05-25 18:28:40 +02:00
62630ae068
Modernize for loop 2024-05-25 18:28:39 +02:00
26975a109a
Method ServerConnector.setSoLingerTime() was removed 2024-05-25 18:28:39 +02:00
a943124d45
Fix creating Jetty server from config file 2024-05-25 18:28:38 +02:00
c087cb731e
Use correct version of Jetty servlet 2024-05-25 18:28:38 +02:00
c5f68013b1 Merge branch 'helma-🐜' into renovate/major-jetty-packages 2024-05-19 02:56:40 +02:00
ed575bc4c5
Update README.md
Minor edits
2024-05-19 02:05:49 +02:00
renovate[bot]
1cf738767c
Update Jetty packages 2024-05-18 15:30:36 +00:00
37 changed files with 443 additions and 315 deletions

22
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,22 @@
name: Build
on:
push:
paths:
- .github/workflows/build.yml
- build.gradle
- settings.gradle
- src/**
- launcher/build.gradle
- launcher/src/**
workflow_dispatch:
jobs:
build:
runs-on: antville
steps:
- uses: actions/checkout@v4
- name: Compile with Gradle
run: ./gradlew :compileJava

39
.github/workflows/deploy.yml vendored Normal file
View file

@ -0,0 +1,39 @@
name: Deploy
on:
workflow_dispatch:
inputs:
hostname:
description: Hostname
type: string
required: true
default: antville.org
jobs:
stage:
runs-on: antville
environment:
name: production
url: ${{ inputs.hostname }}
steps:
- uses: actions/checkout@v4
- name: Build with Gradle
run: ./gradlew installDist
- name: Copy build files to server
run: |
rsync ./build/install/helma/ ${{ inputs.hostname }}:./ \
--verbose --archive --delete --compress \
--filter '+ /bin' \
--filter '+ /extras' \
--filter '+ /launcher.jar' \
--filter '- /lib/ext' \
--filter '+ /lib' \
--filter '+ /modules' \
--filter '- /*'
- name: Restart Helma
run: ssh ${{ inputs.hostname }} restart

View file

@ -1,45 +1,59 @@
name: Release
on:
workflow_dispatch:
push:
tags:
- 'v*'
tags: '2*'
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
release:
runs-on: antville
env:
GH_TOKEN: ${{ github.token }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
LC_TIME: en_US.UTF-8
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
fetch-depth: 0
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Create release notes
id: create_release_notes
run: |
release_notes=$(npx git-cliff@latest --latest)
# Write the release notes as a heredoc to the workflow output
# ⚠️ No white space around `<<` is crucial!
echo "release_notes<<.eot0x03" >> $GITHUB_OUTPUT
echo "$release_notes" >> $GITHUB_OUTPUT
echo ".eot0x03" >> $GITHUB_OUTPUT
- name: Build with Gradle
run: ./gradlew assembleDist
- name: Create release
uses: actions/forgejo-release@v2
with:
direction: upload
url: https://code.host.antville.org
token: ${{ github.token }}
title: Helma ${{ github.ref_name }}
release-dir: build/distributions
release-notes: ${{ steps.create_release_notes.outputs.release_notes }}
verbose: true
- name: Create release at GitHub
run: |
gh release create "$GITHUB_REF_NAME" \
--repo "$GITHUB_REPOSITORY" \
--title "$(date +'%d %b %Y')" \
--generate-notes
--title "Helma ${{ github.ref_name }}" \
--notes "${{ steps.create_release_notes.outputs.release_notes }}"
- name: Upload assets
- name: Upload release assets to GitHub
run: |
gh release upload "$GITHUB_REF_NAME" \
build/distributions/helma-*.* \
gh release upload "$GITHUB_REF_NAME" build/distributions/helma-*.* \
--repo "$GITHUB_REPOSITORY" \
--clobber

44
.github/workflows/renovate.yml vendored Normal file
View file

@ -0,0 +1,44 @@
name: Run Renovate
on:
schedule:
- cron: "13 * * * *"
workflow_dispatch:
jobs:
renovate:
runs-on: antville
steps:
- uses: actions/checkout@v4
- name: Run Renovate
# See <https://docs.renovatebot.com/troubleshooting/#log-debug-levels>
# debug | info | warn | error | fatal
run: LOG_LEVEL=info npx renovate
env:
# Renovate is using this token to retrieve release notes
GITHUB_COM_TOKEN: ${{ secrets.renovate_github_com_token }}
# Autodiscover is better suited for an extra repo running Renovate on all desired repos
#RENOVATE_AUTODISCOVER: 'true'
RENOVATE_CONFIG_FILE: renovate.json
RENOVATE_ENDPOINT: ${{ github.api_url }}
RENOVATE_GIT_AUTHOR: Renovate Bot <mail+renovate@antville.org>
#RENOVATE_GIT_IGNORED_AUTHORS:
# - 29139614+renovate[bot]@users.noreply.github.com
RENOVATE_IGNORE_PR_AUTHOR: 'true'
RENOVATE_LOG_FILE: renovate-log.ndjson
RENOVATE_LOG_FILE_LEVEL: debug
RENOVATE_PLATFORM: gitea
RENOVATE_REPOSITORIES: ${{ github.repository }}
RENOVATE_REPOSITORY_CACHE: 'enabled'
# github.token is not working here, it lacks some permissions required by Renovate
RENOVATE_TOKEN: ${{ secrets.renovate_token }}
- name: Save log file
# FIXME: v4 of this action causes an error on Forgejo (“You must configure a GitHub token”)
uses: actions/upload-artifact@v3
if: always()
with:
name: renovate-log.ndjson
path: renovate-log.ndjson

View file

@ -1,45 +0,0 @@
name: Deploy (Staging)
on: workflow_dispatch
jobs:
stage:
runs-on: ubuntu-latest
environment:
name: stage
url: https://antville-test.click
steps:
- uses: actions/checkout@v4
- name: Set up SSH agent
uses: ./.github/actions/ssh
with:
config: ${{ vars.SSH_CONFIG }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
known-hosts: ${{ vars.SSH_KNOWN_HOSTS }}
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Build with Gradle
run: ./gradlew installDist
- name: Publish to staging server
run: |
rsync build/install/helma/ antville.dev:/ \
--verbose --archive --delete --compress \
--filter 'protect /lib/ext' \
--filter '+ /launcher.jar' \
--filter '+ /lib' \
--filter '- /*' \
- name: Restart Helma
run: ssh antville.dev restart

32
.gitignore vendored
View file

@ -1,22 +1,30 @@
.gradle
.idea
.settings
build
# Generally ignore hidden files
.*
/apps
# Manage some Codium configuration
.vscode/*
!.vscode
!.vscode/extensions.json
!.vscode/launch.json
!.vscode/settings.json
!.vscode/tasks.json
# Ignore files created during build or run
/bin
/backups
/db
build
/docs
/extras
/lib
/licenses
/log
# Ignore files managed in src/dist
/*.properties
/apps
/db
/extras
/launcher.jar
/static
/*.properties
/launcher.jar
/passwd
/start.*
# Manage Gradle configuration
!/gradle.properties

View file

@ -1 +1 @@
11.0
17

View file

@ -1,5 +1,6 @@
{
"recommendations": [
"vscjava.vscode-java-pack"
"vscjava.vscode-java-pack",
"vscjava.vscode-gradle"
]
}

65
.vscode/launch.json vendored
View file

@ -12,73 +12,10 @@
},
{
"type": "java",
"name": "ImageInfo",
"request": "launch",
"mainClass": "helma.image.ImageInfo",
"projectName": "helma_"
},
{
"type": "java",
"name": "CommandlineRunner",
"request": "launch",
"mainClass": "helma.main.CommandlineRunner",
"projectName": "helma_"
},
{
"type": "java",
"name": "Server",
"name": "Debug",
"request": "launch",
"mainClass": "helma.main.Server",
"projectName": "helma_"
},
{
"type": "java",
"name": "XmlConverter",
"request": "launch",
"mainClass": "helma.objectmodel.dom.XmlConverter",
"projectName": "helma_"
},
{
"type": "java",
"name": "Crypt",
"request": "launch",
"mainClass": "helma.util.Crypt",
"projectName": "helma_"
},
{
"type": "java",
"name": "HtmlEncoder",
"request": "launch",
"mainClass": "helma.util.HtmlEncoder",
"projectName": "helma_"
},
{
"type": "java",
"name": "Logo",
"request": "launch",
"mainClass": "helma.util.Logo",
"projectName": "helma_"
},
{
"type": "java",
"name": "MarkdownProcessor",
"request": "launch",
"mainClass": "helma.util.MarkdownProcessor",
"projectName": "helma_"
},
{
"type": "java",
"name": "Commandline",
"request": "launch",
"mainClass": "helma.main.launcher.Commandline",
"projectName": "launcher"
},
{
"type": "java",
"name": "Main",
"request": "launch",
"mainClass": "helma.main.launcher.Main",
"projectName": "launcher"
}
]
}

View file

@ -1,6 +1,6 @@
# License
Copyright (c) 1999-2008 Helma Project. All rights reserved.
Copyright (c) 1999-2025 Helma Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

View file

@ -2,8 +2,8 @@
## TL;DR
- Make sure you have Java 11 or higher installed
- Download and unpack the [latest release](https://github.com/antville/helma/releases)
- Make sure you have Java 17 or higher installed
- Download and unpack the [latest release](https://code.host.antville.org/antville/helma/releases)
- Invoke `./bin/helma`, resp. `./bin/helma.bat`, depending on your platform
- Direct your web browser to <http://localhost:8080>
@ -33,10 +33,12 @@ Helma is built with [Gradle](https://gradle.org), the build task depends on the
### Additional Prerequisites
* [Rsync](https://rsync.samba.org) version ≥ 3.1.0
* [Node.js](https://nodejs.org) LTS version
* [Rsync](https://rsync.samba.org) version ≥ 3.1.0
Clone this repository to your machine and start the build process with `./gradlew install`. The build script is going to ask you if you want to update the installation, enter `yes` or `no`.
Clone this repository to your machine and run Helma with `./gradlew run`.
To update the installation from a build, run `./gradlew update` and enter `yes` at the prompt.
> ⚠️
> Please be aware that this step is going to overwrite files in the installation directory escpecially at a later time when there might be substantial changes. Should this happen by accident you find the previous installation in the `backups` directory.

View file

@ -1,6 +1,6 @@
plugins {
id 'application'
id 'com.github.jk1.dependency-license-report' version '2.7'
id 'com.github.jk1.dependency-license-report' version '2.9'
}
import org.apache.tools.ant.filters.FixCrLfFilter
@ -17,9 +17,9 @@ def textFiles = ['**/*.hac', '**/.html', '**/*.js', '**/*.md', '**/*.properties'
allprojects {
apply plugin: 'java'
compileJava {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
repositories {
@ -27,7 +27,7 @@ allprojects {
}
}
version = new Date().format("yyyyMMdd")
version = new Date().format("yy.M.d")
tasks.build.dependsOn javadoc, 'jsdoc', 'generateLicenseReport'
tasks.compileJava.dependsOn 'processSource'
@ -42,15 +42,6 @@ if (JavaVersion.current().isJava8Compatible()) {
}
}
sourceSets {
main {
java {
// Sources in `src` will be available here after processing
srcDirs = ["$buildDir/src/main/java"]
}
}
}
configurations {
// Wrapping implementation because it does not allow access to its files
// (i.e. cannot be resolved)
@ -58,17 +49,18 @@ configurations {
}
dependencies {
implementation 'com.google.code.gson:gson:2.11.0'
implementation 'commons-codec:commons-codec:1.17.0'
implementation 'commons-fileupload:commons-fileupload:1.5'
implementation 'commons-logging:commons-logging:1.3.2'
implementation 'commons-net:commons-net:3.10.0'
implementation 'com.google.code.gson:gson:2.12.1'
implementation 'commons-codec:commons-codec:1.18.0'
implementation 'org.apache.commons:commons-fileupload2-core:2.0.0-M2'
implementation 'org.apache.commons:commons-fileupload2-jakarta:2.0.0-M1'
implementation 'commons-logging:commons-logging:1.3.5'
implementation 'commons-net:commons-net:3.11.1'
implementation 'com.sun.mail:javax.mail:1.6.2'
implementation 'javax.servlet:javax.servlet-api:4.0.1'
implementation 'jakarta.servlet:jakarta.servlet-api:5.0.0'
implementation 'org.ccil.cowan.tagsoup:tagsoup:1.2.1'
implementation 'org.eclipse.jetty:jetty-servlet:9.4.54.v20240208'
implementation 'org.eclipse.jetty:jetty-xml:9.4.54.v20240208'
implementation 'org.mozilla:rhino:1.7.13'
implementation 'org.eclipse.jetty.ee9:jetty-ee9-servlet:12.0.19'
implementation 'org.eclipse.jetty:jetty-xml:12.0.19'
implementation 'org.mozilla:rhino-all:1.8.0'
implementation 'org.sejda.imageio:webp-imageio:0.1.6'
implementation 'xerces:xercesImpl:2.12.2'
implementation 'xmlrpc:xmlrpc:2.0.1'
@ -78,6 +70,37 @@ def rhinoJar = configurations.library.files.find { jar ->
jar.name.startsWith('rhino')
}
run {
jvmArgs jettyLogLevel, suppressMacosDockIcon
classpath += fileTree(dir: 'lib/ext', include: '*.jar')
}
application {
mainClass = 'helma.main.Server'
applicationDistribution.from(projectDir) {
include 'modules/**'
include 'LICENSE.md'
include 'README.md'
include 'start.*'
}
applicationDistribution.from(javadoc.destinationDir) {
include '**'
into 'docs/javadoc'
}
applicationDistribution.from("${project.buildDir}/docs/jsdoc") {
include '**'
into 'docs/jsdoc'
}
applicationDistribution.from("${project.buildDir}/reports/dependency-license") {
include '**'
into 'licenses'
}
}
startScripts {
applicationName = 'helma'
classpath = files('../launcher.jar')
@ -103,30 +126,6 @@ distributions {
}
}
application {
applicationDistribution.from(projectDir) {
include 'modules/**'
include 'LICENSE.md'
include 'README.md'
include 'start.*'
}
applicationDistribution.from(javadoc.destinationDir) {
include '**'
into 'docs/javadoc'
}
applicationDistribution.from("${project.buildDir}/docs/jsdoc") {
include '**'
into 'docs/jsdoc'
}
applicationDistribution.from("${project.buildDir}/reports/dependency-license") {
include '**'
into 'licenses'
}
}
distTar {
dependsOn ':generateLicenseReport', ':javadoc', ':jsdoc'
@ -147,42 +146,35 @@ distZip {
installDist {
dependsOn build
if (!System.getenv('CI')) {
finalizedBy 'update'
}
}
run {
classpath = files('launcher.jar')
jvmArgs jettyLogLevel, suppressMacosDockIcon
}
task processSource(type: Sync) {
def date = new Date().format("MMMM dd, yyyy")
def processSource = tasks.register('processSource', Sync) {
def gitOutput = new ByteArrayOutputStream()
outputs.dir "${project.buildDir}/src"
exec {
commandLine 'git', 'describe'
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = gitOutput
errorOutput = new ByteArrayOutputStream()
ignoreExitValue = true
}
def description = date
def tag = gitOutput.toString().trim()
// TODO: Implement extended description in Java code
if (tag) description = "$tag; $description"
from 'src'
filter {
line -> line.replaceAll('__builddate__', date)
} into "${project.buildDir}/src"
line -> line
.replaceAll('__builddate__', new Date().format("d MMM yyyy"))
.replaceAll('__commithash__', gitOutput.toString().trim())
.replaceAll('__version__', version)
} into outputs.files.singleFile
}
task update {
tasks.compileJava.source = processSource.map { it.outputs.files }
tasks.register('update') {
dependsOn installDist
def rsyncArgs = ['--archive', '--filter', '- backups']
def confirm = {
@ -226,7 +218,7 @@ task update {
}
}
task jsdoc(type: Exec) {
tasks.register('jsdoc', Exec) {
description 'Generates JSDoc API documentation for the included JavaScript modules.'
group 'Documentation'
@ -240,7 +232,7 @@ task jsdoc(type: Exec) {
args = ['jsdoc', '-d', "$destination"].plus(sources)
}
task xgettext(type: JavaExec) {
tasks.register('xgettext', JavaExec) {
description 'Extracts translatable message strings from source code.'
group 'i18n'
@ -257,7 +249,7 @@ task xgettext(type: JavaExec) {
]
}
task po2js(type: JavaExec) {
tasks.register('po2js', JavaExec) {
description 'Converts translated message strings from PO format to JavaScript.'
group 'i18n'
@ -272,7 +264,7 @@ task po2js(type: JavaExec) {
]
}
task rhinoShell(type: JavaExec) {
tasks.register('rhinoShell', JavaExec) {
description 'Runs the interactive Rhino JavaScript shell.'
group 'Application'
@ -284,7 +276,7 @@ task rhinoShell(type: JavaExec) {
// Call this task with a function definition using the `-P` parameter, e.g.
// `./gradlew commandLine -Pfunction=manage.getAllApplications`
task commandLine(type: JavaExec) {
tasks.register('commandLine', JavaExec) {
description 'Runs a function in a Helma application with `-Pfunction=app.functionName`.'
group 'Application'
@ -292,3 +284,11 @@ task commandLine(type: JavaExec) {
mainClass = 'helma.main.launcher.Commandline'
args '-h', projectDir, function
}
tasks.register('debug', JavaExec) {
group = 'application'
main = 'helma.main.Server'
classpath = sourceSets.main.runtimeClasspath
jvmArgs = ['-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005']
classpath += fileTree(dir: 'lib/ext', include: '*.jar')
}

52
cliff.toml Normal file
View file

@ -0,0 +1,52 @@
# git-cliff ~ default configuration file
# https://git-cliff.org/docs/configuration
#
# Lines starting with "#" are comments.
# Configuration options are organized into tables and keys.
# See documentation for more information on available options.
[changelog]
trim = true
header = "## Changes"
body = """
{% for group, commits in commits | filter(attribute="merge_commit") | group_by(attribute="group") %}
### {{ group | striptags | trim | upper_first }}
{% for commit in commits %}
* [<tt>{{ commit.id | split(pat="") | slice(end=11) | join() }}</tt>]\
(https://code.host.antville.org/antville/helma/commit/{{ commit.id }}) \
{% if commit.breaking %}**Breaking:** {% endif %}\
{{ commit.message | split(pat="\\n") | first | upper_first | escape }}\
{% endfor %}
{% endfor %}
**Full Changelog:** [{{ previous.version }} {{ version }}]\
(https://code.host.antville.org/antville/helma/compare/\
{{ previous.version | urlencode }}..{{ version | urlencode }})\n\n
"""
footer = """
Generated by [git-cliff](https://git-cliff.org/).
"""
[git]
conventional_commits = false
filter_commits = false
filter_unconventional = false
protect_breaking_commits = false
sort_commits = "newest"
split_commits = false
topo_order = false
commit_parsers = [
{ message = "^Apply \\d+ suggestion", skip = true },
{ message = "^Merge .*(branch|dependabot|dependency|renovate)", skip = true },
{ message = "^Lock file maintenance", skip = true },
{ message = "yarn\\.lock", skip = true },
{ message = "^[Ff]ix", group = "<!-- 0 --> 🐛 Bug Fixes" },
{ field = "author.name", pattern = "[Rr]enovate|[Dd]ependabot", group = "<!-- 3 --> 📦 Dependency Updates" },
{ message = "^Merge pull request", group = "<!-- 1 --> 🔀 Merges" },
{ message = ".*", group = "<!-- 2 --> Uncategorized" },
]

Binary file not shown.

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

10
gradlew vendored
View file

@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@ -84,7 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@ -112,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@ -203,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
@ -211,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.

6
gradlew.bat vendored
View file

@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@ -68,11 +70,11 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell

0
lib/ext/.keep Normal file
View file

View file

@ -1,8 +1,8 @@
dependencies {
runtimeOnly 'ch.ethz.ganymed:ganymed-ssh2:build209'
runtimeOnly 'net.sourceforge.jexcelapi:jxl:2.5.7'
runtimeOnly 'org.apache.lucene:lucene-analyzers:2.9.4'
runtimeOnly 'org.apache.lucene:lucene-core:2.9.4'
runtimeOnly 'org.apache.lucene:lucene-analyzers:2.2.0'
runtimeOnly 'org.apache.lucene:lucene-core:2.2.0'
}
jar.enabled = false
@ -12,7 +12,7 @@ processResources.enabled = false
processTestResources.enabled = false
test.enabled = false
task deps(type: Copy) {
tasks.register('deps', Copy) {
from sourceSets.main.runtimeClasspath
into '.'
}

View file

@ -15,7 +15,7 @@ processResources.enabled = false
processTestResources.enabled = false
test.enabled = false
task deps(type: Copy) {
tasks.register('deps', Copy) {
from sourceSets.main.runtimeClasspath
into 'lib'
}

View file

@ -10,7 +10,7 @@ processResources.enabled = false
processTestResources.enabled = false
test.enabled = false
task deps(type: Copy) {
tasks.register('deps', Copy) {
from sourceSets.main.runtimeClasspath
into 'lib'
}

View file

@ -10,7 +10,7 @@ processResources.enabled = false
processTestResources.enabled = false
test.enabled = false
task deps(type: Copy) {
tasks.register('deps', Copy) {
from sourceSets.main.runtimeClasspath
into 'code'
}

View file

@ -16,3 +16,6 @@ project(':modules').projectDir = file('modules/helma')
project(':jala').projectDir = file('modules/jala')
project(':hopKit').projectDir = file('modules/jala/util/HopKit')
project(':test').projectDir = file('modules/jala/util/Test')
// Rename this project to prevent redundancy and renaming of main project (VSC does not care, though)
project(':modules').name = 'modules'

21
src/dist/extras/deploy.sh vendored Executable file
View file

@ -0,0 +1,21 @@
#!/bin/sh
# Use this script as forced command of an authorized SSH key:
# command="/home/helma/extras/deploy.sh" ssh-ed25519 AAAAC3NzaC…
case "$SSH_ORIGINAL_COMMAND" in
ping)
echo pong
;;
restart)
printf 'Restarting Helma… '
sudo /bin/systemctl restart helma
printf '%s\n' 'done.'
;;
*)
# Allow any rsync command but restrict it to the installation directory
rrsync -wo /home/helma
;;
esac

View file

@ -18,7 +18,7 @@ ExecStart = /usr/bin/java -server \
-jar launcher.jar \
-w 8080 -x 8081
ExecReload = touch apps.properties && touch server.properties
ExecReload = /bin/sh -c 'touch apps.properties && touch server.properties'
ExecStop = /bin/kill -15 $MAINPID
[Install]

View file

@ -17,7 +17,7 @@
package helma.framework;
import java.io.Serializable;
import javax.servlet.http.Cookie;
import jakarta.servlet.http.Cookie;
/**
* Cookie Transmitter. A simple, serializable representation

View file

@ -16,7 +16,7 @@
package helma.framework;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Map;

View file

@ -19,9 +19,9 @@ package helma.framework;
import helma.util.SystemMap;
import helma.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Cookie;
import org.apache.commons.codec.binary.Base64;

View file

@ -19,7 +19,7 @@ package helma.framework;
import helma.objectmodel.db.Transactor;
import helma.scripting.ScriptingException;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.PrintWriter;

View file

@ -21,7 +21,7 @@ import helma.framework.core.Application;
import helma.util.*;
import helma.scripting.ScriptingException;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.*;
import java.util.*;

View file

@ -19,11 +19,13 @@ import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.xmlrpc.XmlRpcHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
import org.eclipse.jetty.ee9.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.ResourceFactory;
import helma.framework.core.Application;
import helma.framework.repository.FileRepository;
@ -481,23 +483,29 @@ public class ApplicationManager implements XmlRpcHandler {
// if there is a static direcory specified, mount it
if (this.staticDir != null) {
String staticPath = getAbsoluteFile(this.staticDir).getCanonicalPath();
File staticContent = getAbsoluteFile(this.staticDir);
getLogger().info("Serving static from " + staticContent.getPath());
getLogger().info("Serving static from " + staticPath);
getLogger().info("Mounting static at " + staticMountpoint);
ResourceHandler rhandler = new ResourceHandler();
rhandler.setResourceBase(staticContent.getPath());
rhandler.setBaseResource(ResourceFactory.of(rhandler).newResource(staticPath));
rhandler.setWelcomeFiles(staticHome);
staticContext = ApplicationManager.this.context.addContext(staticMountpoint, ""); //$NON-NLS-1$
ContextHandler staticContext = new ContextHandler();
staticContext.setContextPath(staticMountpoint);
staticContext.setHandler(rhandler);
ApplicationManager.this.context.addHandler(staticContext);
staticContext.start();
}
appContext = new ServletContextHandler(context, pathPattern, true, true);
// I hope I am correct assuming Helma does not need Jettys session management, but using
// `ServletContextHandler.SESSIONS` causes an exception: Shared scheduler not started
appContext = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
appContext.setContextPath(pathPattern);
context.addHandler(appContext);
Class servletClass = servletClassName == null ?
EmbeddedServletClient.class : Class.forName(servletClassName);
ServletHolder holder = new ServletHolder(servletClass);
@ -529,10 +537,9 @@ public class ApplicationManager implements XmlRpcHandler {
}
if (protectedStaticDir != null) {
File protectedContent = getAbsoluteFile(protectedStaticDir);
appContext.setResourceBase(protectedContent.getPath());
getLogger().info("Serving protected static from " +
protectedContent.getPath());
String protectedContent = getAbsoluteFile(protectedStaticDir).getCanonicalPath();
appContext.setBaseResourceAsString(protectedContent);
getLogger().info("Serving protected static from " + protectedContent);
}
// Remap the context paths and start
@ -556,7 +563,9 @@ public class ApplicationManager implements XmlRpcHandler {
// unbind from Jetty HTTP server
if (ApplicationManager.this.jetty != null) {
if (this.appContext != null) {
ApplicationManager.this.context.removeHandler(this.appContext);
// Adding appContext to the ContextHandlerCollection works (see above) but removing it causes an exception of
// incompatible types: ServletContextHandler cannot be converted to Handler
//ApplicationManager.this.context.removeHandler(this.appContext);
this.appContext.stop();
this.appContext.destroy();
this.appContext = null;

View file

@ -16,11 +16,12 @@
package helma.main;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.URLResourceFactory;
import org.eclipse.jetty.xml.XmlConfiguration;
import java.net.URL;
@ -36,18 +37,20 @@ public class JettyServer {
public static JettyServer init(Server server, ServerConfig config) throws IOException {
File configFile = config.getConfigFile();
if (configFile != null && configFile.exists()) {
return new JettyServer(configFile.toURI().toURL());
URLResourceFactory resourceFactory = new URLResourceFactory();
Resource resource = resourceFactory.newResource(configFile.toURI());
return new JettyServer(resource);
} else if (config.hasWebsrvPort()) {
return new JettyServer(config.getWebsrvPort(), server);
}
return null;
}
private JettyServer(URL url) throws IOException {
private JettyServer(Resource resource) throws IOException {
http = new org.eclipse.jetty.server.Server();
try {
XmlConfiguration config = new XmlConfiguration(url);
XmlConfiguration config = new XmlConfiguration(resource);
config.configure(http);
} catch (IOException e) {
@ -73,7 +76,6 @@ public class JettyServer {
connector.setHost(webPort.getAddress().getHostAddress());
connector.setPort(webPort.getPort());
connector.setIdleTimeout(30000);
connector.setSoLingerTime(-1);
connector.setAcceptorPriorityDelta(0);
connector.setAcceptQueueSize(0);
@ -100,12 +102,13 @@ public class JettyServer {
}
private void openListeners() throws IOException {
// opening the listener here allows us to run on priviledged port 80 under jsvc
// opening the listener here allows us to run on privileged port 80 under jsvc
// even as non-root user, because init() is called with root privileges
// while start() will be called with the user we will actually run as
Connector[] connectors = http.getConnectors();
for (int i = 0; i < connectors.length; i++) {
((ServerConnector) connectors[i]).open();
for (var connector : http.getConnectors()) {
if (connector instanceof ServerConnector) {
((ServerConnector) connector).open();
}
}
}
}

View file

@ -21,6 +21,7 @@ import helma.framework.repository.FileResource;
import helma.framework.core.*;
import helma.objectmodel.db.DbSource;
import helma.util.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlrpc.*;
@ -36,7 +37,13 @@ import helma.util.ResourceProperties;
*/
public class Server implements Runnable {
// version string
public static final String version = "🐜 (__builddate__)";
public static final String version = "__version__";
// build date
public static final String buildDate = "__builddate__";
// commit hash
public static final String commitHash = "__commithash__";
// static server instance
private static Server server;
@ -143,17 +150,13 @@ public class Server implements Runnable {
* check if we are running on a Java 2 VM - otherwise exit with an error message
*/
public static void checkJavaVersion() {
String javaVersion = System.getProperty("java.version");
String javaVersion = System.getProperty("java.version", "0");
int majorVersion = Integer.parseInt(javaVersion.split("\\.")[0]);
if ((javaVersion == null) || javaVersion.startsWith("1.5")
|| javaVersion.startsWith("1.4")
|| javaVersion.startsWith("1.3")
|| javaVersion.startsWith("1.2")
|| javaVersion.startsWith("1.1")
|| javaVersion.startsWith("1.0")) {
System.err.println("This version of Helma requires Java 1.6 or greater.");
if (majorVersion < 17) {
System.err.println("This version of Helma requires Java 17 or greater.");
if (javaVersion == null) { // don't think this will ever happen, but you never know
if (majorVersion == 0) { // don't think this will ever happen, but you never know
System.err.println("Your Java Runtime did not provide a version number. Please update to a more recent version.");
} else {
System.err.println("Your Java Runtime is version " + javaVersion +

View file

@ -22,18 +22,29 @@ package helma.servlet;
import helma.framework.*;
import helma.framework.core.Application;
import helma.util.*;
import java.io.*;
import java.util.*;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.security.SecureRandom;
import java.security.NoSuchAlgorithmException;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.apache.commons.fileupload2.core.DiskFileItemFactory;
import org.apache.commons.fileupload2.core.FileItem;
import org.apache.commons.fileupload2.core.FileUploadException;
import org.apache.commons.fileupload2.core.FileUploadSizeException;
import org.apache.commons.fileupload2.core.ProgressListener;
import org.apache.commons.fileupload2.jakarta.JakartaServletDiskFileUpload;
import org.apache.commons.fileupload2.jakarta.JakartaServletFileUpload;
import org.apache.commons.fileupload2.jakarta.JakartaServletRequestContext;
/**
* This is an abstract Hop servlet adapter. This class communicates with hop applications
@ -218,9 +229,9 @@ public abstract class AbstractServletClient extends HttpServlet {
// read file uploads
List uploads = null;
ServletRequestContext reqcx = new ServletRequestContext(request);
JakartaServletRequestContext reqcx = new JakartaServletRequestContext(request);
if (ServletFileUpload.isMultipartContent(reqcx)) {
if (JakartaServletFileUpload.isMultipartContent(reqcx)) {
// get session for upload progress monitoring
UploadStatus uploadStatus = getApplication().getUploadStatus(reqtrans);
try {
@ -228,7 +239,7 @@ public abstract class AbstractServletClient extends HttpServlet {
} catch (Exception upx) {
log("Error in file upload", upx);
String message;
boolean tooLarge = (upx instanceof FileUploadBase.SizeLimitExceededException);
boolean tooLarge = (upx instanceof FileUploadSizeException);
if (tooLarge) {
message = "File upload size exceeds limit of " + uploadLimit + " kB";
} else {
@ -653,12 +664,12 @@ public abstract class AbstractServletClient extends HttpServlet {
map.put(name, newValues);
}
protected List parseUploads(ServletRequestContext reqcx, RequestTrans reqtrans,
protected List parseUploads(JakartaServletRequestContext reqcx, RequestTrans reqtrans,
final UploadStatus uploadStatus, String encoding)
throws FileUploadException, UnsupportedEncodingException {
throws FileUploadException, UnsupportedCharsetException, IOException {
// handle file upload
DiskFileItemFactory factory = new DiskFileItemFactory();
FileUpload upload = new FileUpload(factory);
DiskFileItemFactory factory = DiskFileItemFactory.builder().get();
JakartaServletFileUpload upload = new JakartaServletFileUpload(factory);
// use upload limit for individual file size, but also set a limit on overall size
upload.setFileSizeMax(uploadLimit * 1024);
upload.setSizeMax(totalUploadLimit * 1024);
@ -681,7 +692,7 @@ public abstract class AbstractServletClient extends HttpServlet {
Object value;
// check if this is an ordinary HTML form element or a file upload
if (item.isFormField()) {
value = item.getString(encoding);
value = item.getString(Charset.forName(encoding));
} else {
value = new MimePart(item);
}

View file

@ -19,7 +19,7 @@ package helma.servlet;
import helma.framework.*;
import helma.framework.core.Application;
import helma.main.*;
import javax.servlet.*;
import jakarta.servlet.*;
/**
* Servlet client that runs a Helma application for the embedded

View file

@ -23,7 +23,7 @@ import helma.main.ServerConfig;
import helma.main.Server;
import java.io.*;
import javax.servlet.*;
import jakarta.servlet.*;
import java.util.*;
/**

View file

@ -16,7 +16,7 @@
package helma.util;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload2.core.FileItem;
import java.io.*;
import java.util.Date;
@ -238,7 +238,7 @@ public class MimePart implements Serializable {
file = new File(base, filename);
if (fileItem != null) {
fileItem.write(file);
fileItem.write(file.toPath());
// null out fileItem, since calling write() may have moved the temp file
fileItem = null;
} else {