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]

Reply via email to