@@ -326,26 +326,30 @@ private static class Logging {
326
326
* read* requests
327
327
*/
328
328
329
- /* ClassCache Entry for caching class.forName results upon enableClassCaching */
330
- private static final ClassCache classCache ;
331
- private static final boolean isClassCachingEnabled ;
332
- static {
333
- isClassCachingEnabled =
334
- AccessController .doPrivileged (new GetClassCachingSettingAction ());
335
- classCache = (isClassCachingEnabled ? new ClassCache () : null );
336
- }
329
+ /* ClassCache Entry for caching class.forName results upon enableClassCaching */
330
+ private static final ClassCache classCache ;
331
+ private static final boolean isClassCachingEnabled ;
332
+ static {
333
+ isClassCachingEnabled =
334
+ AccessController .doPrivileged (new GetClassCachingSettingAction ());
335
+ classCache = (isClassCachingEnabled ? new ClassCache () : null );
336
+ }
337
337
338
338
339
- /** if true LUDCL/forName results would be cached, false by default starting Java8 */
340
- private static final class GetClassCachingSettingAction
341
- implements PrivilegedAction <Boolean > {
342
- public Boolean run () {
343
- String property =
344
- System .getProperty ("com.ibm.enableClassCaching" , "false " );
345
- return property .equalsIgnoreCase ("true" );
346
- }
347
- }
339
+ /** if true LUDCL/forName results would be cached, true by default starting Java8 */
340
+ private static final class GetClassCachingSettingAction
341
+ implements PrivilegedAction <Boolean > {
342
+ public Boolean run () {
343
+ String property =
344
+ System .getProperty ("com.ibm.enableClassCaching" , "true " );
345
+ return property .equalsIgnoreCase ("true" );
346
+ }
347
+ }
348
348
private ClassLoader cachedLudcl ;
349
+ /* If user code is invoked in the middle of a call to readObject the cachedLudcl
350
+ * must be refreshed as the ludcl could have been changed while in user code.
351
+ */
352
+ private boolean refreshLudcl = false ;
349
353
350
354
/**
351
355
* Creates an ObjectInputStream that reads from the specified InputStream.
@@ -496,7 +500,7 @@ private Object readObjectImpl(Class caller)
496
500
ClassLoader oldCachedLudcl = null ;
497
501
boolean setCached = false ;
498
502
499
- if ((curContext == null ) && (isClassCachingEnabled )) {
503
+ if ((( null == curContext ) || refreshLudcl ) && (isClassCachingEnabled )) {
500
504
oldCachedLudcl = cachedLudcl ;
501
505
502
506
// If caller is not provided, follow the standard path to get the cachedLudcl.
@@ -509,6 +513,7 @@ private Object readObjectImpl(Class caller)
509
513
}
510
514
511
515
setCached = true ;
516
+ refreshLudcl = false ;
512
517
}
513
518
514
519
// if nested read, passHandle contains handle of enclosing object
@@ -613,10 +618,11 @@ public Object readUnshared() throws IOException, ClassNotFoundException {
613
618
ClassLoader oldCachedLudcl = null ;
614
619
boolean setCached = false ;
615
620
616
- if ((curContext == null ) && (isClassCachingEnabled )) {
621
+ if ((( null == curContext ) || refreshLudcl ) && (isClassCachingEnabled )) {
617
622
oldCachedLudcl = cachedLudcl ;
618
623
cachedLudcl = latestUserDefinedLoader ();
619
624
setCached = true ;
625
+ refreshLudcl = false ;
620
626
}
621
627
622
628
// if nested read, passHandle contains handle of enclosing object
@@ -793,10 +799,15 @@ protected Class<?> resolveClass(ObjectStreamClass desc)
793
799
{
794
800
String name = desc .getName ();
795
801
try {
796
- return ((classCache == null ) ?
797
- Class .forName (name , false , latestUserDefinedLoader ()) :
798
- classCache .get (name , cachedLudcl ));
799
-
802
+ if (null == classCache ) {
803
+ return Class .forName (name , false , latestUserDefinedLoader ());
804
+ } else {
805
+ if (refreshLudcl ) {
806
+ cachedLudcl = latestUserDefinedLoader ();
807
+ refreshLudcl = false ;
808
+ }
809
+ return classCache .get (name , cachedLudcl );
810
+ }
800
811
} catch (ClassNotFoundException ex ) {
801
812
Class <?> cl = primClasses .get (name );
802
813
if (cl != null ) {
@@ -2199,6 +2210,8 @@ private Object readOrdinaryObject(boolean unshared)
2199
2210
handles .lookupException (passHandle ) == null &&
2200
2211
desc .hasReadResolveMethod ())
2201
2212
{
2213
+ /* user code is invoked */
2214
+ refreshLudcl = true ;
2202
2215
Object rep = desc .invokeReadResolve (obj );
2203
2216
if (unshared && rep .getClass ().isArray ()) {
2204
2217
rep = cloneArray (rep );
@@ -2319,6 +2332,9 @@ private void readSerialData(Object obj, ObjectStreamClass desc)
2319
2332
curContext = new SerialCallbackContext (obj , slotDesc );
2320
2333
2321
2334
bin .setBlockDataMode (true );
2335
+
2336
+ /* user code is invoked */
2337
+ refreshLudcl = true ;
2322
2338
slotDesc .invokeReadObject (obj , this );
2323
2339
} catch (ClassNotFoundException ex ) {
2324
2340
/*
@@ -2371,6 +2387,8 @@ private void readSerialData(Object obj, ObjectStreamClass desc)
2371
2387
slotDesc .hasReadObjectNoDataMethod () &&
2372
2388
handles .lookupException (passHandle ) == null )
2373
2389
{
2390
+ /* user code is invoked */
2391
+ refreshLudcl = true ;
2374
2392
slotDesc .invokeReadObjectNoData (obj );
2375
2393
}
2376
2394
}
0 commit comments