0

Google App Engine (GAE) のサーブレットで Java Google Drive API を使用しようとしていますが、サーブレットが Eclipse の (localhost) サーバーに最初にロードされるときにNoClassDefFoundErrorを取得します。

テストとして、サーブレットで GoogleClientSecrets クラスのインスタンスを作成しようとしました。Eclipse コンパイラは文句を言いません。Java ビルド パス google-api-client-1.16.0- に C:\app\gDrive\libs**google-api-client-1.16.0-rc.jar** があります。 rc.jar には、 GoogleClientSecrets を含むパッケージcom.google.api.client.googleapis.auth.oauth2が含まれています

Eclipse の Google プラグインの (localhost) サーバーは通常どおりロードされます。サーブレット クラスが最初にロードされるとき (サーブレット クラスへの最初の要求が行われるとき)、NoClassDefFoundError が発生します。GoogleClientSecrets への参照をコメント アウトすると、サーブレットは正常に動作します。

google-api-client-1.16.0-rc.jar は、外部 jar ファイルとして Eclipse -> Java Build Path -> Libraries リストにあります。[注文とエクスポート] タブで「チェック」マークが付いています (これは、jar ファイルを war ファイルにパッケージ化する必要があることを意味すると思います。サーバー環境で使用できる必要があります。

実行時に GAE でこれらのクラスを使用する際に何らかの制限はありますか? サーバーまたはサーブレットのクラスローダーのクラスパスに違いはありますか? (スタンドアロンの Java アプリケーションでは、Google ドライブにアクセスするためのコードは正常に機能します (つまり、その Java アプリケーション環境に必要なすべての jar があります。サーバーに奇妙な点があります (Jetty サーバーだと思います))。


DevAppServer がクラスを見つける方法を更新する

(Mark Doyle が指摘しているように) DevAppServer のクラス ローディング スキームは、DevAppServer コード自体をロードするために使用されるクラス ローディング スキームとは、webapp によって使用されるクラスをロードするために完全に異なります。また、Web アプリのクラス ローディング スキームは、通常の Eclipse プロジェクトのビルドパスではありません。処理する。(わかりやすくするために、ここでこれらすべてがどのように機能するかを文書化しているので、もう一度見つけることができます。)

調べてみると、Web アプリケーションのクラスをロードするときに、DevAppServer が Google クラスの「IsolatedAppClassLoader」を呼び出していることがわかります (各 Web アプリケーションのクラスのロードを互いに分離するためです。IsolatedAppClassLoader.loadClass() はDevAppServerClassLoader .loadClass() を呼び出します)。ケース) は最終的にそのスーパークラス java.lang.ClassLoader.loadClass() を呼び出し、この場合は java.net.URLClassLoader.findClass() を呼び出し、URLClassPath.getResource() を呼び出します。ここで多くの作業が開始されます。

URLClassPath.getResource() には、URLClassPath オブジェクトにリストされている各ローダーを取得する「for」ループがあります。この場合、sun.misc.URLClassPath$JarLoader (URLClassPath のサブクラス) のすべてのインスタンスである、URLClassPath に 17 (!7) 個のローダーがあります。-- これらは DevAppServer jar のようです。クラスが見つからないため、ClassNotFoundException が返されます (このレベルで)。

IsolatedAppClassLoaderはこれを繰り返します (理由はわかりませんが、今度は URLClassLoader オブジェクト (run() メソッド) を直接使用します。PrivilegedExceptionAction.run() に関する何か??)) いずれにせよ、URLClassPath (の匿名サブクラスから) URLClassLoader ??) は URLClassPath.getResource() を実行します (この IsolatedAppClassLoader インスタンスは URLClassLoader のサブクラスです!)。IsolatedAppClassLoader インスタンスには、21 個のローダーを持つ「ucp」フィールド (URLClassPath サブオブジェクト) が含まれています。

1 つ目は、url ファイルを含む FileLoader インスタンス (URLClassPath のサブクラス) です: /C:/eclip/webAppName/war/WEB-INF/classes/ -- これは、war/WEB 内のすべての個々のクラスを見つける場所です。 -INF/classes ディレクトリ。残りの 20 個のローダーはすべて JarLoader ローダーです。その 15 のうち、プロジェクトの war/WEB-INF ディレクトリにある 15 の .jar ファイルに対応します。残りの 5 つの JarLoader インスタンスは次のとおりです。

file:/C:/app/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.8.2/appengine-java-sdk-1.8.2/lib/impl/agent/appengine-agentruntime.jar!/ file:/ C:/app/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.8.2/appengine-java-sdk-1.8.2/lib/tools/jsp/repackaged-appengine-jakarta-jstl-1.1.2.jar !/ ファイル:/C:/app/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.8.2/appengine-java-sdk-1.8.2/lib/tools/jsp/repackaged-appengine-jakarta-standard- 1.1.2.jar!/ ファイル:/C:/app/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.8.2/appengine-java-sdk-1.8.2/lib/tools/jsp/repackaged-appengine -jasper-jdt-6.0.29.jar!/ ファイル:/C:/app/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.8.2/appengine-java-sdk-1.8.2/lib/opt/ tools/appengine-local-endpoints/v1/appengine-local-endpoints.jar!/

なぜこれらがリストに載っているのかわかりませんが、おそらく Jetty の標準的なものでしょうか?

4

1 に答える 1

1

GAE 開発サーバー (Jetty) は独自のクラスパスを設定し、Eclipse のビルド パスで構成した内容には注意を払いません。そのクラスパスには WEB-INF/lib が含まれているため、使用するライブラリがそこにあることを確認する必要があります。同様に、プロジェクトのクラスは通常、WEB-INF/classes にビルドされます。また、実稼働環境をエミュレートするために必要な GAE ライブラリと依存関係も含まれています。

さらに、GAE 開発環境は、独自のクラス ローディング メカニズムも提供します。これにより、GAE ライブラリへのアクセスが提供され、本番環境を模倣するクラスにアクセスできる制限が実装されます。例として、多くの Java IO/graphics クラスは制限されており、使用できません。

warファイルへのエクスポートとパッケージングに関して。Web 開発に Eclipse の WTP を使用している場合、GAE SDK は期待どおりに動作しません。起動すると、カスタム Jetty インスタンスが開始され、web フォルダーがポイントされます。したがって、jar ライブラリを WEB-INF/lib に配置しなかった場合 (同様に、クラスが WEB-INF/classes にコンパイルされなかった場合)、それらは見つかりません。

于 2013-08-18T11:33:54.957 に答える