codeconsole opened a new pull request, #3202:
URL: https://github.com/apache/groovy/pull/3202
`IOGroovyMethods.newObjectInputStream(InputStream, ClassLoader)` resolves
the classes named in a stream through the given class loader, but only in
`resolveClass`. A serialized `java.lang.reflect.Proxy` is resolved by
`resolveProxyClass`, which kept the JDK default: it loads the proxy's
interfaces through the latest user-defined loader on the call stack. So a proxy
whose interface is only visible to the given loader cannot be read back:
```groovy
def gcl = new GroovyClassLoader()
def i = gcl.parseClass('interface Greeter { String greet() }')
def h = gcl.parseClass('''class H implements
java.lang.reflect.InvocationHandler, Serializable {
Object invoke(Object p, java.lang.reflect.Method m, Object[] a) { 'hi' }
}''')
def proxy = java.lang.reflect.Proxy.newProxyInstance(gcl, [i] as Class[],
h.getDeclaredConstructor().newInstance())
def bytes = new ByteArrayOutputStream()
bytes.withObjectOutputStream { it.writeObject(proxy) }
new ByteArrayInputStream(bytes.toByteArray()).withObjectInputStream(gcl) {
it.readObject().greet() }
// java.lang.ClassNotFoundException: Greeter
```
Seen in 4.0.33, 5.0.8 and 6.0.0 too.
The stream now also overrides `resolveProxyClass`. It follows
`ObjectInputStream.resolveProxyClass` but loads each interface with
`Class.forName(name, false, classLoader)`. Non-public interfaces must share one
loader, and the proxy class is defined there; otherwise it is defined in the
given loader. `Proxy.getProxyClass` builds the class, with the deprecation
warning suppressed as in the JDK's own implementation. The
`withObjectInputStream` and `newObjectInputStream` class-loader variants on
InputStream, File and Path all use this stream.
This and #3197 (GROOVY-12676, primitive classes in `resolveClass`) change
different methods of the same stream and merge cleanly.
## Tests
These fail without the change:
- `BinaryStreamsTest.testWithObjectStreamAndClassLoaderReadsProxy`
- `BinaryStreamsTest.testWithObjectStreamAndClassLoaderReadsProxyFromFile`
-
`BinaryStreamsTest.testWithObjectStreamAndClassLoaderReadsProxyOfNonPublicInterface`
-
`BinaryStreamsTest.testWithObjectStreamAndClassLoaderResolvesProxyInterfacesThroughThatLoader`
- `NioExtensionsTest.testWithObjectInputStreamAndClassLoaderReadsProxy`
`BinaryStreamsTest`, `IOGroovyMethodsTest`, `AutoCloneTransformTest`,
`CanonicalComponentsTransformTest` and `org.apache.groovy.nio.*` pass. The
Checkstyle and CodeNarc gates pass.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]