View Javadoc
1   package org.pojomatic.internal;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.io.InputStream;
6   import java.security.cert.Certificate;
7   import java.security.CodeSource;
8   import java.security.ProtectionDomain;
9   
10  import com.google.common.base.Preconditions;
11  import com.google.common.io.ByteStreams;
12  
13  /**
14   * A {@link ClassLoader} which loads classes, but will not expose their byte code.
15   */
16  class ClassOnlyClassLoader extends ClassLoader {
17    private final ClassLoader source;
18  
19    public ClassOnlyClassLoader(ClassLoader source) {
20      super(null);
21      this.source = Preconditions.checkNotNull(source);
22    }
23  
24    @Override
25    protected Class<?> findClass(String name) throws ClassNotFoundException {
26      if (name.startsWith("org.pojomatic.annotations")) {
27        return getClass().getClassLoader().loadClass(name);
28      }
29      try (InputStream classBytesStream = source.getResourceAsStream(name.replace('.', '/') + ".class")) {
30        if (classBytesStream == null) {
31          throw new ClassNotFoundException(name);
32        }
33        byte[] bytes = ByteStreams.toByteArray(classBytesStream);
34        ProtectionDomain protectionDomain =
35            new ProtectionDomain(new CodeSource(new File("/no/such/file").toURI().toURL(), new Certificate[0]), null);
36        return defineClass(name, bytes, 0, bytes.length, protectionDomain);
37      } catch (IOException e) {
38        throw new ClassNotFoundException(name, e);
39      }
40    }
41  }