/* * Copyright 2011-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kr.debop4j.core.reflect; import com.google.common.collect.Lists; import kr.debop4j.core.Guard; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Method; import java.util.List; /** * AccessClassLoader * * @author 배성혁 ( sunghyouk.bae@gmail.com ) * @since 13. 1. 21 */ @Slf4j class AccessClassLoader extends ClassLoader { private static final List<AccessClassLoader> accessClassLoaders = Lists.newArrayList(); /** AccessClassLoger를 생성합니다. */ static AccessClassLoader get(Class type) { if (log.isDebugEnabled()) log.debug("AccessClassLoader를 생성합니다. type=[{}]", type); ClassLoader parent = type.getClassLoader(); // com.google.common.collect.Iterables 를 사용하여 변경해 보세요. synchronized (accessClassLoaders) { for (AccessClassLoader loader : accessClassLoaders) { if (loader.getParent() == parent) return loader; } AccessClassLoader loader = new AccessClassLoader(parent); accessClassLoaders.add(loader); return loader; } } private AccessClassLoader(ClassLoader parent) { super(parent); } protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { Guard.shouldNotBeEmpty(name, "name"); if (name.equals(FieldAccess.class.getName())) return FieldAccess.class; if (name.equals(MethodAccess.class.getName())) return MethodAccess.class; if (name.equals(ConstructorAccess.class.getName())) return ConstructorAccess.class; // all other classes come from the ClassLoader return super.loadClass(name, resolve); } Class<?> defineClass(String name, byte[] bytes) throws ClassFormatError { Guard.shouldNotBeEmpty(name, "name"); Guard.shouldNotBeNull(bytes, "bytes"); try { Method method = ClassLoader.class .getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class}); method.setAccessible(true); // NOTE: 꼭 Integer.valueOf() 를 써야 합니다. // return (Class) method.invoke(getParent(), name, bytes, Integer.valueOf(0), Integer.valueOf(bytes.length)); } catch (Exception ignored) { } return defineClass(name, bytes, 0, bytes.length); } }