0

私はJavaで大規模なシステムを持っています。これは基本的に、ユーザーインターフェイス、アプリケーションの「コアエンジン」、および他の多くのモジュールで構成されています。「コア エンジン」のみで構成され、他の部分を含まないアプレットを作成しようとしています。そのため、更新に対応するために同じコードベースを共有する必要があります。私はこれを実行しましたが、うまく機能します。問題は、他の部分で使用されている必要のない外部 jar がたくさんあり、現在、アプレットはそれらすべてを必要としていることです。

外部 jar を必要とするコードの部分を呼び出さず、クラスのコンストラクターを呼び出しているときにスタック トレースでエラーが発生するため、このクラスの直後に jar が必要になると推測しています (コンストラクターを使用していること) が読み込まれます。しかし、Java は必要な場合にのみクラスをロードすることをインターネットで読んだので、ここで何が起こっているのかわかりません。これらの瓶を必要としないようにするにはどうすればよいか、誰かアドバイスをいただけますか?

PS: 最善のアプローチは、機能を明確なレイヤーに分離してリファクタリングすることであると確信しているため、これにより簡単に取り組むことができます。問題は、これが非常に古くて大きなコードベースであり、この種の大量リファクタリングを (私はしたいのですが) 実行できないことです。

編集 - スタック トレースの 1 つと詳細情報を追加します。

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)

MyClass の 187 行目は次のとおりです。 MyClass2 obj = new MyClass2();

他のすべての FileNotFoundException トレースは同じですが、他のファイルがありません。また、このシステムでは、複数のリリース (たとえば、アカデミック バージョンと商用バージョン) があり、必要な多くの jar はアカデミック バージョンにはありませんが、同じコードを使用して他のバージョンをコンパイルすることができます。これらの瓶を必要とすることに問題があります。

助けを与えるのが難しい状況であることは知っていますが、誰かが同じような状況にあり、ヒントをくれるかもしれないと思いました.

また、次のような方法があるという可能性はありますか:

public void myMethod() {
 ClassInOneOfTheJars c = new ClassInOneOfTheJars();
}

しかし、この方法では、VM が ClassInOneOfTheJars を含む jar を取得しようとすることはあり得ませんか? (私が読んだ限りでは、答えは「いいえ」のようです)。

4

3 に答える 3

1

コメントに基づいて、何が起こったのかというと、ロードしようとしたときだけ、クラスパスを検索するときにMyClass2JVMがアクセスしようとしました。less.jar私の推測では、クラスが最初に必要になったときにのみロードされる方法と.jar同様に、クラスが以前のクラスで見つからない場合にのみ s / 他のクラスパス エントリが最初にアクセスされます。

表示される動作を説明する 1 つの方法は、クラスパスにこれら.jarの が次の順序で含まれていることです。

  1. a.jar(ローカル)
  2. less.jar(リモート)
  3. b.jar(ローカル)

どこMyClassにあるa.jar; とMyClass2ありb.jarます。クラスローダは をロードしようとしMyClass、 を開きa.jar、そこで見つけてロードし、コンストラクタの実行を開始します。コンストラクターは を必要MyClass2とするため、クラスローダーは を開きa.jar、そこにクラスが見つからず、次のクラスパス エントリに移動します。これはless.jarであり、アクセスできず、クラッシュします。.jarクラスパスからアクセスできないものを削除すると、クラスローダーはそこに移動してそこb.jarを見つけることができMyClass2ます。

于 2012-08-01T11:04:57.140 に答える
0

その理由は、でMyClass2何かを使用しているためless.jar、エラーが発生します。

于 2012-08-01T01:51:26.110 に答える
0

行に注意してください

at my.package.MyClass.<init>(MyClass.java:187)

これは、型のオブジェクトMyClassが初期化されていることを意味します。行 187 は、インライン コンストラクター呼び出し、コンストラクター本体内の行、またはデフォルトのフィールド値の初期化であるに違いありません。

初期化は最終的に に何かをロードしようとしjess.jarています。それがエラーの原因です。

于 2012-08-01T02:13:45.600 に答える