优化ClassFilter
This commit is contained in:
@@ -1317,7 +1317,7 @@ public final class Application {
|
||||
try {
|
||||
if (!inited.getAndSet(true)) { //加载自定义的协议,如:SOCKS
|
||||
ClassFilter profilter = new ClassFilter(classLoader, NodeProtocol.class, NodeServer.class, (Class[]) null);
|
||||
ClassFilter.Loader.load(home, classLoader, profilter);
|
||||
loadClassByFilters(profilter);
|
||||
final Set<FilterEntry<NodeServer>> entrys = profilter.getFilterEntrys();
|
||||
for (FilterEntry<NodeServer> entry : entrys) {
|
||||
final Class<? extends NodeServer> type = entry.getType();
|
||||
@@ -1408,14 +1408,18 @@ public final class Application {
|
||||
});
|
||||
}
|
||||
|
||||
void loadClassesByFilters(final ClassFilter... filters) throws IOException {
|
||||
ClassFilter.Loader.load(getHome(), this.serverClassLoader, filters);
|
||||
}
|
||||
|
||||
List<ModuleEngine> getModuleEngines() {
|
||||
return moduleEngines;
|
||||
}
|
||||
|
||||
public void loadClassByFilters(final ClassFilter... filters) throws IOException {
|
||||
ClassFilter.Loader.load(getHome(), getClassLoader(), filters);
|
||||
}
|
||||
|
||||
public void loadServerClassFilters(final ClassFilter... filters) throws IOException {
|
||||
ClassFilter.Loader.load(getHome(), getServerClassLoader(), filters);
|
||||
}
|
||||
|
||||
public DataSource loadDataSource(final String sourceName, boolean autoMemory) {
|
||||
return sourceModule.loadDataSource(sourceName, autoMemory);
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ public final class ClassFilter<T> {
|
||||
* @param url URL
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void filter(AnyValue property, String clazzName, URL url) {
|
||||
public final void filter(AnyValue property, String clazzName, URI url) {
|
||||
filter(property, clazzName, true, url);
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ public final class ClassFilter<T> {
|
||||
* @param autoScan 为true表示自动扫描的, false表示显著调用filter, AutoLoad的注解将被忽略
|
||||
* @param url URL
|
||||
*/
|
||||
public final void filter(AnyValue property, String clazzName, boolean autoScan, URL url) {
|
||||
public final void filter(AnyValue property, String clazzName, boolean autoScan, URI url) {
|
||||
boolean r = accept0(property, clazzName);
|
||||
ClassFilter cf = r ? this : null;
|
||||
if (r && ands != null) {
|
||||
@@ -242,8 +242,10 @@ public final class ClassFilter<T> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
//&& (!(cfe instanceof NoClassDefFoundError) || (cfe instanceof UnsupportedClassVersionError) || ((NoClassDefFoundError) cfe).getMessage().startsWith("java.lang.NoClassDefFoundError: java"))) {
|
||||
logger.log(Level.FINEST, ClassFilter.class.getSimpleName() + " filter error for class: " + clazzName + (url == null ? "" : (" in " + url)), cfe);
|
||||
//&& (!(cfe instanceof NoClassDefFoundError) || (cfe instanceof UnsupportedClassVersionError)
|
||||
//|| ((NoClassDefFoundError) cfe).getMessage().startsWith("java.lang.NoClassDefFoundError: java"))) {
|
||||
logger.log(Level.FINEST, ClassFilter.class.getSimpleName()
|
||||
+ " filter error for class: " + clazzName + (url == null ? "" : (" in " + url)), cfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -559,7 +561,11 @@ public final class ClassFilter<T> {
|
||||
|
||||
protected static final Logger logger = Logger.getLogger(Loader.class.getName());
|
||||
|
||||
protected static final ConcurrentMap<URL, Set<String>> cache = new ConcurrentHashMap<>();
|
||||
protected static final ConcurrentMap<URI, Set<String>> cache = new ConcurrentHashMap<>();
|
||||
|
||||
private Loader() {
|
||||
//do nothng
|
||||
}
|
||||
|
||||
public static void close() {
|
||||
cache.clear();
|
||||
@@ -575,11 +581,11 @@ public final class ClassFilter<T> {
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
public static void load(final File excludeFile, RedkaleClassLoader loader, final ClassFilter... filters) throws IOException {
|
||||
List<URL> urlFiles = new ArrayList<>(2);
|
||||
List<URL> urlJares = new ArrayList<>(2);
|
||||
final URL exurl = excludeFile != null ? excludeFile.toURI().toURL() : null;
|
||||
for (URL url : loader.getAllURLs()) {
|
||||
if (exurl != null && exurl.sameFile(url)) {
|
||||
List<URI> urlFiles = new ArrayList<>(2);
|
||||
List<URI> urlJares = new ArrayList<>(2);
|
||||
final URI exurl = excludeFile != null ? excludeFile.toURI() : null;
|
||||
for (URI url : loader.getAllURIs()) {
|
||||
if (exurl != null && exurl.equals(url)) {
|
||||
continue;
|
||||
}
|
||||
if (url.getPath().endsWith(".jar")) {
|
||||
@@ -591,11 +597,11 @@ public final class ClassFilter<T> {
|
||||
List<File> files = new ArrayList<>();
|
||||
boolean debug = logger.isLoggable(Level.FINEST);
|
||||
StringBuilder debugstr = new StringBuilder();
|
||||
for (final URL url : urlJares) {
|
||||
for (final URI url : urlJares) {
|
||||
Set<String> classes = cache.get(url);
|
||||
if (classes == null) {
|
||||
classes = new LinkedHashSet<>();
|
||||
try (JarFile jar = new JarFile(URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8))) {
|
||||
try (JarFile jar = new JarFile(URLDecoder.decode(url.toURL().getFile(), StandardCharsets.UTF_8))) {
|
||||
Enumeration<JarEntry> it = jar.entries();
|
||||
while (it.hasMoreElements()) {
|
||||
String entryName = it.nextElement().getName().replace('/', '.');
|
||||
@@ -632,6 +638,18 @@ public final class ClassFilter<T> {
|
||||
if (className.startsWith("org.apache.")) {
|
||||
break;
|
||||
}
|
||||
if (className.startsWith("org.redisson.")) {
|
||||
break;
|
||||
}
|
||||
if (className.startsWith("com.fasterxml.")) {
|
||||
break;
|
||||
}
|
||||
if (className.startsWith("org.yaml.")) {
|
||||
break;
|
||||
}
|
||||
if (className.startsWith("reactor.")) {
|
||||
break;
|
||||
}
|
||||
if (className.startsWith("io.netty.")) {
|
||||
break;
|
||||
}
|
||||
@@ -661,17 +679,17 @@ public final class ClassFilter<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final URL url : urlFiles) {
|
||||
for (final URI url : urlFiles) {
|
||||
Set<String> classes = cache.get(url);
|
||||
if (classes == null) {
|
||||
classes = new LinkedHashSet<>();
|
||||
final Set<String> cs = classes;
|
||||
if (url == RedkaleClassLoader.URL_NONE) {
|
||||
if (url == RedkaleClassLoader.URI_NONE) {
|
||||
loader.forEachCacheClass(v -> cs.add(v));
|
||||
}
|
||||
if (cs.isEmpty()) {
|
||||
files.clear();
|
||||
File root = new File(url.getFile());
|
||||
File root = new File(url.toURL().getFile());
|
||||
String rootPath = root.getPath();
|
||||
loadClassFiles(excludeFile, root, files);
|
||||
for (File f : files) {
|
||||
|
||||
@@ -226,7 +226,7 @@ public abstract class NodeServer {
|
||||
filters.addAll(otherFilters);
|
||||
}
|
||||
long s = System.currentTimeMillis();
|
||||
application.loadClassesByFilters(filters.toArray(new ClassFilter[filters.size()]));
|
||||
application.loadClassByFilters(filters.toArray(new ClassFilter[filters.size()]));
|
||||
long e = System.currentTimeMillis() - s;
|
||||
logger.info(this.getClass().getSimpleName() + " load filter class in " + e + " ms");
|
||||
loadService(serviceFilter); //必须在servlet之前
|
||||
|
||||
@@ -42,7 +42,7 @@ public class PrepareCompiler {
|
||||
final ClassFilter<?> beanFilter2 = new ClassFilter(application.getClassLoader(), org.redkale.util.Bean.class, Object.class, (Class[]) null);
|
||||
final ClassFilter<?> filterFilter = new ClassFilter(application.getClassLoader(), null, FilterBean.class, (Class[]) null);
|
||||
|
||||
ClassFilter.Loader.load(application.getHome(), application.getClassLoader(), entityFilter, beanFilter, filterFilter);
|
||||
application.loadClassByFilters(entityFilter, beanFilter, filterFilter);
|
||||
|
||||
for (FilterEntry en : entityFilter.getFilterEntrys()) {
|
||||
Class clz = en.getType();
|
||||
|
||||
@@ -401,7 +401,7 @@ public class MessageModuleEngine extends ModuleEngine {
|
||||
}
|
||||
|
||||
try {
|
||||
ClassFilter.Loader.load(application.getHome(), application.getServerClassLoader(), filter);
|
||||
application.loadServerClassFilters(filter);
|
||||
List<ClassFilter.FilterEntry<? extends MessageConsumer>> entrys = new ArrayList(filter.getFilterEntrys());
|
||||
for (ClassFilter.FilterEntry<? extends MessageConsumer> en : entrys) {
|
||||
Class<? extends MessageConsumer> clazz = en.getType();
|
||||
|
||||
@@ -27,17 +27,7 @@ public class RedkaleClassLoader extends URLClassLoader {
|
||||
|
||||
public static final String RESOURCE_CACHE_CONF_PATH = "/META-INF/redkale/conf";
|
||||
|
||||
public static final URL URL_NONE;
|
||||
|
||||
static {
|
||||
URL url = null;
|
||||
try {
|
||||
url = URI.create("file://redkale/uri").toURL(); //不能是jar结尾,否则会视为jar文件url
|
||||
} catch (MalformedURLException e) {
|
||||
//do nothing
|
||||
}
|
||||
URL_NONE = url;
|
||||
}
|
||||
public static final URI URI_NONE = URI.create("file://redkale/uri"); //不能是jar结尾,否则会视为jar文件url
|
||||
|
||||
private static final String[] buildClasses = {};
|
||||
|
||||
@@ -487,60 +477,64 @@ public class RedkaleClassLoader extends URLClassLoader {
|
||||
return super.getURLs();
|
||||
}
|
||||
|
||||
public URL[] getAllURLs() {
|
||||
public URI[] getAllURIs() {
|
||||
ClassLoader loader = this;
|
||||
HashSet<URL> set = new HashSet<>();
|
||||
HashSet<URI> set = new HashSet<>();
|
||||
String appPath = System.getProperty("java.class.path");
|
||||
if (appPath != null && !appPath.isEmpty()) {
|
||||
for (String path : appPath.replace("://", "&&").replace(":\\", "##").replace(':', ';').split(";")) {
|
||||
try {
|
||||
set.add(Paths.get(path.replace("&&", "://").replace("##", ":\\")).toRealPath().toFile().toURI().toURL());
|
||||
set.add(Paths.get(path.replace("&&", "://").replace("##", ":\\")).toRealPath().toFile().toURI());
|
||||
} catch (Exception e) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
do {
|
||||
String loaderName = loader.getClass().getName();
|
||||
if (loaderName.startsWith("sun.") && loaderName.contains("ExtClassLoader")) {
|
||||
continue;
|
||||
}
|
||||
if (loader instanceof URLClassLoader) {
|
||||
for (URL url : ((URLClassLoader) loader).getURLs()) {
|
||||
set.add(url);
|
||||
try {
|
||||
do {
|
||||
String loaderName = loader.getClass().getName();
|
||||
if (loaderName.startsWith("sun.") && loaderName.contains("ExtClassLoader")) {
|
||||
continue;
|
||||
}
|
||||
} else { //可能JDK9及以上
|
||||
loader.getResource("org.redkale"); //必须要运行一次,确保URLClassPath的值被填充完毕
|
||||
Class loaderClazz = loader.getClass();
|
||||
Object ucp = null;
|
||||
do { //读取 java.base/jdk.internal.loader.BuiltinClassLoader的URLClassPath ucp值
|
||||
try {
|
||||
//需要在命令行里加入: --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
|
||||
Field field = loaderClazz.getDeclaredField("ucp");
|
||||
field.setAccessible(true);
|
||||
ucp = field.get(loader);
|
||||
break;
|
||||
} catch (Throwable e) {
|
||||
//do nothing
|
||||
if (loader instanceof URLClassLoader) {
|
||||
for (URL url : ((URLClassLoader) loader).getURLs()) {
|
||||
set.add(url.toURI());
|
||||
}
|
||||
} while ((loaderClazz = loaderClazz.getSuperclass()) != Object.class);
|
||||
if (ucp != null) { //URLClassPath
|
||||
URL[] urls = null;
|
||||
try { //读取 java.base/jdk.internal.loader.URLClassPath的urls值
|
||||
Method method = ucp.getClass().getMethod("getURLs");
|
||||
urls = (URL[]) method.invoke(ucp);
|
||||
} catch (Exception e) {
|
||||
//do nothing
|
||||
}
|
||||
if (urls != null) {
|
||||
for (URL url : urls) {
|
||||
set.add(url);
|
||||
} else { //可能JDK9及以上
|
||||
loader.getResource("org.redkale"); //必须要运行一次,确保URLClassPath的值被填充完毕
|
||||
Class loaderClazz = loader.getClass();
|
||||
Object ucp = null;
|
||||
do { //读取 java.base/jdk.internal.loader.BuiltinClassLoader的URLClassPath ucp值
|
||||
try {
|
||||
//需要在命令行里加入: --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
|
||||
Field field = loaderClazz.getDeclaredField("ucp");
|
||||
field.setAccessible(true);
|
||||
ucp = field.get(loader);
|
||||
break;
|
||||
} catch (Throwable e) {
|
||||
//do nothing
|
||||
}
|
||||
} while ((loaderClazz = loaderClazz.getSuperclass()) != Object.class);
|
||||
if (ucp != null) { //URLClassPath
|
||||
URL[] urls = null;
|
||||
try { //读取 java.base/jdk.internal.loader.URLClassPath的urls值
|
||||
Method method = ucp.getClass().getMethod("getURLs");
|
||||
urls = (URL[]) method.invoke(ucp);
|
||||
} catch (Exception e) {
|
||||
//do nothing
|
||||
}
|
||||
if (urls != null) {
|
||||
for (URL url : urls) {
|
||||
set.add(url.toURI());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((loader = loader.getParent()) != null);
|
||||
return set.toArray(new URL[set.size()]);
|
||||
} while ((loader = loader.getParent()) != null);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RedkaleException(e);
|
||||
}
|
||||
return set.toArray(new URI[set.size()]);
|
||||
}
|
||||
|
||||
public static class RedkaleCacheClassLoader extends RedkaleClassLoader {
|
||||
@@ -553,8 +547,8 @@ public class RedkaleClassLoader extends URLClassLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL[] getAllURLs() {
|
||||
return new URL[]{URL_NONE};
|
||||
public URI[] getAllURIs() {
|
||||
return new URI[]{URI_NONE};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user