4

このチュートリアルに従って、JavaがコンパイルするAntビルドファイルを作成します。GWTがコンパイルするよりも、正しいアクションを実行して.warファイルをビルドします。

私はEclipseとGWTコンパイルを使用しており、開発モードを実行すると機能します。また、Tomcatへのデプロイにも成功しました。

スクリプトを実行すると、コンパイルは機能しますが、gwt-compilerタスクで失敗します。私のantビルドスクリプトは次のとおりです:

<project name="vlp" default="gwt.compile" basedir=".">
    <tstamp />
    <!-- ################# PROPERTIES ################ -->
    <!-- directory properties -->
    <!-- source -->
    <property name="projectName" value="VirtualLabPortal" />
    <property name="src.dir" location="src" />
    <property name="build.dir" location="bin" />
    <property name="src.build.dir" location="${build.dir}/src" />
    <property name="gwt.build.dir" location="${build.dir}/gwt" />
    <property name="gwt.unitCache.dir" location="gwt-unitCache" />
    <!-- libraries -->
    <property name="src.lib.dir" location="war/WEB-INF/lib" />

    <!-- ___________________________________________________________________
        |                                                                   |
        |               Configure path source/test                          |
        |___________________________________________________________________| 
    -->
    <path id="compile.path">
        <fileset dir="${src.lib.dir}" includes="*.jar" />
        <fileset dir="${src.lib.dir}/gwt" includes="*.jar" />
    </path>
    <!-- ___________________________________________________________________
        |                                                                   |
        |               Clean old compiled source/test/war                  |
        |___________________________________________________________________| 
    -->
    <target name="clean" description="Clean all the old build files.">
        <delete dir="${build.dir}" />
        <delete dir="${gwt.unitCache.dir}" />
        <delete file="${projectWar}" />
        <delete file="${src.lib.dir}/${projectJar}" />
    </target>
    <!-- ___________________________________________________________________
        |                                                                   |
        |                       Compile the source                          |
        |(should exclude gwtview code which is compiled by the gwt compiler)|   
        |___________________________________________________________________| 
    -->
    <target name="src.compile" depends="clean" description="Compile the source code when everything has been cleaned.">
        <mkdir dir="${src.build.dir}" />
        <javac encoding="utf-8" destdir="${src.build.dir}" nowarn="true">
            <src path="${src.dir}" />
            <classpath refid="compile.path" />
        </javac>
    </target>
    <!-- ___________________________________________________________________
        |                                                                   |
        |                       Invoke the GWT compiler                     |
        |___________________________________________________________________| 
    -->
    <property name="module.gwt.xml" location="${src.dir}/com/banctecmtl/ca/vlp" />
    <target name="gwt.compile" depends="src.compile">
        <java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
            <classpath>
                <!-- src dir is added to ensure the module.xml file(s) are on the classpath -->
                <pathelement location="${module.gwt.xml}" />
                <path refid="compile.path" />
            </classpath>
            <jvmarg value="-Xmx512m" />
            <arg line="${projectName} -logLevel ALL -style OBF -war ${build.dir}" />
        </java>
    </target>
    <!-- ___________________________________________________________________
        |                                                                   |
        |           Copy the config files in the war directory              |
        |___________________________________________________________________| 
    -->
    <property name="config.dir" location="war/config" />
    <target name="copy-resources">
        <copy todir="war/config" preservelastmodified="true">
            <fileset dir="${config.dir}">
                <include name="**.*" />
            </fileset>
        </copy>
    </target>
    <!-- ___________________________________________________________________
        |                                                                   |
        |           Create a Jar to be included in the war                  |
        |___________________________________________________________________| 
    -->
    <property name="projectJar" value="${projectName}.jar" />
    <property name="gwt.client.dir" location="com/banctecmtl/ca/vlp/view/webview" />
    <target name="jar" depends="src.compile">
        <!-- should also depend on gwt.compile -->
        <jar jarfile="${src.lib.dir}/${projectJar}" basedir="${src.build.dir}/">
            <!-- Don't wrap any of the client only code into the JAR
                <exclude name="${gwt.client.dir}/**/*.class"/> -->
            <exclude name="${gwt.client.dir}/**/*.class" />
        </jar>
    </target>
    <!-- ___________________________________________________________________
        |                                                                   |
        |                   Create a War from the source                    |
        |___________________________________________________________________| 
    -->
    <property name="projectWar" value="${projectName}.war" />
    <target name="war" depends="jar,copy-resources">
        <war basedir="war" destfile="${projectWar}" webxml="war/WEB-INF/web.xml">
            <exclude name="WEB-INF/**" />
            <webinf dir="war/WEB-INF/">
                <include name="lib/*.jar" />
                <include name="classes/*.properties" />
                <exclude name="**/gwt-dev.jar" />
                <exclude name="**/gwt-user.jar" />
            </webinf>
        </war>
    </target>

    <!-- ___________________________________________________________________
        |                                                                   |
        |                   Deploy to the production server                 |
        |___________________________________________________________________| 
    -->
    <!-- It is possible you can't run this from eclipse,
     you need to edit the run configurations and add the 
     latest jsch library to the classpath -->
    <property name="user" value="root" />
    <property name="password" value="Banctec01" />
    <property name="prodHost" value="vlp" />
    <property name="dest" value="/usr/share/tomcat6/webapps/ROOT.war" />
    <target name="deploy" depends="war">
        <echo message="Copying to : ${user}@${prodHost}:${dest}" />
        <scp file="${projectWar}" remoteTofile="${user}@${prodHost}:${dest}" password="${password}" trust="true" />
    </target>
</project>

次のエラーで失敗します:

Buildfile: D:\workspace\vlp\build.xml
clean:
   [delete] Deleting directory D:\workspace\vlp\war\WEB-INF\classes
src.compile:
    [mkdir] Created dir: D:\workspace\vlp\war\WEB-INF\classes
    [javac] D:\workspace\vlp\build.xml:42: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 134 source files to D:\workspace\vlp\war\WEB-INF\classes
    [javac] Note: D:\workspace\vlp\src\com\banctecmtl\ca\vlp\controller\schedule\ScheduledTaskManager.java uses unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.
gwt.compile:
     [java] Checking for updates
     [java]    First launch was 134c3e23387
     [java]    Last ping was Mon Apr 23 14:42:48 EDT 2012, min wait is 86400000ms
     [java] Module location: file:/D:/workspace/vlp/src/com/banctecmtl/ca/vlp/VirtualLabPortal.gwt.xml
     [java] Loading inherited module 'com.google.gwt.user.User'
     [java]    Module location: jar:file:/D:/workspace/vlp/war/WEB-INF/lib/gwt/gwt-user.jar!/com/google/gwt/user/User.gwt.xml
     [java]    Loading inherited module 'com.google.gwt.animation.Animation'
     [java]       Module location: jar:file:/D:/workspace/vlp/war/WEB-INF/lib/gwt/gwt-user.jar!/com/google/gwt/animation/Animation.gwt.xml
     [java]       Loading inherited module 'com.google.gwt.core.Core'
     [java]          Module location: jar:file:/D:/workspace/vlp/war/WEB-INF/lib/gwt/gwt-user.jar!/com/google/gwt/core/Core.gwt.xml
     [java]          Loading inherited module 'com.google.gwt.dev.jjs.intrinsic.Intrinsic'
     [java]             Module location: jar:file:/D:/workspace/vlp/war/WEB-INF/lib/gwt/gwt-dev.jar!/com/google/gwt/dev/jjs/intrinsic/Intrinsic.gwt.xml
     [java]             Loading inherited module 'com.google.gwt.lang.LongLib'
     [java]                Module location: jar:file:/D:/workspace/vlp/war/WEB-INF/lib/gwt/gwt-dev.jar!/com/google/gwt/lang/LongLib.gwt.xml
     [java]          Loading inherited module 'com.google.gwt.emul.Emulation'
     [java]             Module location: jar:file:/D:/workspace/vlp/war/WEB-INF/lib/gwt/gwt-user.jar!/com/google/gwt/emul/Emulation.gwt.xml
     [java]             Loading inherited module 'com.google.gwt.logging.LogImpl'
     [java]                Module location: jar:file:/D:/workspace/vlp/war/WEB-INF/lib/gwt/gwt-user.jar!/com/google/gwt/logging/LogImpl.gwt.xml
     [java]          Loading inherited module 'com.google.gwt.xhr.XMLHttpRequest'
     [java]             Module location: jar:file:/D:/workspace/vlp/war/WEB-INF/lib/gwt/gwt-user.jar!/com/google/gwt/xhr/XMLHttpRequest.gwt.xml
     [java]             Loading inherited module 'com.google.gwt.core.Core'
     [java]                Module 'com.google.gwt.core.Core' has already been loaded and will be skipped
     [java]          Loading inherited module 'com.google.gwt.core.CompilerParameters'
     [java]             Module location: jar:file:/D:/workspace/vlp/war/WEB-INF/lib/gwt/gwt-user.jar!/com/google/gwt/core/CompilerParameters.gwt.xml
     [java]          [...]
     [java]    Loading inherited module 'com.google.gwt.user.User'
     [java]       Module 'com.google.gwt.user.User' has already been loaded and will be skipped
     [java] Public resources found in...
     [java] Translatable source found in...
     [java] Persistent unit cache dir set to: D:\workspace\vlp\war\..\gwt-unitCache
     [java] Compiling module VirtualLabPortal
     [java] Looking for previously cached Compilation Units in D:\workspace\vlp\war\..\gwt-unitCache
     [java] Loaded 0 units from persistent store.
     [java] Starting UnitWriteThread.
     [java]    Found 0 cached units.  Used 0 / 2413 units from cache.
     [java] [ERROR] Unexpected internal compiler error
     [java] java.lang.RuntimeException: Exception processing units
     [java]     at com.google.gwt.dev.javac.CompilationStateBuilder$CompileMoreLater.compile(CompilationStateBuilder.java:248)
     [java]     at com.google.gwt.dev.javac.CompilationStateBuilder.doBuildFrom(CompilationStateBuilder.java:447)
     [java]     at com.google.gwt.dev.javac.CompilationStateBuilder.buildFrom(CompilationStateBuilder.java:370)
     [java]     at com.google.gwt.dev.cfg.ModuleDef.getCompilationState(ModuleDef.java:360)
     [java]     at com.google.gwt.dev.Precompile.precompile(Precompile.java:252)
     [java]     at com.google.gwt.dev.Precompile.precompile(Precompile.java:233)
     [java]     at com.google.gwt.dev.Precompile.precompile(Precompile.java:145)
     [java]     at com.google.gwt.dev.Compiler.run(Compiler.java:232)
     [java]     at com.google.gwt.dev.Compiler.run(Compiler.java:198)
     [java]     at com.google.gwt.dev.Compiler$1.run(Compiler.java:170)
     [java]     at com.google.gwt.dev.CompileTaskRunner.doRun(CompileTaskRunner.java:88)
     [java]     at com.google.gwt.dev.CompileTaskRunner.runWithAppropriateLogger(CompileTaskRunner.java:82)
     [java]     at com.google.gwt.dev.Compiler.main(Compiler.java:177)
     [java] Caused by: java.lang.NoSuchMethodError: com.google.gwt.dev.jjs.ast.JProgram.serializeTypes(Ljava/util/List;Ljava/io/ObjectOutputStream;)V
     [java]     at com.google.gwt.dev.javac.CompilationUnitImpl.<init>(CompilationUnitImpl.java:68)
     [java]     at com.google.gwt.dev.javac.SourceFileCompilationUnit.<init>(SourceFileCompilationUnit.java:48)
     [java]     at com.google.gwt.dev.javac.CompilationUnitBuilder$ResourceCompilationUnitBuilder.makeUnit(CompilationUnitBuilder.java:154)
     [java]     at com.google.gwt.dev.javac.CompilationUnitBuilder.build(CompilationUnitBuilder.java:266)
     [java]     at com.google.gwt.dev.javac.CompilationStateBuilder$CompileMoreLater$1.run(CompilationStateBuilder.java:223)

BUILD FAILED
D:\workspace\vlp\build.xml:60: Java returned: 1

Total time: 36 seconds

gwt-compilerクラス名をDevModeに変更すると、正常にビルドされていることがわかりました。classname="com.google.gwt.dev.DevMode"の代わりに:を使用しclassname="com.google.gwt.dev.Compiler"ます。

編集:上記のXMLをリファクタリングしました。build.xmlは、すべてのbinディレクトリをクリーンアップします。また、ディレクトリjavacへのポインタとGoogle Web Toolkitコンパイラの出力: 。コンパイラはまだ動作しません...bin/srcbin/gwt

編集:Google開発者サイトからすぐに最新のSDKをダウンロードし、クラスパスとEclipseプラグインにある古いライブラリをオーバーライドしました。それでも、antビルドスクリプトでは機能しません。

誰かがここで何が問題になるのかわかりますか?

4

4 に答える 4

3

私が言えるのは、このメソッドcom.google.gwt.dev.jjs.ast.JProgram.serializeTypes(Ljava/util/List;Ljava/io/ObjectOutputStream;)Vgwt-dev2.4.0でのみ導入されているということです。gwt-dev2.3.0には存在しません。

これは、クラスパスのどこかに2つのgwt-devバージョンがあることを意味します。それらの1つは2.4.0であり、それがcom.google.gwt.dev.javac.CompilationUnitImplその方法を探している理由です。もう1つは2.3.0以前のものであるため、そのメソッドは見つかりません(JProgramクラスは古いバージョンを使用してコンパイラーによってロードされました)。

それらを徹底的に調べてみてください。または、何が入っているかをよく見守るような新鮮な環境を始めてみてください。

于 2012-04-30T21:10:18.220 に答える
3

tl; dr:これは、クラスコンテキストが不十分または正しくない場合と、によって提供されるCompilerリンカーの違いによるものです。DevMode

問題の追跡

あなたが持っている再現が現在のGWTトランクに存在することに気づきました。具体的には、次のコードブロックで失敗しています。

ArrayList<CompilationUnit> resultUnits = new ArrayList<CompilationUnit>();
      do {
        // Compile anything that needs to be compiled.
        buildQueue = new LinkedBlockingQueue<CompilationUnitBuilder>();
        final ArrayList<CompilationUnit> newlyBuiltUnits = new ArrayList<CompilationUnit>();
        final CompilationUnitBuilder sentinel = CompilationUnitBuilder.create((GeneratedUnit) null);
        final Throwable[] workerException = new Throwable[1];
        Thread buildThread = new Thread() {
          @Override
          public void run() {
            try {
              do {
                CompilationUnitBuilder builder = buildQueue.take();
                if (builder == sentinel) {
                  return;
                }
                // Expensive, must serialize GWT AST types to bytes.
                CompilationUnit unit = builder.build(); // <-- Right here.
                newlyBuiltUnits.add(unit);
              } while (true);
            } catch (Throwable e) {
              workerException[0] = e;
            }
          }
        };

トレースよりもさらにスタックをほどくと、最終的にUnifyAst.javaに到達するまで、ファクトリと10層のコードをバウンスします。そして、見よ、見よ:

...
mapApi(enclosingType);

// Now the method should be there.
method = methodMap.get(sig);
if (method == null) {
  // TODO: error logging
  throw new NoSuchMethodError(sig);
}
assert !method.isExternal();
return method;
...

NoSuchMethodErrorこれは、 GWTのプリコンパイル段階で呼び出される唯一のインスタンスです。

コンパイラとDevModeのリンクの違い

涼しい。これが爆発している理由を深く掘り下げたので、なぜDevMode機能Compilerしないのに機能するのかを理解しましょう。どちらもUtil.javaの同じコピーをインポートするため、技術的には、両方のタイプが静的にJavaコンパイラー(GWTコンパイラーではない)で使用可能であることに注意してください。

リンカーを調べると、次のように直接Compiler使用されていることがわかります。Link.link

Link.link(logger.branch(TreeLogger.TRACE, logMessage), module,
          generatedArtifacts, allPerms, resultFiles, options.getWarDir(),
          options.getDeployDir(), options.getExtraDir(), precompileOptions); 

一方DevMode、非常に簡潔な静的呼び出しを使用し、次のインスタンスに別のパスを入力しますStandardLinkerContext

link(loadLogger, module);

...

@Override
protected synchronized void produceOutput(TreeLogger logger, StandardLinkerContext linkerStack,
      ArtifactSet artifacts, ModuleDef module, boolean isRelink) throws UnableToCompleteException {

    ...
    linkerStack.produceOutput(linkLogger, artifacts, Visibility.Public, outFileSet);
    linkerStack.produceOutput(linkLogger, artifacts, Visibility.Deploy, deployFileSet);
    linkerStack.produceOutput(linkLogger, artifacts, Visibility.Private, extraFileSet);
    ...
}

素晴らしい!では、どうすれば修正できますか?

この投稿の執筆の途中で受け入れられたように、yairは、この問題の1つの診断を提供し、2つのバージョンのGWTのコンテキストでは、コンパイル前のステップが競合するクラスIDに対してロバストではないことに注意します。間違ったオブジェクトや不十分なオブジェクトを取り込む他のクラスの可視性の問題precompilation.getGeneratedArtifacts();も、この再現を引き起こす可能性があります。

yairに承認済みの回答ステータスが与えられた場合、問題は解決されたと思います。ただし、この投稿に出くわす他の人にとっては、他のクラスパスまたは可視性の問題により、この正確な問題が再発する可能性があると考えられます。

于 2012-05-02T23:21:27.690 に答える
0

java.io.ObjectOutputStreamクラスはGWTコンパイラではサポートされていません。Javaクラスを使用する前に、 https://developers.google.com/web-toolkit/doc/latest/RefJreEmulation#Package_java_io
を参照して、 GWTがサポートしていることを確認する必要があります。

于 2012-04-04T16:43:11.737 に答える
0

JVMをフォークしてGwtコンパイラを実行すると、binディレクトリはClassPathにあります。

Eclipseは開発モードでコンパイルbinするため、クラスが残っていると、コンパイラーが一部のソースファイルを適切に処理できなくなる可能性があります。

Antターゲットを呼び出す前に、binディレクトリが空であることを確認する必要があります。その時は通過するかもしれません。

2つのターゲットディレクトリを使用することをお勧めします。1つはJavaソースからコンパイルされたクラス用で、もう1つはGWTで生成されたファイル用です。次に、ターゲットwarは両方をWARに収集します。

于 2012-04-26T22:12:39.833 に答える