如何识别内部包?

huangapple go评论91阅读模式
英文:

Kotlin/Java - How to identify internal packages?

问题

TL;DR:

内部包:Java程序可以在不导入外部JAR或显式指定额外类路径的情况下使用的包,例如 java.lang.Exception

我需要此函数的实现:

/**
 * @param package Package name (例如,"java.lang.Exception")
 * @return 如果此包是内部包,则为true。
 */
fun isInternal(package: String): Boolean
{
    // 在这里最有效的实现是什么?
}

Example Cases:

isInternal("java.lang.Exception") // true
isInternal("org.hydev.Test") // false
isInternal("com.sun.net.httpserver") // true
isInternal("sun.misc.BASE64Encoder") // true
isInternal("javax.xml.ws") // true
// 但必须还有更多不以java.或com.sun.或sun.开头的内部包。

Long story:

我正在构建HyLogger,这是一个专注于颜色编码的记录器库,以下是我遇到的问题:

如何识别内部包?

当调用Throwable.printStackTrace()时,堆栈跟踪中第一个不是来自我的记录器库的条目将是java.lang.Throwable$WrappedPrintStream.println:749。因此,在搜索堆栈跟踪以找到用于FQCN的最有用的条目时,需要过滤掉内部包。一个简单的解决方案是过滤掉以java.sun.com.sun.开头的条目,但一定会有比这三个更多的内部包前缀,这就是我提出这个问题的原因。

英文:

TL;DR:

Internal package: Packages that Java programs can use without importing external jars or explicitly specifying extra classpaths, like java.lang.Exception.

I need an implementation of this function:

/**
 * @param package Package name (Eg. "java.lang.Exception")
 * @return True if this package is an internal package.
 */
fun isInternal(package: String): Boolean
{
    // What is the most efficient implementation here?
}

Example Cases:

isInternal("java.lang.Exception") // true
isInternal("org.hydev.Test") // false
isInternal("com.sun.net.httpserver") // true
isInternal("sun.misc.BASE64Encoder") // true
isInternal("javax.xml.ws") // true
// But there must be more internal packages that don't start with java. or com.sun. or sun.

Long story:

I'm building HyLogger, a logger library focused on color-coding, and here is the problem I ran to:

如何识别内部包?

When Throwable.printStackTrace() is called, the first entry in the stack trace that's not from my logger library would be java.lang.Throwable$WrappedPrintStream.println:749. Therefore, when searching through the stack trace to find the most useful entry for FQCN, internal packages need to be filtered. An easy solution is to filter out entries that start with java., sun., or com.sun., but there must be more internal packages prefixes than those three, which is why I asked this question.

答案1

得分: 2

你的定义中的“内部类”似乎对应于由JVM的引导类加载器加载的类。

从Java 9开始,StackTraceElement类有一个名为getClassLoaderName()的方法(javadoc)。这将返回一个String,或者如果类加载器没有名称则返回null。引导类加载器应该没有名称...或者(可能)有一个可以区分的名称。

或者,您可以在类上调用Class.forName,然后在Class对象上调用getClassLoader()。如果该类由引导类加载器加载,该调用将返回null

即使你对“内部类”的定义不完全等同于“由引导类加载器加载”,它可能仍然与类的类加载器相关。上述方法应该仍然适用...只需要进行一些调整。

英文:

It seems to me that your definition of an "internal class" corresponds to a class that is loaded by the JVM's bootstrap classloader.

From Java 9 onwards, the StackTraceElement class has a method called getClassLoaderName() (javadoc). This returns a String, or null if the classloader has no name. The bootstrap classloader should have no name ... or (possibly) a name that you can distinguish.

Alternatively, you could call Class.forName on the class, and then call getClassLoader() on the Class object. If the class was loaded by the bootclassloader, that call will return null.


Even if your definition of an "internal class" doesn't exactly mean "loaded by the bootstrap classloader", it probably does relate to the classes classloader. The above approach should still work ... with some tweaks.

huangapple
  • 本文由 发表于 2020年8月1日 05:26:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/63199276.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定