Vault Java SDK Upgrade to Java 17 (original) (raw)
Over the next several releases, Veeva is upgrading the Vault Java SDK compilation from Java 8 to Java 17. Java 17 includes optimizations that can improve performance and efficiency compared to Java 8, allowing for reduced resource usage.
Existing integrations are not affected as long as developers do not update or modify existing integration code. When Java 17 is enabled, Vault compiles code deployments with Java 17 instead of Java 8. If no code is deployed, there is no behavior change. Updating or modifying an existing integration requires deployment, which means that updating an existing integration compiled with Java 8 will cause the integration to recompile with Java 17.
Until 25R2, Admins can disable Java 17 to allow developers to modify existing integrations and deploy with Java 8 compilation. After 25R2, Admins can no longer disable Java 17 compilation.
We recommend developers test their code using Java 17 as soon as possible, which will allow developers to modify existing integrations if needed after 25R2. After 25R2, all code will compile with Java 17. At this time, existing integrations compiled with Java 8 cannot be modified without changing compilation from Java 8 to Java 17.
The upgrade to Java 17 may require code changes to keep custom integrations working with Java 17 compilation. To help with this migration, we’ve created a list of solutions to common Java 17 compilation errors.
Release Dates
Limited Release Dates
- 24R2.3; September 27, 2024: Developers and Admins can optionally enable Java 17 to test their custom code for compatibility. Enabling Java 17 does not automatically test your custom code for compatibility. Existing code already deployed to your Vault is not affected. To test your existing custom code for compatibility, you must enable Java 17 and then redeploy your code.
- 24R3.2; December 18, 2024: Vault will auto-enable Java 17, with the option to disable if code incompatibilities are found. This release does not automatically test your custom code for compatibility with Java 17. Existing custom code already deployed to your Vault is not affected. You must redeploy your existing code to recompile with Java 17.
- 25R1.2; April 25, 2025: All custom Vault Java SDK code will compile with Java 17. Existing custom code deployed to Vault is not affected as long as developers do not update or modify existing integration code. After this date, there is no way to modify existing code without upgrading to Java 17 compilation.
General Release Dates
- 24R3; December 13, 2024: Developers and Admins can optionally enable Java 17 to test their custom code for compatibility. Enabling Java 17 does not automatically test your custom code for compatibility. Existing code already deployed to your Vault is not affected. To test your existing custom code for compatibility, you must enable Java 17 and then redeploy your code.
- 25R1; April 11, 2025: Vault will auto-enable Java 17, with the option to disable if code incompatibilities are found. This release does not automatically test your custom code for compatibility with Java 17. Existing custom code already deployed to your Vault is not affected. You must redeploy your existing code to recompile with Java 17.
- 25R2; July 25, 2025: All custom Vault Java SDK code will compile with Java 17. Existing custom code deployed to Vault is not affected as long as developers do not update or modify existing integration code. After this date, there is no way to modify existing code without upgrading to Java 17 compilation.
How to Enable Java 17
The upgrade to Java 17 may require code changes. We recommend developers enable Java 17 and test their code as soon as possible.
When enabled, the Use Java 17 Compilation and Runtime setting causes Vault code deployments to compile with Java 17. Enabling Java 17 compilation in your Vault does not automatically test your code for compatibility, as existing code is not recompiled. To test your code for compatibility with Java 17, you must enable Java 17 in your Vault and then redeploy any existing custom code to recompile with Java 17.
To enable Java 17:
- Navigate to Admin > Settings > General Settings.
- Click Edit.
- Select the Use Java 17 Compilation and Runtime checkbox.
- Click Save.
When Java 17 is enabled:
- Existing custom code currently deployed to your Vault is not affected.
- Updates to (or re-deployment of) existing code will compile with Java 17 instead of Java 8.
- New code deployed to your Vault will compile with Java 17.
How to Temporarily Disable Java 17
The upgrade to Java 17 may require code changes. If your organization needs more time to make these changes, you can temporarily disable Java 17. Disabling Java 17 allows your developers to modify your existing integrations without upgrading to Java 17 yet. Organizations must upgrade by 25R2 (25R1.2), at which time the option to disable Java 17 will no longer be available.
To disable Java 17:
- Navigate to Admin > Settings > General Settings.
- Click Edit.
- Clear the Use Java 17 Compilation and Runtime checkbox.
- Click Save.
When Java 17 is disabled:
- Updates to (or re-deployment of) existing custom code will compile with Java 8.
- New code deployed to your Vault will compile with Java 8.
- On the 25R2 (25R1.2) relase, this setting will no longer be available and all code will require Java 17 compilation.
How to Redeploy Existing Integration Code
When evaluating custom code for compatibility with Java 17, developers may want to start by making no changes and redeploying existing code as-is in a sandbox Vault. This will evaluate if code changes are needed for the upgrade to Java 17 compilation.
To redeploy existing code without making changes:
- Create a sandbox Vault. Verify that Java 17 is enabled in your sandbox Vault.
- Export a VPK from your production Vault.
- Import the VPK to your sandbox Vault with the
replace_alldeployment option. - Deploy the imported VPK to your sandbox Vault. Code that cannot compile with Java 17 will fail to deploy.
If code incompatibilities are found, developers should deploy code changes with the Maven Plugin. For example, developers may need to deploy changes for common Java 17 compilation errors.
POM Update to Test Java 17
To test your code with Java 17 locally, you must make the following change to your POM file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<!-- Source will still be Java 8 -->
<source>1.8</source>
<!-- compile using Java 17 -->
<target>17</target>
</configuration>
</plugin>
Common Java 17 Compilation Errors
The following solutions can help you fix common issues you may encounter when upgrading to Java 17.
Can’t find your issue? Let us know in the Vault for Developers community on Veeva Connect.
Java Record Class Error
Summary of Issue:
- Java 17 introduces the java.lang.Record class
- Vault Java SDK has the com.veeva.vault.sdk.api.data.Record class
- If custom code uses a wildcard import (
import com.veeva.vault.sdk.api.data.*), the Java 17 compiler cannot determine whichRecordclass is being referenced
Affected Code Example
The following example code demonstrates the Java Record Class error:
package com.veeva.vault.custom.triggers;
import com.veeva.vault.sdk.api.data.*;
@RecordTriggerInfo(object = "vsdk_hello_world__c", name="vsdk_hello_world__c", events = {RecordEvent.BEFORE_INSERT})
public class HelloWorld implements RecordTrigger {
public void execute(RecordTriggerContext recordTriggerContext) {
LogService logService = ServiceLocator.locate(LogService.class);
// is this java.lang.Record, or com.veeva.vault.sdk.api.data.Record?
Record record = recordTriggerContext.getRecordChanges().get(0).getNew();
}
}
Compilation Error
Compiling the affected code example produces the following error:
MESSAGE "[type=INVALID_DATA,message=javasdk/src/main/java/com/veeva/vault/custom/triggers/HelloWorld.java:51: error: reference to Record is ambiguous
Record record = recordTriggerContext.getRecordChanges().get(0).getNew();
^
both interface com.veeva.vault.sdk.api.data.Record in com.veeva.vault.sdk.api.data and class java.lang.Record in java.lang match
Solution
Provide a specific import statement for the Record class.
package com.veeva.vault.custom.triggers;
import com.veeva.vault.sdk.api.data.Record;
import com.veeva.vault.sdk.api.data.RecordChange;
import com.veeva.vault.sdk.api.data.RecordEvent;
import com.veeva.vault.sdk.api.data.RecordTrigger;
import com.veeva.vault.sdk.api.data.RecordTriggerContext;
import com.veeva.vault.sdk.api.data.RecordTriggerInfo;
@RecordTriggerInfo(object = "vsdk_hello_world__c", name="vsdk_hello_world__c", events = {RecordEvent.BEFORE_INSERT})
public class HelloWorld implements RecordTrigger {
public void execute(RecordTriggerContext recordTriggerContext) {
LogService logService = ServiceLocator.locate(LogService.class);
// Now it is clear this is com.veeva.vault.sdk.api.data.Record
Record record = recordTriggerContext.getRecordChanges().get(0).getNew();
}
}
Underscore Keyword Error
Summary of Issue:
- Underscore (
_) is a keyword in Java 17 - Keywords cannot be used as identifiers
Affected Code Example
The following example code demonstrates the Underscore Keyword error:
package com.veeva.vault.custom.triggers;
import com.veeva.vault.sdk.api.data.Record;
import com.veeva.vault.sdk.api.data.RecordChange;
import com.veeva.vault.sdk.api.data.RecordEvent;
import com.veeva.vault.sdk.api.data.RecordTrigger;
import com.veeva.vault.sdk.api.data.RecordTriggerContext;
import com.veeva.vault.sdk.api.data.RecordTriggerInfo;
@RecordTriggerInfo(object = "vsdk_hello_world__c", name="vsdk_hello_world__c", events = {RecordEvent.BEFORE_INSERT})
public class HelloWorld implements RecordTrigger {
public void execute(RecordTriggerContext recordTriggerContext) {
LogService logService = ServiceLocator.locate(LogService.class);
// Cannot use underscore (_) as identifier
Record _ = recordTriggerContext.getRecordChanges().get(0).getNew();
// Cannot use underscore (_) as identifier
List<BigDecimal> bgdList = VaultCollections.newList();
bgdList.stream().forEach(_ -> _.add(new BigDecimal(14)));
}
}
Compilation Error
Compiling the affected code example produces the following error:
java: as of release 9, '_' is a keyword, and may not be used as an identifier
java: '_' used as an identifier
(use of '_' as an identifier is forbidden for lambda parameters)
Solution
Replace all identifiers using an underscore (_) with a different, non-keyword String.
package com.veeva.vault.custom.triggers;
import com.veeva.vault.sdk.api.data.Record;
import com.veeva.vault.sdk.api.data.RecordChange;
import com.veeva.vault.sdk.api.data.RecordEvent;
import com.veeva.vault.sdk.api.data.RecordTrigger;
import com.veeva.vault.sdk.api.data.RecordTriggerContext;
import com.veeva.vault.sdk.api.data.RecordTriggerInfo;
@RecordTriggerInfo(object = "vsdk_hello_world__c", name="vsdk_hello_world__c", events = {RecordEvent.BEFORE_INSERT})
public class HelloWorld implements RecordTrigger {
public void execute(RecordTriggerContext recordTriggerContext) {
LogService logService = ServiceLocator.locate(LogService.class);
// Replaced underscore (_) identifier with non-keyword String
Record record = recordTriggerContext.getRecordChanges().get(0).getNew();
// Replaced underscore (_) identifier with non-keyword String
List<BigDecimal> bgdList = VaultCollections.newList();
bgdList.stream().forEach(bd -> bd.add(new BigDecimal(14)));
}
}

