Compare commits

..

2 commits

Author SHA1 Message Date
renovate[bot]
4b8d121266
Update Lucene packages to v2.9.4 2024-06-01 17:07:00 +00:00
85f6102112
Add reusable workflow for setting up SSH agent 2024-06-01 19:06:05 +02:00
37 changed files with 316 additions and 444 deletions

View file

@ -1,22 +0,0 @@
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

View file

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

View file

@ -1,44 +0,0 @@
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

45
.github/workflows/stage.yml vendored Normal file
View file

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

View file

@ -1 +1 @@
17 11.0

View file

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

103
.vscode/launch.json vendored
View file

@ -1,21 +1,84 @@
{ {
// Use IntelliSense to learn about possible attributes. // Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes. // Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"type": "java", "type": "java",
"name": "Current File", "name": "Current File",
"request": "launch", "request": "launch",
"mainClass": "${file}" "mainClass": "${file}"
}, },
{ {
"type": "java", "type": "java",
"name": "Debug", "name": "ImageInfo",
"request": "launch", "request": "launch",
"mainClass": "helma.main.Server", "mainClass": "helma.image.ImageInfo",
"projectName": "helma_" "projectName": "helma_"
} },
] {
} "type": "java",
"name": "CommandlineRunner",
"request": "launch",
"mainClass": "helma.main.CommandlineRunner",
"projectName": "helma_"
},
{
"type": "java",
"name": "Server",
"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 # License
Copyright (c) 1999-2025 Helma Project. All rights reserved. Copyright (c) 1999-2008 Helma Project. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View file

@ -2,8 +2,8 @@
## TL;DR ## TL;DR
- Make sure you have Java 17 or higher installed - Make sure you have Java 11 or higher installed
- Download and unpack the [latest release](https://code.host.antville.org/antville/helma/releases) - Download and unpack the [latest release](https://github.com/antville/helma/releases)
- Invoke `./bin/helma`, resp. `./bin/helma.bat`, depending on your platform - Invoke `./bin/helma`, resp. `./bin/helma.bat`, depending on your platform
- Direct your web browser to <http://localhost:8080> - Direct your web browser to <http://localhost:8080>
@ -33,12 +33,10 @@ Helma is built with [Gradle](https://gradle.org), the build task depends on the
### Additional Prerequisites ### Additional Prerequisites
* [Node.js](https://nodejs.org) LTS version
* [Rsync](https://rsync.samba.org) version ≥ 3.1.0 * [Rsync](https://rsync.samba.org) version ≥ 3.1.0
* [Node.js](https://nodejs.org) LTS version
Clone this repository to your machine and run Helma with `./gradlew run`. 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`.
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. > 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 { plugins {
id 'application' id 'application'
id 'com.github.jk1.dependency-license-report' version '2.9' id 'com.github.jk1.dependency-license-report' version '2.7'
} }
import org.apache.tools.ant.filters.FixCrLfFilter import org.apache.tools.ant.filters.FixCrLfFilter
@ -17,9 +17,9 @@ def textFiles = ['**/*.hac', '**/.html', '**/*.js', '**/*.md', '**/*.properties'
allprojects { allprojects {
apply plugin: 'java' apply plugin: 'java'
java { compileJava {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_11
} }
repositories { repositories {
@ -27,7 +27,7 @@ allprojects {
} }
} }
version = new Date().format("yy.M.d") version = new Date().format("yyyyMMdd")
tasks.build.dependsOn javadoc, 'jsdoc', 'generateLicenseReport' tasks.build.dependsOn javadoc, 'jsdoc', 'generateLicenseReport'
tasks.compileJava.dependsOn 'processSource' tasks.compileJava.dependsOn 'processSource'
@ -42,6 +42,15 @@ if (JavaVersion.current().isJava8Compatible()) {
} }
} }
sourceSets {
main {
java {
// Sources in `src` will be available here after processing
srcDirs = ["$buildDir/src/main/java"]
}
}
}
configurations { configurations {
// Wrapping implementation because it does not allow access to its files // Wrapping implementation because it does not allow access to its files
// (i.e. cannot be resolved) // (i.e. cannot be resolved)
@ -49,18 +58,17 @@ configurations {
} }
dependencies { dependencies {
implementation 'com.google.code.gson:gson:2.12.1' implementation 'com.google.code.gson:gson:2.11.0'
implementation 'commons-codec:commons-codec:1.18.0' implementation 'commons-codec:commons-codec:1.17.0'
implementation 'org.apache.commons:commons-fileupload2-core:2.0.0-M2' implementation 'commons-fileupload:commons-fileupload:1.5'
implementation 'org.apache.commons:commons-fileupload2-jakarta:2.0.0-M1' implementation 'commons-logging:commons-logging:1.3.2'
implementation 'commons-logging:commons-logging:1.3.5' implementation 'commons-net:commons-net:3.10.0'
implementation 'commons-net:commons-net:3.11.1'
implementation 'com.sun.mail:javax.mail:1.6.2' implementation 'com.sun.mail:javax.mail:1.6.2'
implementation 'jakarta.servlet:jakarta.servlet-api:5.0.0' implementation 'javax.servlet:javax.servlet-api:4.0.1'
implementation 'org.ccil.cowan.tagsoup:tagsoup:1.2.1' implementation 'org.ccil.cowan.tagsoup:tagsoup:1.2.1'
implementation 'org.eclipse.jetty.ee9:jetty-ee9-servlet:12.0.19' implementation 'org.eclipse.jetty:jetty-servlet:9.4.54.v20240208'
implementation 'org.eclipse.jetty:jetty-xml:12.0.19' implementation 'org.eclipse.jetty:jetty-xml:9.4.54.v20240208'
implementation 'org.mozilla:rhino-all:1.8.0' implementation 'org.mozilla:rhino:1.7.13'
implementation 'org.sejda.imageio:webp-imageio:0.1.6' implementation 'org.sejda.imageio:webp-imageio:0.1.6'
implementation 'xerces:xercesImpl:2.12.2' implementation 'xerces:xercesImpl:2.12.2'
implementation 'xmlrpc:xmlrpc:2.0.1' implementation 'xmlrpc:xmlrpc:2.0.1'
@ -70,37 +78,6 @@ def rhinoJar = configurations.library.files.find { jar ->
jar.name.startsWith('rhino') 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 { startScripts {
applicationName = 'helma' applicationName = 'helma'
classpath = files('../launcher.jar') classpath = files('../launcher.jar')
@ -126,6 +103,30 @@ 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 { distTar {
dependsOn ':generateLicenseReport', ':javadoc', ':jsdoc' dependsOn ':generateLicenseReport', ':javadoc', ':jsdoc'
@ -146,35 +147,42 @@ distZip {
installDist { installDist {
dependsOn build dependsOn build
if (!System.getenv('CI')) {
finalizedBy 'update'
}
} }
def processSource = tasks.register('processSource', Sync) { run {
classpath = files('launcher.jar')
jvmArgs jettyLogLevel, suppressMacosDockIcon
}
task processSource(type: Sync) {
def date = new Date().format("MMMM dd, yyyy")
def gitOutput = new ByteArrayOutputStream() def gitOutput = new ByteArrayOutputStream()
outputs.dir "${project.buildDir}/src"
exec { exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD' commandLine 'git', 'describe'
standardOutput = gitOutput standardOutput = gitOutput
errorOutput = new ByteArrayOutputStream() errorOutput = new ByteArrayOutputStream()
ignoreExitValue = true ignoreExitValue = true
} }
def description = date
def tag = gitOutput.toString().trim()
// TODO: Implement extended description in Java code
if (tag) description = "$tag; $description"
from 'src' from 'src'
filter { filter {
line -> line line -> line.replaceAll('__builddate__', date)
.replaceAll('__builddate__', new Date().format("d MMM yyyy")) } into "${project.buildDir}/src"
.replaceAll('__commithash__', gitOutput.toString().trim())
.replaceAll('__version__', version)
} into outputs.files.singleFile
} }
tasks.compileJava.source = processSource.map { it.outputs.files } task update {
tasks.register('update') {
dependsOn installDist
def rsyncArgs = ['--archive', '--filter', '- backups'] def rsyncArgs = ['--archive', '--filter', '- backups']
def confirm = { def confirm = {
@ -218,7 +226,7 @@ tasks.register('update') {
} }
} }
tasks.register('jsdoc', Exec) { task jsdoc(type: Exec) {
description 'Generates JSDoc API documentation for the included JavaScript modules.' description 'Generates JSDoc API documentation for the included JavaScript modules.'
group 'Documentation' group 'Documentation'
@ -232,7 +240,7 @@ tasks.register('jsdoc', Exec) {
args = ['jsdoc', '-d', "$destination"].plus(sources) args = ['jsdoc', '-d', "$destination"].plus(sources)
} }
tasks.register('xgettext', JavaExec) { task xgettext(type: JavaExec) {
description 'Extracts translatable message strings from source code.' description 'Extracts translatable message strings from source code.'
group 'i18n' group 'i18n'
@ -249,7 +257,7 @@ tasks.register('xgettext', JavaExec) {
] ]
} }
tasks.register('po2js', JavaExec) { task po2js(type: JavaExec) {
description 'Converts translated message strings from PO format to JavaScript.' description 'Converts translated message strings from PO format to JavaScript.'
group 'i18n' group 'i18n'
@ -264,7 +272,7 @@ tasks.register('po2js', JavaExec) {
] ]
} }
tasks.register('rhinoShell', JavaExec) { task rhinoShell(type: JavaExec) {
description 'Runs the interactive Rhino JavaScript shell.' description 'Runs the interactive Rhino JavaScript shell.'
group 'Application' group 'Application'
@ -276,7 +284,7 @@ tasks.register('rhinoShell', JavaExec) {
// Call this task with a function definition using the `-P` parameter, e.g. // Call this task with a function definition using the `-P` parameter, e.g.
// `./gradlew commandLine -Pfunction=manage.getAllApplications` // `./gradlew commandLine -Pfunction=manage.getAllApplications`
tasks.register('commandLine', JavaExec) { task commandLine(type: JavaExec) {
description 'Runs a function in a Helma application with `-Pfunction=app.functionName`.' description 'Runs a function in a Helma application with `-Pfunction=app.functionName`.'
group 'Application' group 'Application'
@ -284,11 +292,3 @@ tasks.register('commandLine', JavaExec) {
mainClass = 'helma.main.launcher.Commandline' mainClass = 'helma.main.launcher.Commandline'
args '-h', projectDir, function 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')
}

View file

@ -1,52 +0,0 @@
# 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 distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

10
gradlew vendored
View file

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

6
gradlew.bat vendored
View file

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

View file

View file

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

View file

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

View file

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

View file

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

View file

@ -16,6 +16,3 @@ project(':modules').projectDir = file('modules/helma')
project(':jala').projectDir = file('modules/jala') project(':jala').projectDir = file('modules/jala')
project(':hopKit').projectDir = file('modules/jala/util/HopKit') project(':hopKit').projectDir = file('modules/jala/util/HopKit')
project(':test').projectDir = file('modules/jala/util/Test') 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'

View file

@ -1,21 +0,0 @@
#!/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 \ -jar launcher.jar \
-w 8080 -x 8081 -w 8080 -x 8081
ExecReload = /bin/sh -c 'touch apps.properties && touch server.properties' ExecReload = touch apps.properties && touch server.properties
ExecStop = /bin/kill -15 $MAINPID ExecStop = /bin/kill -15 $MAINPID
[Install] [Install]

View file

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

View file

@ -16,12 +16,12 @@
package helma.framework; package helma.framework;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.Serializable; import java.io.Serializable;
import java.util.Map; import java.util.Map;
/** /**
* *
*/ */
public class RequestBean implements Serializable { public class RequestBean implements Serializable {
private static final long serialVersionUID = -6826881712426326687L; private static final long serialVersionUID = -6826881712426326687L;
@ -89,7 +89,7 @@ public class RequestBean implements Serializable {
* @return the header value, or null * @return the header value, or null
*/ */
public String getHeader(String name) { public String getHeader(String name) {
return req.getHeader(name); return req.getHeader(name);
} }
/** /**

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -19,7 +19,7 @@ package helma.servlet;
import helma.framework.*; import helma.framework.*;
import helma.framework.core.Application; import helma.framework.core.Application;
import helma.main.*; import helma.main.*;
import jakarta.servlet.*; import javax.servlet.*;
/** /**
* Servlet client that runs a Helma application for the embedded * 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 helma.main.Server;
import java.io.*; import java.io.*;
import jakarta.servlet.*; import javax.servlet.*;
import java.util.*; import java.util.*;
/** /**
@ -98,7 +98,7 @@ public final class StandaloneServletClient extends AbstractServletClient {
repositoryImpl = "helma.framework.repository.FileRepository"; repositoryImpl = "helma.framework.repository.FileRepository";
} }
} }
try { try {
Repository newRepository = (Repository) Class.forName(repositoryImpl) Repository newRepository = (Repository) Class.forName(repositoryImpl)
.getConstructor(parameters) .getConstructor(parameters)
@ -116,7 +116,7 @@ public final class StandaloneServletClient extends AbstractServletClient {
} }
} }
} }
// add app dir // add app dir
FileRepository appRep = new FileRepository(appDir); FileRepository appRep = new FileRepository(appDir);
log("adding repository: " + appDir); log("adding repository: " + appDir);

View file

@ -16,7 +16,7 @@
package helma.util; package helma.util;
import org.apache.commons.fileupload2.core.FileItem; import org.apache.commons.fileupload.FileItem;
import java.io.*; import java.io.*;
import java.util.Date; import java.util.Date;
@ -238,7 +238,7 @@ public class MimePart implements Serializable {
file = new File(base, filename); file = new File(base, filename);
if (fileItem != null) { if (fileItem != null) {
fileItem.write(file.toPath()); fileItem.write(file);
// null out fileItem, since calling write() may have moved the temp file // null out fileItem, since calling write() may have moved the temp file
fileItem = null; fileItem = null;
} else { } else {
@ -249,7 +249,7 @@ public class MimePart implements Serializable {
// return file name // return file name
return filename; return filename;
} catch (Exception x) { } catch (Exception x) {
System.err.println("Error in MimePart.writeToFile(): " + x); System.err.println("Error in MimePart.writeToFile(): " + x);
return null; return null;
} }
} }