Details
-
Bug
-
Resolution: Fixed
-
P3
-
21
Description
ADDITIONAL SYSTEM INFORMATION :
openjdk version "21-ea" 2023-09-19
OpenJDK Runtime Environment (build 21-ea+10-784)
OpenJDK 64-Bit Server VM (build 21-ea+10-784, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
Regression fromJDK-8299571:
The fix to the above issue introduced a new bug when registering the same `java.time.zone.ZoneRulesProvider` twice it will in fact remove the provider from the registered ones again.
REGRESSION : Last worked in version 20
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a new `java.time.zone.ZoneRulesProvider` whichg provides a new unregistered ZoneId.
2. Call `java.time.zone.ZoneRulesProvider.registerProvider(zrp);` once. Provider will be registered.
3. Call `java.time.zone.ZoneRulesProvider.registerProvider(zrp);` again. Registering will fail with a `ZoneRulesException` as expected.
4. The newly introduced cleanup will remove the provider again.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The provider should still be registered for the ZoneId because it was registered successfully once.
ACTUAL -
The provider is unregistered and the ZoneId is not available.
---------- BEGIN SOURCE ----------
import java.util.Set;
import java.util.NavigableMap;
import java.time.ZoneId;
import java.time.zone.ZoneRules;
import java.time.zone.ZoneRulesProvider;
import java.time.zone.ZoneRulesException;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertThrows;
class ZoneRulesProviderTest {
private static final String ZONE = "MyZone";
@Test void registerProviderTwice() {
// setup
ZoneRulesProvider zrp = new ZoneRulesProvider() {
@Override protected Set<String> provideZoneIds() {
return Set.of(ZONE);
}
@Override protected ZoneRules provideRules(String zoneId, boolean forCaching) {
return null;
}
@Override protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
return null;
}
};
assertFalse(ZoneId.getAvailableZoneIds().contains(ZONE));
ZoneRulesProvider.registerProvider(zrp);
assertTrue(ZoneId.getAvailableZoneIds().contains(ZONE));
assertNotNull(ZoneId.of(ZONE));
// exercise
assertThrows(ZoneRulesException.class, () -> ZoneRulesProvider.registerProvider(zrp));
// verify - these will fail
assertTrue(ZoneId.getAvailableZoneIds().contains(ZONE));
assertNotNull(ZoneId.of(ZONE));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Register the provider again (?)
FREQUENCY : always
openjdk version "21-ea" 2023-09-19
OpenJDK Runtime Environment (build 21-ea+10-784)
OpenJDK 64-Bit Server VM (build 21-ea+10-784, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
Regression from
The fix to the above issue introduced a new bug when registering the same `java.time.zone.ZoneRulesProvider` twice it will in fact remove the provider from the registered ones again.
REGRESSION : Last worked in version 20
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a new `java.time.zone.ZoneRulesProvider` whichg provides a new unregistered ZoneId.
2. Call `java.time.zone.ZoneRulesProvider.registerProvider(zrp);` once. Provider will be registered.
3. Call `java.time.zone.ZoneRulesProvider.registerProvider(zrp);` again. Registering will fail with a `ZoneRulesException` as expected.
4. The newly introduced cleanup will remove the provider again.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The provider should still be registered for the ZoneId because it was registered successfully once.
ACTUAL -
The provider is unregistered and the ZoneId is not available.
---------- BEGIN SOURCE ----------
import java.util.Set;
import java.util.NavigableMap;
import java.time.ZoneId;
import java.time.zone.ZoneRules;
import java.time.zone.ZoneRulesProvider;
import java.time.zone.ZoneRulesException;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertThrows;
class ZoneRulesProviderTest {
private static final String ZONE = "MyZone";
@Test void registerProviderTwice() {
// setup
ZoneRulesProvider zrp = new ZoneRulesProvider() {
@Override protected Set<String> provideZoneIds() {
return Set.of(ZONE);
}
@Override protected ZoneRules provideRules(String zoneId, boolean forCaching) {
return null;
}
@Override protected NavigableMap<String, ZoneRules> provideVersions(String zoneId) {
return null;
}
};
assertFalse(ZoneId.getAvailableZoneIds().contains(ZONE));
ZoneRulesProvider.registerProvider(zrp);
assertTrue(ZoneId.getAvailableZoneIds().contains(ZONE));
assertNotNull(ZoneId.of(ZONE));
// exercise
assertThrows(ZoneRulesException.class, () -> ZoneRulesProvider.registerProvider(zrp));
// verify - these will fail
assertTrue(ZoneId.getAvailableZoneIds().contains(ZONE));
assertNotNull(ZoneId.of(ZONE));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Register the provider again (?)
FREQUENCY : always
Attachments
Issue Links
- duplicates
-
JDK-8302898 ZoneRulesProvider.registerProvider() twice will remove provider
-
- Resolved
-
- relates to
-
JDK-8299571 ZoneRulesProvider.registerProvider() can leave inconsistent state on failure
-
- Closed
-