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