英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论