-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
17
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
Windows 11 Enterprise
OS build: 22000.2057
openjdk version "17.0.7" 2023-04-18
OpenJDK Runtime Environment Temurin-17.0.7+7 (build 17.0.7+7)
OpenJDK 64-Bit Server VM Temurin-17.0.7+7 (build 17.0.7+7, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
When the super class modifies fields of the sub class before they are technically assigned then these changes will have no effect and will be over written by the sub class after wards.
Closest related bug I could find is: https://bugs.java.com/bugdatabase/view_bug?bug_id=6275018
REGRESSION : Last worked in version 17.0.7
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
create a class that has a method that gets called in the constructor of this super class. This must modify fields in its sub-class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The following lines should be printed in the terminal
Check
123
true
"Hello World"
constructor
123
true
"Hello World"
when done constructing
123
true
"Hello World"
ACTUAL -
The following lines are actually be printed in the terminal:
Check
123
true
"Hello World"
constructor
null
null
null
when done constructing
null
null
null
---------- BEGIN SOURCE ----------
/*
* I created the following github repo that should contain all the java code to reproduce:
* https://github.com/St-H123/Java-Compliler-bug
*
* I also wrote more information but in case you would also like the raw source code I have it here:
*/
/**
* Just a class to help explain the problem as short as possible
*/
public class Entry {
public String value = "";
public String field = "";
}
/**
* The fixed version of the problemetic class
*/
public class FixedStringAssigned extends SuperClass {
public Integer valueOne;
public Boolean valueTwo;
public String valueThree;
public FixedStringAssigned(String input) throws IllegalArgumentException {
super(input);
System.out.println("constructor");
System.out.println(valueOne);
System.out.println(valueTwo);
System.out.println(valueThree);
System.out.println();
}
@Override
protected void assign(Entry entry) throws IllegalArgumentException{
switch (entry.field) {
case "valueOne":
valueOne = Integer.parseInt(entry.value);
break;
case "valueTwo":
valueTwo = Boolean.parseBoolean(entry.value);
break;
case "valueThree":
valueThree = entry.value;
break;
default:
super.assign(entry);
}
}
@Override
protected void check() {
System.out.println("Check");
System.out.println(valueOne);
if (valueOne == null) {
throw new IllegalStateException();
}
System.out.println(valueTwo);
if (valueTwo == null) {
throw new IllegalStateException();
}
System.out.println(valueThree);
if (valueThree == null) {
throw new IllegalStateException();
}
System.out.println();
}
}
public class Main {
public static void main(String[] args) {
StringAssigned instance = new StringAssigned("valueOne:123,valueThree:\"Hello World\",valueTwo:true");
System.out.println("when done constructring");
System.out.println(instance.valueOne);
System.out.println(instance.valueTwo);
System.out.println(instance.valueThree);
System.out.println();
}
}
/**
* Helper class.
*/
public class Splitter {
public static Entry[] split(String input) {
String[] array = (input.split(","));
Entry[] entries = new Entry[array.length];
for (int index = 0; index < array.length; index++) {
String[] split = array[index].split(":");
String field = split[0];
String value = split[1];
entries[index] = new Entry();
entries[index].value = value;
entries[index].field = field;
}
return entries;
}
}
/**
* The problemetic class
*/
public class StringAssigned extends SuperClass {
public Integer valueOne = null;
public Boolean valueTwo = null;
public String valueThree = null;
public StringAssigned(String input) throws IllegalArgumentException {
super(input);
System.out.println("constructor");
System.out.println(valueOne);
System.out.println(valueTwo);
System.out.println(valueThree);
System.out.println();
}
@Override
protected void assign(Entry entry) throws IllegalArgumentException{
switch (entry.field) {
case "valueOne":
valueOne = Integer.parseInt(entry.value);
break;
case "valueTwo":
valueTwo = Boolean.parseBoolean(entry.value);
break;
case "valueThree":
valueThree = entry.value;
break;
default:
super.assign(entry);
}
}
@Override
protected void check() {
System.out.println("Check");
System.out.println(valueOne);
if (valueOne == null) {
throw new IllegalStateException();
}
System.out.println(valueTwo);
if (valueTwo == null) {
throw new IllegalStateException();
}
System.out.println(valueThree);
if (valueThree == null) {
throw new IllegalStateException();
}
System.out.println();
}
}
/**
* The super class of StringAssigned.
*/
public abstract class SuperClass {
public SuperClass(String input) throws IllegalArgumentException{
Entry[] entries = Splitter.split(input);
for (Entry entry : entries) {
this.assign(entry);
}
this.check();
}
/**
* goes through the fields and assigns them
* throws an exception if the field is not reconised
*/
protected void assign(Entry entry) throws IllegalArgumentException{
throw new IllegalArgumentException();
}
/**
* Checks all the fields and throws exceptions while in the
* constructor if they are not correct.
*/
protected abstract void check();
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
not a true work around but instead of using `... = null;` just leave the assignment. This would only work if you want your default to be `null`
FREQUENCY : always
Windows 11 Enterprise
OS build: 22000.2057
openjdk version "17.0.7" 2023-04-18
OpenJDK Runtime Environment Temurin-17.0.7+7 (build 17.0.7+7)
OpenJDK 64-Bit Server VM Temurin-17.0.7+7 (build 17.0.7+7, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
When the super class modifies fields of the sub class before they are technically assigned then these changes will have no effect and will be over written by the sub class after wards.
Closest related bug I could find is: https://bugs.java.com/bugdatabase/view_bug?bug_id=6275018
REGRESSION : Last worked in version 17.0.7
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
create a class that has a method that gets called in the constructor of this super class. This must modify fields in its sub-class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The following lines should be printed in the terminal
Check
123
true
"Hello World"
constructor
123
true
"Hello World"
when done constructing
123
true
"Hello World"
ACTUAL -
The following lines are actually be printed in the terminal:
Check
123
true
"Hello World"
constructor
null
null
null
when done constructing
null
null
null
---------- BEGIN SOURCE ----------
/*
* I created the following github repo that should contain all the java code to reproduce:
* https://github.com/St-H123/Java-Compliler-bug
*
* I also wrote more information but in case you would also like the raw source code I have it here:
*/
/**
* Just a class to help explain the problem as short as possible
*/
public class Entry {
public String value = "";
public String field = "";
}
/**
* The fixed version of the problemetic class
*/
public class FixedStringAssigned extends SuperClass {
public Integer valueOne;
public Boolean valueTwo;
public String valueThree;
public FixedStringAssigned(String input) throws IllegalArgumentException {
super(input);
System.out.println("constructor");
System.out.println(valueOne);
System.out.println(valueTwo);
System.out.println(valueThree);
System.out.println();
}
@Override
protected void assign(Entry entry) throws IllegalArgumentException{
switch (entry.field) {
case "valueOne":
valueOne = Integer.parseInt(entry.value);
break;
case "valueTwo":
valueTwo = Boolean.parseBoolean(entry.value);
break;
case "valueThree":
valueThree = entry.value;
break;
default:
super.assign(entry);
}
}
@Override
protected void check() {
System.out.println("Check");
System.out.println(valueOne);
if (valueOne == null) {
throw new IllegalStateException();
}
System.out.println(valueTwo);
if (valueTwo == null) {
throw new IllegalStateException();
}
System.out.println(valueThree);
if (valueThree == null) {
throw new IllegalStateException();
}
System.out.println();
}
}
public class Main {
public static void main(String[] args) {
StringAssigned instance = new StringAssigned("valueOne:123,valueThree:\"Hello World\",valueTwo:true");
System.out.println("when done constructring");
System.out.println(instance.valueOne);
System.out.println(instance.valueTwo);
System.out.println(instance.valueThree);
System.out.println();
}
}
/**
* Helper class.
*/
public class Splitter {
public static Entry[] split(String input) {
String[] array = (input.split(","));
Entry[] entries = new Entry[array.length];
for (int index = 0; index < array.length; index++) {
String[] split = array[index].split(":");
String field = split[0];
String value = split[1];
entries[index] = new Entry();
entries[index].value = value;
entries[index].field = field;
}
return entries;
}
}
/**
* The problemetic class
*/
public class StringAssigned extends SuperClass {
public Integer valueOne = null;
public Boolean valueTwo = null;
public String valueThree = null;
public StringAssigned(String input) throws IllegalArgumentException {
super(input);
System.out.println("constructor");
System.out.println(valueOne);
System.out.println(valueTwo);
System.out.println(valueThree);
System.out.println();
}
@Override
protected void assign(Entry entry) throws IllegalArgumentException{
switch (entry.field) {
case "valueOne":
valueOne = Integer.parseInt(entry.value);
break;
case "valueTwo":
valueTwo = Boolean.parseBoolean(entry.value);
break;
case "valueThree":
valueThree = entry.value;
break;
default:
super.assign(entry);
}
}
@Override
protected void check() {
System.out.println("Check");
System.out.println(valueOne);
if (valueOne == null) {
throw new IllegalStateException();
}
System.out.println(valueTwo);
if (valueTwo == null) {
throw new IllegalStateException();
}
System.out.println(valueThree);
if (valueThree == null) {
throw new IllegalStateException();
}
System.out.println();
}
}
/**
* The super class of StringAssigned.
*/
public abstract class SuperClass {
public SuperClass(String input) throws IllegalArgumentException{
Entry[] entries = Splitter.split(input);
for (Entry entry : entries) {
this.assign(entry);
}
this.check();
}
/**
* goes through the fields and assigns them
* throws an exception if the field is not reconised
*/
protected void assign(Entry entry) throws IllegalArgumentException{
throw new IllegalArgumentException();
}
/**
* Checks all the fields and throws exceptions while in the
* constructor if they are not correct.
*/
protected abstract void check();
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
not a true work around but instead of using `... = null;` just leave the assignment. This would only work if you want your default to be `null`
FREQUENCY : always