Java 从JAR文件导入安全类
考虑一个java程序从jar文件导入类的场景。如果同一个类驻留在两个或多个jar文件中,则可能会出现问题Java 从JAR文件导入安全类,java,class,import,jar,class-library,Java,Class,Import,Jar,Class Library,考虑一个java程序从jar文件导入类的场景。如果同一个类驻留在两个或多个jar文件中,则可能会出现问题 在这种情况下,程序导入的类是什么?是上课吗 使用较旧的时间戳 我们可以遵循哪些实践来避免此类复杂情况 编辑:这是一个例子。我有两个jar文件my1.jar和my2.jar。这两个文件都包含com.mycompany.CrazyWriter默认情况下,类由使用按顺序搜索的类路径加载 如果同一个类有两个实现,则将加载类装入器首先找到的实现 如果这些类实际上不是同一个类(相同的名称但不同的方法),
编辑:这是一个例子。我有两个jar文件my1.jar和my2.jar。这两个文件都包含com.mycompany.CrazyWriter默认情况下,类由使用按顺序搜索的类路径加载 如果同一个类有两个实现,则将加载类装入器首先找到的实现 如果这些类实际上不是同一个类(相同的名称但不同的方法),那么在尝试使用它时会出现异常
通过使用多个类加载器,可以在单个VM中加载两个名称相同的类。该框架可以为您管理大量的复杂性,确保加载了正确的版本,等等。首先,我假设您的意思是同一个类驻留在另外两个jar文件中 现在,回答您的问题:
-bootclasspath
编辑:针对此答案的其中一条评论。我最初认为这会有所不同,因为理论上它不应该从不同的jar文件加载同一个包中的两个类。但是,经过一些实验后,我发现这个假设并不成立,至少在默认的安全提供程序中是如此。类加载器负责加载类。 它扫描类路径并加载它首先找到的类。 如果在类路径上有两次相同的Jar,或者如果有两个Jar包含同一类的两个不同版本(即com.packagename.Classname),则会加载第一个找到的Jar 尽量避免在类路径上使用同一个jar两次
如果您的意思是在另外两个罐子中,正如已经回答的那样,那么将使用类路径中的顺序
一个包应该只在一个JAR中,以避免重复的类。如果两个类具有相同的简单名称,如
java.util.Date
和java.sql.Date
,但它们位于不同的包中,那么它们实际上是不同的类。您必须使用完全限定名(至少与其中一个类不同)来区分它们如果您在确定正在使用的类的哪个版本时遇到问题,那么jwhich可能有用:
如果同一个类驻留在另外两个jar中,则应该存在问题 你到底是什么意思?为什么这应该是个问题 在这种情况下,程序导入的类是什么?(具有较旧时间戳的类??) 如果一个类存在于两个JAR中,那么该类将从找到它的类路径上的第一个JAR加载。引用(引用部分也适用于存档文件): 指定多个类路径项的顺序很重要。Java解释器将按照类路径变量中出现的顺序在目录中查找类。在上面的示例中,Java解释器将首先在目录
C:\Java\MyClasses
中查找所需的类。只有在该目录中找不到具有正确名称的类时,解释器才会在C:\java\OtherClasses
目录中查找
换句话说,如果需要特定的顺序,那么只需在类路径中显式地枚举JAR文件。这是应用服务器供应商常用的一种方法:要修补产品的特定类,您可以在主JAR(比如weblogic.JAR
)之前的类路径上放置一个包含修补类的JAR(例如CR1234.JAR
)
我们可以遵循哪些实践来避免此类复杂情况
很明显,答案是不要这样做(或者像上面给出的示例那样只是故意的)。同一个类驻留在另外两个类中-你能澄清一下吗?“如果同一个类驻留在另外两个类中”?您的意思是“如果同一个类驻留在两个以上的罐子中”吗?根据编辑,更新了问题以澄清第一句话。1。那么默认的类加载器(这就是问题所在)呢?2.在多个jar中放置同一类的不同版本有一些有效的用例(例如,修补一个类)。@Pascal您可能认为这是一个有效的用例,但替换原来的jar要好得多,因为一般来说您需要重新启动。答案是,如上所述,类加载器将使用它首先找到的任何类。一般来说,这将来自类路径上的第一个jar文件。@Paul BEA不会给您提供新的weblogic.jar,因此不,替换原始jar并不更好(问题不是是否重新启动)。我使用过的所有JVM都会选择找到的第一个类。@Pascal我已经更新了答案,因为我认为密封罐子会有影响,但事实并非如此。我仍然不认为在多个jar文件中拆分同一个包是一个好主意,但我承认有时它可能有用,即使它会否定您与供应商签订的任何支持合同;-)关于编辑:当JVM试图从具有不同凭据的JAR加载同一包中的不同类时,会抛出异常。在不同的地方有相同的班级