What steps does it take to reproduce the issue?
- When does this issue occur?
When dataverse.lang.directory is configured and a Bundle_en.properties file exists in that directory (even an empty file), Dataverse fails to start after a restart or redeploy.
- Which page(s) does it occurs on?
Not page-specific; Dataverse fails during application deployment/startup. No pages are reachable.
- Deploy Dataverse 6.9 on Payara 6.2025.10 - verify it starts normally.
- Set the JVM option:
asadmin create-jvm-options -- "-Ddataverse.lang.directory=/usr/local/payara6/glassfish/domains/domain1/lang"
- Create the directory and an override file (content does not matter — even an empty file triggers the bug):
mkdir -p /usr/local/payara6/glassfish/domains/domain1/lang
touch /usr/local/payara6/glassfish/domains/domain1/lang/Bundle_en.properties
chown -R dataverse:dataverse /usr/local/payara6/glassfish/domains/domain1/lang
- Restart Payara:
- Dataverse fails to start with
NullPointerException in PasswordValidatorServiceBean.<init>. The version API (/api/info/version) returns a Payara error page instead of JSON. Removing the file and restarting immediately resolves it.
- To whom does it occur (all users, curators, superusers)?
All users — the application does not start at all.
- What did you expect to happen?
Dataverse should start normally and use the keys in Bundle_en.properties as overrides for the English locale, as documented in the Installation Guide. This is the recommended upgrade-safe mechanism for text customizations.
Which version of Dataverse are you using?
- Dataverse: 6.9 (build 2027-e2021d3)
- Payara: 6.2025.10 (build 42)
- Java: OpenJDK 17.0.19 (Red Hat)
- OS: RHEL 8 (Rocky Linux 8)
Dataverse 6.10 likely affected as well (same code pattern present in the v6.10 source for GoodStrengthRule.java).
Any related open or closed issues to this bug report?
Not aware of any existing issues for this specific failure.
Screenshots:
Full stack trace from server.log:
[SEVERE] Exception while loading the app : EJB Container initialization error
java.lang.NullPointerException
at java.base/java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
at java.base/java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006)
at java.base/java.util.Properties.put(Properties.java:1301)
at java.base/java.util.Properties.setProperty(Properties.java:229)
at edu.harvard.iq.dataverse.validation.PasswordValidatorServiceBean.<init>(PasswordValidatorServiceBean.java:102)
at edu.harvard.iq.dataverse.validation.__EJB31_Generated__PasswordValidatorServiceBean__Intf____Bean__.<init>(Unknown Source)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...
at com.sun.ejb.containers.StatelessSessionContainer.initializeHome(StatelessSessionContainer.java:216)
at com.sun.ejb.containers.StatelessContainerFactory.createContainer(StatelessContainerFactory.java:63)
at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:225)
Root cause analysis:
GoodStrengthRule.java initializes static fields at class-load time by calling BundleUtil.getStringFromBundle():
static final String ERROR_CODE_GOODSTRENGTH = BundleUtil.getStringFromBundle("passwdVal.goodStrengthRule.errorCode");
static final String ERROR_MESSAGE_GOODSTRENGTH = BundleUtil.getStringFromBundle("passwdVal.goodStrengthRule.errorMsg");
When dataverse.lang.directory is set, BundleUtil attempts to load the ResourceBundle from the external directory during class loading. At this point during EJB container initialization, the resource bundle system is not fully available, so BundleUtil.getStringFromBundle() returns null. This null is then passed to Properties.setProperty() in PasswordValidatorServiceBean.<init> (line 102):
properties.setProperty(GoodStrengthRule.ERROR_CODE_GOODSTRENGTH, GoodStrengthRule.ERROR_MESSAGE_GOODSTRENGTH);
ConcurrentHashMap.put() (which backs Properties) does not allow null keys or values, hence the NPE.
Workaround:
Remove the JVM option to disable external bundle overrides entirely:
asadmin delete-jvm-options -- "-Ddataverse.lang.directory=/usr/local/payara6/glassfish/domains/domain1/lang"
This means text customizations cannot be externalized in an upgrade-safe way on 6.9.
Are you thinking about creating a pull request for this issue?
Happy to discuss, though the fix appears straightforward. The suggested (by my coding assistant) approach is to change GoodStrengthRule.java to lazy initialization so BundleUtil is not called during class loading:
class GoodStrengthRule extends LengthRule {
static String getErrorCode() {
return BundleUtil.getStringFromBundle("passwdVal.goodStrengthRule.errorCode");
}
static String getErrorMessage() {
return BundleUtil.getStringFromBundle("passwdVal.goodStrengthRule.errorMsg");
}
@Override
public RuleResult validate(PasswordData passwordData) {
final RuleResult result = super.validate(passwordData);
if (!result.isValid()) {
result.getDetails().clear();
result.getDetails().add(new RuleResultDetail(getErrorCode(), createRuleResultDetailParameters()));
}
return result;
}
}
And add a null guard in PasswordValidatorServiceBean:
public PasswordValidatorServiceBean() {
final Properties properties = PropertiesMessageResolver.getDefaultProperties();
String errorCode = GoodStrengthRule.getErrorCode();
String errorMessage = GoodStrengthRule.getErrorMessage();
if (errorCode != null && errorMessage != null) {
properties.setProperty(errorCode, errorMessage);
}
messageResolver = new PropertiesMessageResolver(properties);
}
This ensures BundleUtil is called at first validation use (when the application is fully initialized) rather than during class loading. I'm not a java developer and I have not tested this at all so I'm not sure how reasonable this suggestion is.
What steps does it take to reproduce the issue?
When
dataverse.lang.directoryis configured and aBundle_en.propertiesfile exists in that directory (even an empty file), Dataverse fails to start after a restart or redeploy.Not page-specific; Dataverse fails during application deployment/startup. No pages are reachable.
NullPointerExceptioninPasswordValidatorServiceBean.<init>. The version API (/api/info/version) returns a Payara error page instead of JSON. Removing the file and restarting immediately resolves it.All users — the application does not start at all.
Dataverse should start normally and use the keys in
Bundle_en.propertiesas overrides for the English locale, as documented in the Installation Guide. This is the recommended upgrade-safe mechanism for text customizations.Which version of Dataverse are you using?
Dataverse 6.10 likely affected as well (same code pattern present in the v6.10 source for
GoodStrengthRule.java).Any related open or closed issues to this bug report?
Not aware of any existing issues for this specific failure.
Screenshots:
Full stack trace from
server.log:Root cause analysis:
GoodStrengthRule.javainitializes static fields at class-load time by callingBundleUtil.getStringFromBundle():When
dataverse.lang.directoryis set,BundleUtilattempts to load theResourceBundlefrom the external directory during class loading. At this point during EJB container initialization, the resource bundle system is not fully available, soBundleUtil.getStringFromBundle()returnsnull. This null is then passed toProperties.setProperty()inPasswordValidatorServiceBean.<init>(line 102):ConcurrentHashMap.put()(which backsProperties) does not allow null keys or values, hence the NPE.Workaround:
Remove the JVM option to disable external bundle overrides entirely:
This means text customizations cannot be externalized in an upgrade-safe way on 6.9.
Are you thinking about creating a pull request for this issue?
Happy to discuss, though the fix appears straightforward. The suggested (by my coding assistant) approach is to change
GoodStrengthRule.javato lazy initialization soBundleUtilis not called during class loading:And add a null guard in
PasswordValidatorServiceBean:This ensures
BundleUtilis called at first validation use (when the application is fully initialized) rather than during class loading. I'm not a java developer and I have not tested this at all so I'm not sure how reasonable this suggestion is.