Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8b48693
validate any DOI URL sent
qqmyers Jul 15, 2026
93f3c95
note * not recommended for prod
qqmyers Jul 15, 2026
d10c0dc
feat(ci): add SonarQube analysis and coverage reporting to GitHub Act…
poikilotherm Jul 21, 2026
3985900
chore(ci): update Maven CI workflow for SonarQube compatibility
poikilotherm Jul 21, 2026
0f724e9
new setting to determine create behavior w.r.t. default license assig…
qqmyers Jul 21, 2026
e8716e5
release note
qqmyers Jul 21, 2026
72a5ad2
IQSS/12483 gbr req question fix (#12501)
qqmyers Jul 22, 2026
2b69f80
only support full on/off
qqmyers Jul 22, 2026
9a34fe1
Merge remote-tracking branch 'IQSS/develop' into IQSS/11161-defaultLi…
qqmyers Jul 22, 2026
a018fdb
fix tests, fully enforce no license and terms in TofU&A
qqmyers Jul 22, 2026
f9b46f3
move DatasetType logic before setLicense()
qqmyers Jul 22, 2026
b485249
NPE for preview of draft file with retention period (#12434)
jo-pol Jul 22, 2026
c6cfad1
chore(deps): bump org.postgresql:postgresql in /modules/dataverse-parent
dependabot[bot] Jul 23, 2026
9f1bcd1
Release note
jo-pol Jul 27, 2026
2d95572
Merge pull request #12561 from DANS-KNAW-jp/release-note
pdurbin Jul 27, 2026
515bdfe
Merge pull request #12555 from IQSS/dependabot/maven/modules/datavers…
pdurbin Jul 27, 2026
f03a14f
chore(deps): bump org.omnifaces:omnifaces from 4.7.5 to 4.7.12
dependabot[bot] Jul 27, 2026
6489918
Merge remote-tracking branch 'IQSS/develop' into COAR-DOI-Url-checks
qqmyers Jul 27, 2026
85639e5
updates per review, dropping support for api urls
qqmyers Jul 27, 2026
119cf32
update test
qqmyers Jul 27, 2026
613b5bc
Merge pull request #12564 from IQSS/dependabot/maven/org.omnifaces-om…
pdurbin Jul 28, 2026
d88961a
Merge pull request #12550 from IQSS/9846-enable-sonarqube
pdurbin Jul 28, 2026
5cfcb49
fix test - was using illegal TofUandA
qqmyers Jul 29, 2026
e7f0751
remove obsolete test - can't have license and TofU
qqmyers Jul 29, 2026
c361b33
note the enforcement of license OR custom terms on setters
qqmyers Jul 29, 2026
8975844
Apply suggestion from @pdurbin
qqmyers Jul 29, 2026
e2dc20a
chore(ci): limit SonarQube job to upstream repository #12570
poikilotherm Jul 31, 2026
d94e01d
style(build): fix minor typos in pom.xml
poikilotherm Jul 31, 2026
fe112ca
chore(ci): add secret check for SonarQube job
poikilotherm Jul 31, 2026
0a49c4c
Merge pull request #12576 from poikilotherm/12570-disable-sonar-forks
pdurbin Jul 31, 2026
711b0b8
Merge remote-tracking branch 'IQSS/develop' into IQSS/11161-defaultLi…
qqmyers Jul 31, 2026
2d2867d
Merge pull request #12551 from GlobalDataverseCommunityConsortium/IQS…
sekmiller Aug 5, 2026
ad7ada1
Merge pull request #12538 from GlobalDataverseCommunityConsortium/COA…
sekmiller Aug 5, 2026
70751e9
perf(json): caching of JsonBuilderFactory in JsonUtil
Jul 17, 2026
429a031
style(json): improve Javadocs for JSON builders
poikilotherm Jul 17, 2026
605ed2d
style(json): revert star import
Jul 17, 2026
d9fc3ea
perf(json): use cached builder factory in JsonUtil
Jul 17, 2026
c422174
build: integrate forbidden-apis plugin to enforce API usage rules
poikilotherm Jul 17, 2026
467025c
build: update rules to refine JSON-P API restrictions
poikilotherm Jul 17, 2026
b209941
perf(json): replaced cached builder factory in JsonUtil with cached J…
Jul 21, 2026
a5c2e24
perf(json): added all types of JsonUtil.createValue()
Jul 21, 2026
27fbb04
fix(forbiddenapis): use java.lang. in Json.createValue signature, whi…
Jul 21, 2026
5c50e56
style(forbiddenapis): move signatures file to dataverse-sca-config
Jul 31, 2026
ada2db1
build: remove dataverse-sca-config module and reorganize forbidden-ap…
poikilotherm Jul 31, 2026
9ddbf5c
build: move Checkstyle config to subfolder
poikilotherm Jul 31, 2026
6b2954a
doc(releaseNote): add JSON-P performance release note
Aug 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 58 additions & 3 deletions .github/workflows/maven_unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ jobs:
# Get the build output from the integration test job
- uses: actions/download-artifact@v8
with:
name: java-reportdir
name: java-reportdir
- run: tar -xvf java-reportdir.tar

# Deposit Code Coverage
Expand All @@ -159,10 +159,65 @@ jobs:
continue-on-error: true
run: >
mvn -B
-DrepoToken=${COVERALLS_SECRET} -DpullRequest=${{ github.event.number }}
-DrepoToken="${COVERALLS_SECRET}" -DpullRequest=${{ github.event.number }}
jacoco:report coveralls:report

# NOTE: this may be extended with adding a report to the build output, leave a comment, send to Sonarcloud, ...
# Note: The SONAR_TOKEN secret is required to push analysis results to Sonarcloud.
# We check for them here and subsequent jobs can rely on this to decide if they shall run.
check-secrets:
needs: integration-test
name: Check for Secrets Availability
runs-on: ubuntu-latest
outputs:
available: ${{ steps.secret-check.outputs.available }}
steps:
- id: secret-check
# perform secret check & put boolean result as an output
shell: bash
run: |
if [ "${{ secrets.SONAR_TOKEN }}" != '' ]; then
echo "available=true" >> "$GITHUB_OUTPUT";
else
echo "available=false" >> "$GITHUB_OUTPUT";
fi

sonarcloud:
runs-on: ubuntu-latest
needs: check-secrets
name: SonarQube Analysis and Coverage
# Only run in upstream repo - avoid unnecessary runs in forks (they don't have access to SONAR_TOKEN)
if: needs.check-secrets.outputs.available == 'true'
steps:
# TODO: As part of #10618 change to setup-maven custom action
# Basic setup chores
- uses: actions/checkout@v7
with:
# Sonarcube benefits from a full Git history in it's analysis (assign issues, etc)
fetch-depth: 0
- uses: actions/setup-java@v5
with:
java-version: '21'
distribution: temurin
cache: maven

# Get the coverage output from the integration test job
- uses: actions/download-artifact@v8
with:
name: java-reportdir
# Get the binary class files as Sonar needs them for analysis
- uses: actions/download-artifact@v8
with:
name: java-artifacts
- run: |
tar -xvf java-builddir.tar
tar -xvf java-reportdir.tar

# Run Sonarcube analysis
- name: Analyze and commit to SonarCloud
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: mvn -B org.sonarsource.scanner.maven:sonar-maven-plugin:sonar

# TODO: Add a filter step here, that avoids calling the app image release workflow if there are changes to the base image.
# Use https://github.com/dorny/paths-filter to solve this. Will require and additional job or adding to integration-test job.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/reviewdog_checkstyle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ jobs:
with:
fail_on_error: true
reporter: github-pr-review
checkstyle_config: checkstyle.xml
checkstyle_config: src/maven/checkstyle.xml
github_token: ${{ secrets.GITHUB_TOKEN }}

8 changes: 8 additions & 0 deletions doc/release-notes/11161-do-not-assume-default-license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
### New Feature Flag: do-not-assume-default-license

A new feature flag `do-not-assume-default-license` has been added. This flag controls the behavior when creating a dataset via API without providing a license or terms of use.

- By default (flag disabled), the default license will be automatically assigned if no license and no terms are provided in the input JSON, regardless of whether custom terms are allowed.
- When enabled, no license (and no terms) will be assigned if none are provided.

**Note:** Previously, if custom terms were allowed, the system would not assign a default license in this case. To retain that behavior, you must now enable this feature flag.
4 changes: 4 additions & 0 deletions doc/release-notes/12362-factory-method-for-JSONbuilders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Improved JSON Performance

A Jakarta JSON-P provider is now reused for every builder or value creation.
This improves the performance of large JSON operations, especially large exports and API responses, without changing the existing behavior or the JSON output.
1 change: 1 addition & 0 deletions doc/release-notes/12433-NPE-draft-prefiew
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This release fixes a null pointer exception when previewing a draft file with a retention period.
1 change: 1 addition & 0 deletions doc/release-notes/12483-gbr-req-question-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A bug that caused any required custom questions in guestbooks to still be optional has been fixed in the current UI.
File renamed without changes.
2 changes: 2 additions & 0 deletions doc/sphinx-guides/source/api/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ v6.12

- **/api/admin/index/perms/{id}**

- Dataset creation API calls may now behave differently when neither a license nor terms are provided, depending on the new :ref:`dataverse.feature.do-not-assume-default-license` feature flag.

v6.11
-----

Expand Down
2 changes: 1 addition & 1 deletion doc/sphinx-guides/source/developers/testing/fixtures.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ DatasetFixture fixture = DatasetFixtureBuilder.builder()
.populator(FixturePopulator.minimal())
.build();

JsonArrayBuilder files = Json.createArrayBuilder();
JsonArrayBuilder files = JsonUtil.createArrayBuilder();

for (FileMetadata fileMetadata : fixture.fileMetadatas()) {
files.add(JsonPrinter.json(fileMetadata.getDataFile(), fileMetadata, true));
Expand Down
11 changes: 11 additions & 0 deletions doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3951,8 +3951,10 @@ Linked Data Notifications (LDN) Allowed Hosts
+++++++++++++++++++++++++++++++++++++++++++++

Dataverse supports receiving LDN notifications via the /api/inbox endpoint. The dataverse.ldn.allowed-hosts allows you to specify the list of host IP addresses from which LDN notifications can be received, or ``*`` to receive messages from anywhere.
Note that since the Inbox endpoint does not require authentication, allowing un-trusted hosts via ``*`` is not recommended for production.

Example: ``dataverse.ldn.allowed-hosts=*``
Example: ``dataverse.ldn.allowed-hosts=172.16.234.56,172.16.234.57``

COAR Notify Relationship Announcement Notify Superusers Only
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Expand Down Expand Up @@ -4055,6 +4057,15 @@ In a future Dataverse version, the (currently) experimental response message sty

See also :ref:`dataverse.legacy.api-response-message-style`.

.. _dataverse.feature.do-not-assume-default-license:

dataverse.feature.do-not-assume-default-license
+++++++++++++++++++++++++++++++++++++++++++++++

When creating a dataset via API, if neither a license nor any terms of use are provided, the system normally assigns the default license. If this feature flag is enabled, no license is assigned (and no terms) in this case.

Defaults to ``false``.

.. _dataverse.feature.avoid-expensive-solr-join:

dataverse.feature.avoid-expensive-solr-join
Expand Down
17 changes: 15 additions & 2 deletions modules/dataverse-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@

<!-- Major system components and dependencies -->
<payara.version>7.2026.2</payara.version>
<postgresql.version>42.7.11</postgresql.version>
<postgresql.version>42.7.12</postgresql.version>
<solr.version>9.8.0</solr.version>
<postgresql.server.version>16</postgresql.server.version>
<aws.version>2.33.0</aws.version>
Expand All @@ -173,7 +173,6 @@
<smallrye-mpconfig.version>3.7.1</smallrye-mpconfig.version>
<junit.jupiter.version>5.10.2</junit.jupiter.version>
<mockito.version>5.11.0</mockito.version>
<maven-jacoco-plugin.version>0.8.11</maven-jacoco-plugin.version>

<checkstyle.version>9.3</checkstyle.version>

Expand All @@ -198,9 +197,18 @@
<maven-checkstyle-plugin.version>3.2.2</maven-checkstyle-plugin.version>
<nexus-staging-plugin.version>1.6.13</nexus-staging-plugin.version>
<pomchecker-maven-plugin.version>1.7.0</pomchecker-maven-plugin.version>
<sonar.version>5.7.0.6970</sonar.version>
<maven-jacoco-plugin.version>0.8.14</maven-jacoco-plugin.version>

<!-- Container related -->
<fabric8-dmp.version>0.48.0</fabric8-dmp.version>

<!-- SonarQube Code Quality related -->
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<sonar.organization>iqss</sonar.organization>
<sonar.projectKey>IQSS_dataverse</sonar.projectKey>
<sonar.moduleKey>${project.groupId}:${project.artifactId}</sonar.moduleKey>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
</properties>

<pluginRepositories>
Expand Down Expand Up @@ -318,6 +326,11 @@
<artifactId>pomchecker-maven-plugin</artifactId>
<version>${pomchecker-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>${sonar.version}</version>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
Expand Down
68 changes: 62 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
<surefire.jacoco.args>-Ddummy.jacoco.property=true</surefire.jacoco.args>
<failsafe.jacoco.args>-Ddummy.jacoco.property=true</failsafe.jacoco.args>

<jacoco.merged.outputdir>${project.reporting.outputDirectory}/jacoco-merged-test-coverage-report</jacoco.merged.outputdir>
<sonar.coverage.jacoco.xmlReportPaths>${jacoco.merged.outputdir}/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>

<!-- By default, this module will produce a WAR file. -->
<!-- This will be switched within the container profile! -->
<packaging.type>war</packaging.type>
Expand Down Expand Up @@ -140,10 +143,10 @@
</dependency>

<!-- TECHNICAL DEBT
For a very long time, in a lots of places people used org.apache.commons.httpclient to access
HTTP resources, wrap responses in exceptions etc.
For a very long time, in a lot of places people used org.apache.commons.httpclient to access
HTTP resources, wrap responses in exceptions, etc.

This library had been used via an transitive dependency of sword2-server. During its recent updates,
This library had been used via a transitive dependency of sword2-server. During its recent updates,
the dependency was dropped, went missing, eventually breaking our code. Re-adding this 2007 goodie here
as a direct dependency.

Expand Down Expand Up @@ -357,7 +360,7 @@
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>4.7.5</version>
<version>4.7.12</version>
</dependency>

<!-- Jakarta Validation API & runtime -->
Expand Down Expand Up @@ -883,6 +886,59 @@
</resource>
</resources>
<plugins>
<plugin>
<groupId>de.thetaphi</groupId>
<artifactId>forbiddenapis</artifactId>
<version>3.10</version>
<configuration>
<!-- If the used Java version is too new, don't fail, just do nothing: -->
<failOnUnsupportedJava>false</failOnUnsupportedJava>
<!--
If a class is missing while parsing signatures files, all methods
and fields from this class are silently ignored. This is useful
in multi-module Maven projects where only some modules have the
dependency to which the signature file(s) apply.

This settings prints no warning at all, so verify the signatures
at least once with full dependencies.
-->
<ignoreSignaturesOfMissingClasses>true</ignoreSignaturesOfMissingClasses>
<bundledSignatures>
<!-- See https://github.com/policeman-tools/forbidden-apis/wiki/BundledSignatures -->
<bundledSignature>jdk-non-portable</bundledSignature>
<bundledSignature>jdk-internal</bundledSignature>

<!-- Enabling the following checks will require refactoring within the codebase -->
<!--
<bundledSignature>jdk-reflection</bundledSignature>
<bundledSignature>jdk-unsafe</bundledSignature>
<bundledSignature>jdk-deprecated</bundledSignature>
<bundledSignature>jdk-system-out</bundledSignature>
<bundledSignature>commons-io-unsafe-${commons.io.version}</bundledSignature>
-->
</bundledSignatures>
<signaturesFiles>
<signaturesFile>${project.basedir}/src/maven/forbiddenapis.txt</signaturesFile>
</signaturesFiles>
<targetVersion>${target.java.version}</targetVersion>
</configuration>
<executions>
<execution>
<id>for-classes</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
<execution>
<id>for-test-classes</id>
<phase>process-test-classes</phase>
<goals>
<goal>testCheck</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand Down Expand Up @@ -1031,7 +1087,7 @@
</goals>
<configuration>
<dataFile>${project.build.directory}/coverage-reports/merged.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco-merged-test-coverage-report</outputDirectory>
<outputDirectory>${jacoco.merged.outputdir}</outputDirectory>
<skip>${skipIntegrationTests}</skip>
</configuration>
</execution>
Expand Down Expand Up @@ -1103,7 +1159,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<configLocation>${project.basedir}/src/maven/checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
</configuration>
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/DataFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import edu.harvard.iq.dataverse.util.json.JsonUtil;
import jakarta.json.Json;
import jakarta.json.JsonArrayBuilder;
import jakarta.persistence.*;
Expand Down Expand Up @@ -446,7 +448,7 @@ public JsonArrayBuilder getTagLabelsAsJsonArrayBuilder(){

List<DataFileTag> currentDataTags = this.getTags();

JsonArrayBuilder builder = Json.createArrayBuilder();
JsonArrayBuilder builder = JsonUtil.createArrayBuilder();

if ( (currentDataTags == null)||(currentDataTags.isEmpty())){
return builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Set;
import java.util.logging.Logger;

import edu.harvard.iq.dataverse.util.json.JsonUtil;
import jakarta.ejb.EJB;
import jakarta.ejb.Stateless;
import jakarta.inject.Named;
Expand Down Expand Up @@ -645,7 +646,7 @@ private String tryToReplaceRetrievalUriParam(String retrievalUri, String paramNa
*/
private JsonObject filterResponse(JsonObject cvocEntry, JsonObject readObject, String termUri) {

JsonObjectBuilder job = Json.createObjectBuilder();
JsonObjectBuilder job = JsonUtil.createObjectBuilder();
JsonObject filtering = cvocEntry.getJsonObject("retrieval-filtering");
logger.fine("RF: " + filtering.toString());
JsonObject managedFields = cvocEntry.getJsonObject("managed-fields");
Expand All @@ -658,7 +659,7 @@ private JsonObject filterResponse(JsonObject cvocEntry, JsonObject readObject, S
logger.fine("F: " + filter.toString());
JsonArray params = filter.getJsonArray("params");
if (params == null) {
params = Json.createArrayBuilder().build();
params = JsonUtil.createArrayBuilder().build();
}
logger.fine("Params: " + params.toString());
List<Object> vals = new ArrayList<Object>();
Expand Down Expand Up @@ -790,7 +791,7 @@ Object processPathSegment(int index, String[] pathParts, JsonValue curPath, Stri
}
}
} else {
JsonArrayBuilder parts = Json.createArrayBuilder();
JsonArrayBuilder parts = JsonUtil.createArrayBuilder();
for (JsonValue subPath : arr) {
if (subPath instanceof JsonObject) {
JsonValue nextValue = ((JsonObject) subPath).get(keyVal[0]);
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -3015,7 +3015,7 @@ public String updateCurrentVersion() {
String status = updateVersion.getArchivalCopyLocationStatus();
if((status==null) || status.equals(DatasetVersion.ARCHIVAL_STATUS_FAILURE) || (JvmSettings.BAGIT_ARCHIVE_ON_VERSION_UPDATE.lookupOptional(Boolean.class).orElse(false) && archiveCommand.canDelete())){
// Delete the record of any existing copy since it is now out of date/incorrect
JsonObjectBuilder job = Json.createObjectBuilder();
JsonObjectBuilder job = JsonUtil.createObjectBuilder();
job.add(DatasetVersion.ARCHIVAL_STATUS, DatasetVersion.ARCHIVAL_STATUS_PENDING);
updateVersion.setArchivalCopyLocation(JsonUtil.prettyPrint(job.build()));
//Persist to db now
Expand Down Expand Up @@ -6126,7 +6126,7 @@ public String getCroissant() {
reviewsJsonObj = commandEngine.submit(new GetDatasetReviewsCommand(dvRequestService.getDataverseRequest(), dataset));
JsonObjectBuilder reviews = CroissantExportUtil.getReviews(reviewsJsonObj);
JsonObject croissantJson = JsonUtil.getJsonObject(croissant);
String updatedContent = Json.createObjectBuilder(croissantJson)
String updatedContent = JsonUtil.createObjectBuilder(croissantJson)
.add("reviews", reviews.build().getJsonArray("reviews")).build().toString();
return updatedContent;
} catch (CommandException e) {
Expand Down Expand Up @@ -6206,7 +6206,7 @@ public void archiveVersion(Long id, boolean force) {
if (status == null || (force && cmd.canDelete())) {

// Set initial pending status
JsonObjectBuilder job = Json.createObjectBuilder();
JsonObjectBuilder job = JsonUtil.createObjectBuilder();
job.add(DatasetVersion.ARCHIVAL_STATUS, DatasetVersion.ARCHIVAL_STATUS_PENDING);
dv.setArchivalCopyLocation(JsonUtil.prettyPrint(job.build()));
//Persist now
Expand Down
Loading
Loading