Details
-
Bug
-
Resolution: Fixed
-
P3
-
7u4
-
b93
-
windows_7
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8018831 | 7u45 | Sergey Malenkov | P3 | Closed | Fixed | b01 |
JDK-8015390 | 7u40 | Sergey Malenkov | P3 | Closed | Fixed | b28 |
Description
FULL PRODUCT VERSION :
java version " 1.7.0_17 "
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
EXTRA RELEVANT SYSTEM CONFIGURATION :
The following jar files are required: guava-14.0.1.jar and junit-4.10.jar. They are available at https://code.google.com/p/guava-libraries/ and https://github.com/junit-team/junit/wiki
A DESCRIPTION OF THE PROBLEM :
Encoding and decoding of a valid Java Bean, containing a com.google.common.collect.HashMultimap, fails. The error results from an issue in com.sun.beans.finder.MethodFinder.findMethod. The HashMultimap class inherits it's " put " method from the package private implementation in: StandardSetMultimap (and above). But that method isn't callable as the class that declares it isn't public. What the FindMethod method should do is find the public method from the Multimap interface and return that - since that is the only method that can be called without special privileges.
REGRESSION. Last worked in version 7
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) compile the unit test
javac -cp guava-14.0.1.jar;junit-4.10.jar;. XmlEncoderTest.java
2) run the unit test
java -cp guava-14.0.1.jar;junit-4.10.jar;. org.junit.runner.JUnitCore XmlEncoderTest
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The unit test should produce a valid XML file containing the following:
<?xml version= " 1.0 " encoding= " UTF-8 " ?>
<java version= " 1.7.0_17 " class= " java.beans.XMLDecoder " >
<object class= " XmlEncoderTest$SomeBean " >
<void property= " stateMap " >
<object class= " com.google.common.collect.HashMultimap " method= " create " >
<void method= " put " >
<string>pz3</string>
<string>pz4</string>
</void>
<void method= " put " >
<string>pz1</string>
<string>pz2</string>
</void>
</object>
</void>
</object>
</java>
The unit test should then decode the XML into a SomeBean object contains a HashMultimap with 2 entries (pz1,pz2) and (pz3,pz4).
ACTUAL -
The unit test produces a valid XML file; however, the following statements are written to output. Additionally, the decode SomeBean object's HashMultimap contains no entries.
.java.lang.Exception: Encoder: discarding statement HashMultimap.put( " pz3 " , " pz4
" );
Continuing ...
java.lang.Exception: Encoder: discarding statement HashMultimap.put( " pz1 " , " pz2 "
);
Continuing ...
java.lang.NoSuchMethodException: <unbound>=HashMultimap.put( " pz3 " , " pz4 " );
Continuing ...
java.lang.NoSuchMethodException: <unbound>=HashMultimap.put( " pz1 " , " pz2 " );
Continuing ...
ERROR MESSAGES/STACK TRACES THAT OCCUR :
JUnit version 4.10
.java.lang.Exception: Encoder: discarding statement HashMultimap.put( " pz3 " , " pz4
" );
Continuing ...
java.lang.Exception: Encoder: discarding statement HashMultimap.put( " pz1 " , " pz2 "
);
Continuing ...
java.lang.NoSuchMethodException: <unbound>=HashMultimap.put( " pz3 " , " pz4 " );
Continuing ...
java.lang.NoSuchMethodException: <unbound>=HashMultimap.put( " pz1 " , " pz2 " );
Continuing ...
E
Time: 0.308
There was 1 failure:
1) testEncoding(XmlEncoderTest)
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:92)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertTrue(Assert.java:54)
at XmlEncoderTest.testEncoding(XmlEncoderTest.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(Framework
Method.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCal
lable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMe
thod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMet
hod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRun
ner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRun
ner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
at org.junit.runner.JUnitCore.runMain(JUnitCore.java:98)
at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:53)
at org.junit.runner.JUnitCore.main(JUnitCore.java:45)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import static org.junit.Assert.*;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.Statement;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Map;
import org.junit.Test;
import com.google.common.collect.HashMultimap;
public class XmlEncoderTest {
@Test
public void testEncoding() throws Exception {
// create the bean
SomeBean sb = new SomeBean();
// add some data
HashMultimap<String, String> stateMap = HashMultimap.create();
stateMap.put( " pz1 " , " pz2 " );
stateMap.put( " pz3 " , " pz4 " );
sb.setStateMap(stateMap);
String fileName = " myXMLFile.xml " ;
// encode as xml
FileOutputStream os = new FileOutputStream(fileName);
XMLEncoder encoder = new XMLEncoder(os);
encoder.setPersistenceDelegate(HashMultimap.class, new CustomPersistenceDelegate());
encoder.writeObject(sb);
encoder.close();
// decode the xml
XMLDecoder decoder = new XMLDecoder(new FileInputStream(fileName));
Object deSerializedObject = decoder.readObject();
assertNotNull(deSerializedObject);
HashMultimap<String, String> map = ((SomeBean) deSerializedObject).getStateMap();
assertTrue(map.containsKey( " pz1 " ));
assertTrue(map.containsKey( " pz3 " ));
}
static class CustomPersistenceDelegate extends DefaultPersistenceDelegate {
@Override
protected Expression instantiate(Object oldInstance, Encoder out) {
return new Expression(oldInstance, oldInstance.getClass(), " create " , null);
}
@Override
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
com.google.common.collect.HashMultimap<String, String> m = (com.google.common.collect.HashMultimap) oldInstance;
for (Map.Entry<String, String> entry : m.entries()) {
out.writeStatement(new Statement(oldInstance, " put " , new Object[] { entry.getKey(), entry.getValue() }));
}
}
}
static public class SomeBean {
private HashMultimap<String, String> stateMap;
public HashMultimap<String, String> getStateMap() {
return stateMap;
}
public void setStateMap(HashMultimap<String, String> stateMap) {
this.stateMap = stateMap;
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use JRE 7 u3 or lower. The bug is present in JRE 7 u4 and up.
java version " 1.7.0_17 "
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
EXTRA RELEVANT SYSTEM CONFIGURATION :
The following jar files are required: guava-14.0.1.jar and junit-4.10.jar. They are available at https://code.google.com/p/guava-libraries/ and https://github.com/junit-team/junit/wiki
A DESCRIPTION OF THE PROBLEM :
Encoding and decoding of a valid Java Bean, containing a com.google.common.collect.HashMultimap, fails. The error results from an issue in com.sun.beans.finder.MethodFinder.findMethod. The HashMultimap class inherits it's " put " method from the package private implementation in: StandardSetMultimap (and above). But that method isn't callable as the class that declares it isn't public. What the FindMethod method should do is find the public method from the Multimap interface and return that - since that is the only method that can be called without special privileges.
REGRESSION. Last worked in version 7
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) compile the unit test
javac -cp guava-14.0.1.jar;junit-4.10.jar;. XmlEncoderTest.java
2) run the unit test
java -cp guava-14.0.1.jar;junit-4.10.jar;. org.junit.runner.JUnitCore XmlEncoderTest
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The unit test should produce a valid XML file containing the following:
<?xml version= " 1.0 " encoding= " UTF-8 " ?>
<java version= " 1.7.0_17 " class= " java.beans.XMLDecoder " >
<object class= " XmlEncoderTest$SomeBean " >
<void property= " stateMap " >
<object class= " com.google.common.collect.HashMultimap " method= " create " >
<void method= " put " >
<string>pz3</string>
<string>pz4</string>
</void>
<void method= " put " >
<string>pz1</string>
<string>pz2</string>
</void>
</object>
</void>
</object>
</java>
The unit test should then decode the XML into a SomeBean object contains a HashMultimap with 2 entries (pz1,pz2) and (pz3,pz4).
ACTUAL -
The unit test produces a valid XML file; however, the following statements are written to output. Additionally, the decode SomeBean object's HashMultimap contains no entries.
.java.lang.Exception: Encoder: discarding statement HashMultimap.put( " pz3 " , " pz4
" );
Continuing ...
java.lang.Exception: Encoder: discarding statement HashMultimap.put( " pz1 " , " pz2 "
);
Continuing ...
java.lang.NoSuchMethodException: <unbound>=HashMultimap.put( " pz3 " , " pz4 " );
Continuing ...
java.lang.NoSuchMethodException: <unbound>=HashMultimap.put( " pz1 " , " pz2 " );
Continuing ...
ERROR MESSAGES/STACK TRACES THAT OCCUR :
JUnit version 4.10
.java.lang.Exception: Encoder: discarding statement HashMultimap.put( " pz3 " , " pz4
" );
Continuing ...
java.lang.Exception: Encoder: discarding statement HashMultimap.put( " pz1 " , " pz2 "
);
Continuing ...
java.lang.NoSuchMethodException: <unbound>=HashMultimap.put( " pz3 " , " pz4 " );
Continuing ...
java.lang.NoSuchMethodException: <unbound>=HashMultimap.put( " pz1 " , " pz2 " );
Continuing ...
E
Time: 0.308
There was 1 failure:
1) testEncoding(XmlEncoderTest)
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:92)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertTrue(Assert.java:54)
at XmlEncoderTest.testEncoding(XmlEncoderTest.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(Framework
Method.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCal
lable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMe
thod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMet
hod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRun
ner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRun
ner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
at org.junit.runner.JUnitCore.runMain(JUnitCore.java:98)
at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:53)
at org.junit.runner.JUnitCore.main(JUnitCore.java:45)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import static org.junit.Assert.*;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.Statement;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Map;
import org.junit.Test;
import com.google.common.collect.HashMultimap;
public class XmlEncoderTest {
@Test
public void testEncoding() throws Exception {
// create the bean
SomeBean sb = new SomeBean();
// add some data
HashMultimap<String, String> stateMap = HashMultimap.create();
stateMap.put( " pz1 " , " pz2 " );
stateMap.put( " pz3 " , " pz4 " );
sb.setStateMap(stateMap);
String fileName = " myXMLFile.xml " ;
// encode as xml
FileOutputStream os = new FileOutputStream(fileName);
XMLEncoder encoder = new XMLEncoder(os);
encoder.setPersistenceDelegate(HashMultimap.class, new CustomPersistenceDelegate());
encoder.writeObject(sb);
encoder.close();
// decode the xml
XMLDecoder decoder = new XMLDecoder(new FileInputStream(fileName));
Object deSerializedObject = decoder.readObject();
assertNotNull(deSerializedObject);
HashMultimap<String, String> map = ((SomeBean) deSerializedObject).getStateMap();
assertTrue(map.containsKey( " pz1 " ));
assertTrue(map.containsKey( " pz3 " ));
}
static class CustomPersistenceDelegate extends DefaultPersistenceDelegate {
@Override
protected Expression instantiate(Object oldInstance, Encoder out) {
return new Expression(oldInstance, oldInstance.getClass(), " create " , null);
}
@Override
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
super.initialize(type, oldInstance, newInstance, out);
com.google.common.collect.HashMultimap<String, String> m = (com.google.common.collect.HashMultimap) oldInstance;
for (Map.Entry<String, String> entry : m.entries()) {
out.writeStatement(new Statement(oldInstance, " put " , new Object[] { entry.getKey(), entry.getValue() }));
}
}
}
static public class SomeBean {
private HashMultimap<String, String> stateMap;
public HashMultimap<String, String> getStateMap() {
return stateMap;
}
public void setStateMap(HashMultimap<String, String> stateMap) {
this.stateMap = stateMap;
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use JRE 7 u3 or lower. The bug is present in JRE 7 u4 and up.
Attachments
Issue Links
- backported by
-
JDK-8015390 Java Bean Persistence with XMLEncoder
- Closed
-
JDK-8018831 Java Bean Persistence with XMLEncoder
- Closed
- relates to
-
JDK-7092744 XMLEncoder fails to encode and breaks backward compatibility
- Resolved