如何使Java不调用外部库

如何使Java不调用外部库,java,architecture,Java,Architecture,我有一个Java大型系统,它基本上由用户界面、应用程序的“核心引擎”和许多其他模块组成。 我正在尝试创建一个小程序,它将只包含“核心引擎”,而不包含其他部分,因此我需要共享相同的代码库以跟上更新。 我已经完成了这项工作,效果很好,问题是在我不需要的其他部分中使用了很多外部jar,而applet目前需要它们 我不调用需要外部jar的代码部分,当我调用一个类的构造函数时,堆栈跟踪会给我一个错误,因此我猜测,在加载这个类(我正在使用构造函数)时,它就需要jar。但我在互联网上读到,Java只在需要时加

我有一个Java大型系统,它基本上由用户界面、应用程序的“核心引擎”和许多其他模块组成。 我正在尝试创建一个小程序,它将只包含“核心引擎”,而不包含其他部分,因此我需要共享相同的代码库以跟上更新。 我已经完成了这项工作,效果很好,问题是在我不需要的其他部分中使用了很多外部jar,而applet目前需要它们

我不调用需要外部jar的代码部分,当我调用一个类的构造函数时,堆栈跟踪会给我一个错误,因此我猜测,在加载这个类(我正在使用构造函数)时,它就需要jar。但我在互联网上读到,Java只在需要时加载类,所以我不确定这里发生了什么。有谁能给我一些建议,我怎样才能不需要这些罐子呢

PS:我相信最好的方法是重构它,将功能划分为清晰的层,这样我就可以更容易地解决这个问题。问题是,这是一个非常古老和庞大的代码库,现在进行这种大规模重构(尽管我愿意)是不可行的

编辑-添加一个堆栈跟踪和更多信息:

java.io.FileNotFoundException: http://localhost:3000/applet/jess.jar
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at com.sun.deploy.net.DownloadEngine.getJarFileWithoutCache(Unknown Source)
    at com.sun.deploy.net.DownloadEngine.downloadJarFileWithoutCache(Unknown Source)
    at sun.plugin.PluginURLJarFileCallBack$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.PluginURLJarFileCallBack.retrieve(Unknown Source)
    at sun.net.www.protocol.jar.URLJarFile.retrieve(Unknown Source)
    at sun.net.www.protocol.jar.URLJarFile.getJarFile(Unknown Source)
    at sun.net.www.protocol.jar.JarFileFactory.get(Unknown Source)
    at sun.net.www.protocol.jar.JarURLConnection.connect(Unknown Source)
    at sun.plugin.net.protocol.jar.CachedJarURLConnection.connect(Unknown Source)
    at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFileInternal(Unknown Source)
    at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFile(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.getJarFile(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.access$1000(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.ensureOpen(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.<init>(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
    at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at my.package.MyClass.<init>(MyClass.java:187)
    at my.package.MyApplet.start(MyApplet.java:38)
    at com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.start(Unknown Source)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

但是这个方法永远不会让VM尝试获取包含jar的jar?(据我所知,答案似乎是“否”。

原因是
MyClass2
less.jar
中使用了一些东西,因此导致了错误。

注意这行

at my.package.MyClass.<init>(MyClass.java:187)
在my.package.MyClass.(MyClass.java:187)
这意味着正在初始化类型为
MyClass
的对象。我打赌第187行是一个内联构造函数调用,是构造函数体中的一行,或者是一个默认字段值初始化


初始化最终尝试在
jess.jar
中加载某些内容,这就是导致错误的原因。

根据注释,发生的情况是,只有在尝试加载
MyClass2
时,JVM才在搜索类路径时尝试访问
less.jar
。我的猜测是,只有在第一次需要类时才加载它们,因此,
.jar
s/只有在前面的类中找不到类时才第一次访问其他类路径条目

解释您看到的行为的一种方法是,类路径按以下顺序包含这些
.jar
s:

  • a.jar
    (本地)
  • less.jar
    (远程)
  • b.jar
    (本地)

  • 其中
    MyClass
    位于
    a.jar
    中;而
    MyClass2
    b.jar
    中。类加载器尝试加载
    MyClass
    ,打开
    a.jar
    ,在那里找到并加载它,然后开始运行构造函数。构造函数需要
    MyClass2
    ,因此类加载器打开
    a.jar
    ,在那里找不到类,并转到下一个类路径条目。这是
    less.jar
    ,它是不可访问的,您会遇到崩溃。当您从类路径中删除不可访问的
    .jar
    时,类加载器可以移动到
    b.jar
    并在那里找到
    MyClass2

    如果您得到ClassNotFoundExceptions,显然是因为您确实在使用有问题的类。如果您认为不需要它们,那么为什么要对它们进行代码实例化?我想不看代码,只有你能回答这个问题。如果没有更多的细节和堆栈跟踪,任何人都无法提供帮助。这实际上是一个FileNotFoundException(如果我把文件放在那里,一切都正常,但我不需要这些文件,这就是问题所在)。添加了一个堆栈跟踪示例。提示位于my.package.MyClass.(MyClass.java:187)。转到
    MyClass.java
    line
    187
    ,你会发现它盯着你的脸。你真的需要那一行吗,试着注释它,看看会发生什么。有没有代码显式地尝试加载
    jess.jar
    ?因为这看起来更像是这个
    .jar
    的URL位于应用程序的类路径上,Java最终会在查找任何尚未加载的类时访问它。也许你只需要从类路径中删除这个URL,这很有意义。这就是为什么我同时得到所有FileNotFoundException。谢谢:)
    at my.package.MyClass.<init>(MyClass.java:187)