GateAwareObjectInputStream.java
01 /*
02  *  GateAwareObjectInputStream.java
03  *
04  *  Copyright (c) 1995-2012, The University of Sheffield. See the file
05  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
06  *
07  *  This file is part of GATE (see http://gate.ac.uk/), and is free
08  *  software, licenced under the GNU Library General Public License,
09  *  Version 2, June 1991 (in the distribution as file licence.html,
10  *  and also available at http://gate.ac.uk/gate/licence.html).
11  *
12  *  Ian Roberts, 04/Apr/2007
13  *
14  *  $Id: GateAwareObjectInputStream.java 15333 2012-02-07 13:18:33Z ian_roberts $
15  */
16 
17 package gate.persist;
18 
19 import java.io.*;
20 import java.lang.reflect.Proxy;
21 
22 import gate.Gate;
23 
24 /**
25  * An ObjectInputStream that attempts to resolve the classes of objects
26  * loaded from the stream via the GateClassLoader if they cannot be
27  * found by the usual means. This allows LRs to be loaded successfully
28  * from a serial datastore when they have features (or annotations with
29  * features) whose class is defined in a plugin.
30  */
31 public class GateAwareObjectInputStream extends ObjectInputStream {
32   /**
33    * Creates a GATE aware object input stream to read from the given
34    * source.
35    */
36   public GateAwareObjectInputStream(InputStream sourcethrows IOException {
37     super(source);
38   }
39 
40   /**
41    * Resolve the class of an object read from the stream. First attempts
42    * to use the default resolution method provided by ObjectInputStream.
43    * If that fails with a ClassNotFoundException then tries to resolve
44    * the class via the GATE classloader instead.
45    */
46   @Override
47   protected Class<?> resolveClass(ObjectStreamClass descthrows IOException,
48           ClassNotFoundException {
49     try {
50       return super.resolveClass(desc);
51     }
52     catch(ClassNotFoundException cnfe) {
53       // try the GATE classloader instead
54       return Class.forName(desc.getName(), false, Gate.getClassLoader());
55     }
56   }
57 
58   /**
59    * Resolve a proxy class that implements the given interfaces. First
60    * attempts to use the default resolution method provided by
61    * ObjectInputStream. If that fails with a ClassNotFoundException then
62    * tries to resolve the interfaces and create the proxy class using
63    * the GATE classloader instead.
64    */
65   @Override
66   protected Class<?> resolveProxyClass(String[] interfacesthrows IOException,
67           ClassNotFoundException {
68     try {
69       return super.resolveProxyClass(interfaces);
70     }
71     catch(ClassNotFoundException cnfe) {
72       // failed to load with the normal method, try the GATE ClassLoader
73       // instead
74       Class<?>[] interfaceClasses = new Class<?>[interfaces.length];
75       for(int i = 0; i < interfaces.length; i++) {
76         interfaceClasses[i= Class.forName(interfaces[i], false, Gate
77                 .getClassLoader());
78       }
79       return Proxy.getProxyClass(Gate.getClassLoader(), interfaceClasses);
80     }
81   }
82 }