I'm working on Liferay 7. I'm new to Liferay and I'm experiencing an issue that I spent too much time on.
I have a portlet that I decided to create a Service Builder (named "Employee"). Here is my service.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 7.0.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_7_0_0.dtd">
<service-builder package-path="com.test">
<author>sachin.singh</author>
<namespace>crud</namespace>
<entity name="Employee" table="user" local-service="true" remote-service="true">
<column name="iduser" type="int" primary="true" id-type="increment"/>
<column name="name" type="String" />
<column name="secret_code" type="String" />
</entity>
</service-builder>
And when i am building using liferay service builder i am getting this error
[copy] Copying 1 file to D:\tools\com.liferay.portal.plugins.sdk-1.0.11\portlets\firstLiferay-portlet\docroot\WEB-INF\classes
[copy] Copied 3 empty directories to 2 empty directories under D:\tools\com.liferay.portal.plugins.sdk-1.0.11\portlets\firstLiferay-portlet\docroot\WEB-INF\classes
[jar] Building MANIFEST-only jar: D:\tools\com.liferay.portal.plugins.sdk-1.0.11\portlets\firstLiferay-portlet\service-builder-classpath.jar
[delete] Deleting: D:\tools\com.liferay.portal.plugins.sdk-1.0.11\portlets\firstLiferay-portlet\service-builder-classpath.jar.manifest
[java] Java Result: 1
[delete] Deleting: D:\tools\com.liferay.portal.plugins.sdk-1.0.11\portlets\firstLiferay-portlet\service-builder-classpath.jar
[echo] java.lang.NoClassDefFoundError: com/thoughtworks/qdox/model/JavaMethod
[echo] at java.lang.Class.getDeclaredMethods0(Native Method)
[echo] at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
[echo] at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
[echo] at java.lang.Class.getMethod0(Class.java:3018)
[echo] at java.lang.Class.getMethod(Class.java:1784)
[echo] at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
[echo] at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
[echo] Caused by: java.lang.ClassNotFoundException: com.thoughtworks.qdox.model.JavaMethod
[echo] at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
[echo] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[echo] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
[echo] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
[echo] ... 7 more
[echo] Error: A JNI error has occurred, please check your installation and try again
[echo] Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; support was removed in 8.0
[echo] Exception in thread "main"
I checked and cross verify,All jars are there in jar library.
Here is the screenshot of added jar:
Especially when you're new, I'd recommend to try again and use Liferay Workspace instead of the (deprecated) plugins-sdk. All of the samples (here's one for service builder) build on this, and plugins-sdk should largely be used only to migrate existing legacy plugins to the latest release.
I'm not sure what your screenshot shows - if it's all of the bundled jars, then it looks horrible. You should only have tiny plugins in times of OSGi bundles, and it definitely looks like those are way too many dependencies.
After clean checkout/clone from repo, I get this error in eclipse on the execution of the jaxb2-maven-plugin xjc goal.
After "Update Maven Configuration" the code is still not generated.
In my neon3 eclipse(4.6.3) I have installed the m2e plugin(1.7.1) together with the "m2e connector for jaxb2"(4.0.0)
null (org.codehaus.mojo:jaxb2-maven-plugin:2.2:xjc:xjc-evu:generate-sources)
org.apache.maven.plugin.MojoExecutionException
at org.codehaus.mojo.jaxb2.javageneration.AbstractJavaGeneratorMojo.performExecution(AbstractJavaGeneratorMojo.java:482)
at org.codehaus.mojo.jaxb2.AbstractJaxbMojo.execute(AbstractJaxbMojo.java:257)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
at org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:331)
at org.eclipse.m2e.core.internal.embedder.MavenImpl$11.call(MavenImpl.java:1362)
at org.eclipse.m2e.core.internal.embedder.MavenImpl$11.call(MavenImpl.java:1)
at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:176)
at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:112)
at org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:1360)
at org.eclipse.m2e.core.project.configurator.MojoExecutionBuildParticipant.build(MojoExecutionBuildParticipant.java:52)
at org.eclipse.m2e.core.internal.builder.MavenBuilderImpl.build(MavenBuilderImpl.java:137)
at org.eclipse.m2e.core.internal.builder.MavenBuilder$1.method(MavenBuilder.java:172)
at org.eclipse.m2e.core.internal.builder.MavenBuilder$1.method(MavenBuilder.java:1)
at org.eclipse.m2e.core.internal.builder.MavenBuilder$BuildMethod$1$1.call(MavenBuilder.java:115)
at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:176)
at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:112)
at org.eclipse.m2e.core.internal.builder.MavenBuilder$BuildMethod$1.call(MavenBuilder.java:105)
at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:176)
at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:151)
at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:99)
at org.eclipse.m2e.core.internal.builder.MavenBuilder$BuildMethod.execute(MavenBuilder.java:86)
at org.eclipse.m2e.core.internal.builder.MavenBuilder.build(MavenBuilder.java:200)
at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:735)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246)
at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:301)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:304)
at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:360)
at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:383)
at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144)
at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
Caused by: java.lang.NullPointerException
at org.codehaus.mojo.jaxb2.shared.environment.ToolExecutionEnvironment.restore(ToolExecutionEnvironment.java:182)
at org.codehaus.mojo.jaxb2.javageneration.AbstractJavaGeneratorMojo.performExecution(AbstractJavaGeneratorMojo.java:427)
... 33 more
In the same pom.xml it is marked under lifecycle-mapping as
<action>
<execute>
<runOnIncremental>false</runOnIncremental>
<runOnConfiguration>true</runOnConfiguration>
</execute>
</action>
Here stands that the bitstrings connector should support the jaxb2-maven-plugin and in this comment from the Author I can see there is support since version 1.0.3.201107311209. Nevertheless on the authors homepage it is stated
Plugin: org.codehaus.mojo:jaxb2-maven-plugin Home:
http://mojo.codehaus.org/jaxb2-maven-plugin
(Note: not required for jaxb2-maven-plugin version 1.5+)
Which m2e connector or pom.xml configuration should I use to make jaxb2-maven-plugin work in eclipse (Meaning, it will generate surces in the generate-sources phase on update configuration and add the generated folder into classpath) ?
mvn clean install worked for me.
My workaround: After clean checkout, run the Maven generate-sources phase manually, and configure build-helper plugin to add the jaxb folder as resources folder into eclipse project (for this you need of course the m2e connector for build-helper-maven-plugin )
The long awaited Super Dev Mode came and I attempted to use it. After building GWT trunk I created a test app and compiled it successfully. I then added this to the module XML file with the intent to enable Source Maps for Chrome:
<!-- Allows debugging without DevMode -->
<set-property name="compiler.useSourceMaps" value="true">
<when-property-is name="user.agent" value="safari" />
</set-property>
I then tried to compile the application. The output was the following:
Compiling module com.hsi.gwt.test.sdm.Hello_sdm
Compiling 6 permutations
Compiling permutation 0...
Compiling permutation 1...
Compiling permutation 2...
Compiling permutation 3...
Compiling permutation 4...
Compiling permutation 5...
Source Maps Enabled
Compile of permutations succeeded
Linking into /Users/bbrudnoy/Workspaces/indigo-hsi/hello-sdm/war/hello_sdm
Invoking Linker Export CompilationResult symbol maps
[ERROR] Failed to link
java.lang.NoClassDefFoundError: org/json/JSONException
at com.google.gwt.thirdparty.debugging.sourcemap.SourceMapGeneratorV3.mergeMapSection(SourceMapGeneratorV3.java:243)
at com.google.gwt.core.linker.SymbolMapsLinker.link(SymbolMapsLinker.java:299)
at com.google.gwt.core.ext.linker.impl.StandardLinkerContext.invokeLinkForOnePermutation(StandardLinkerContext.java:372)
at com.google.gwt.dev.Link.finishPermutation(Link.java:491)
at com.google.gwt.dev.Link.doSimulatedShardingLink(Link.java:453)
at com.google.gwt.dev.Link.link(Link.java:200)
at com.google.gwt.dev.Compiler.run(Compiler.java:262)
at com.google.gwt.dev.Compiler.run(Compiler.java:198)
at com.google.gwt.dev.Compiler$1.run(Compiler.java:170)
at com.google.gwt.dev.CompileTaskRunner.doRun(CompileTaskRunner.java:88)
at com.google.gwt.dev.CompileTaskRunner.runWithAppropriateLogger(CompileTaskRunner.java:82)
at com.google.gwt.dev.Compiler.main(Compiler.java:177)
Caused by: java.lang.ClassNotFoundException: org.json.JSONException
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 12 more
What am I missing?
If you use Maven then add the following to your pom.xml file. It should help you overcome that problem.
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
</dependency>
EDIT: this is fixed in GWT 2.5
This is a known issue: http://code.google.com/p/google-web-toolkit/issues/detail?id=7397
As a quick workaround, you can add the gwt-servlet-deps.jar to the classpath.
BTW, Super Dev Mode will automatically generate source maps, you don't need to enable them in your module (but for now you have to enable Super Dev Mode and use the xsiframe linker)
I'm following this tutorial to create my ant build file that java compiles, than GWT compiles than perform the correct actions to build my .war file.
I use Eclipse and GWT-compile works, and when I run the development mode it works. I have also successfully deployed on tomcat.
The things is when I run my script, the compiles work but it fails on the gwt-compiler task. My ant build script is as follow :
<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>
It fails with the following error :
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
I found that changing the gwt-compiler class name to the DevMode is building successfully. Using : classname="com.google.gwt.dev.DevMode" instead of classname="com.google.gwt.dev.Compiler".
EDIT : I refactored the XML above.
The build.xml cleans all the bin directory. I also pointer the javacto the bin/src directory and Google Web Toolkit compiler outputs to : bin/gwt. The compiler still doesn't work...
EDIT : I downloaded the latest SDK right away from google developpers site, and overrided the old librairies found in my classpath and in my eclipse plugin. Still won't work with the ant build script.
Anybody sees what could be the problem here?
All I can say is that the method com.google.gwt.dev.jjs.ast.JProgram.serializeTypes(Ljava/util/List;Ljava/io/ObjectOutputStream;)V is introduced only in gwt-dev 2.4.0. It doesn't exist in gwt-dev 2.3.0.
Which implies there are somewhere, in the classpath, two gwt-dev versions. One of them is 2.4.0, which is why com.google.gwt.dev.javac.CompilationUnitImpl is looking for that method. The other is of 2.3.0 or older, which is why that method isn't found (JProgram class was loaded by the compiler using the older version).
Try to look them up thoroughly. Or try to start a fresh environment in which you put a good eye on what's getting in.
tl;dr: this is due to differences in the linkers provided by Compiler versus DevMode in cases of insufficient or incorrect class context
Tracing the issue
I noticed that the repro you have exists in the current GWT trunk. Specifically, it's failing in this block of code:
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;
}
}
};
Unwinding the stack further than your trace, we bounce through a factory and ten layers of code, until we finally hit UnifyAst.java. And, lo and behold:
...
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;
...
This is the only instance of NoSuchMethodError called by the Precompilation stage of GWT.
Differences in Compiler and DevMode linking
Cool. Now that we've taken the deep dive into why this is exploding, let's figure out why DevMode works when Compiler doesn't. We note that both import the same copy of Util.java, so technically, both types are available statically to our Java compiler (just not the GWT compiler).
Inspecting the linkers, we note that Compiler uses Link.link directly:
Link.link(logger.branch(TreeLogger.TRACE, logMessage), module,
generatedArtifacts, allPerms, resultFiles, options.getWarDir(),
options.getDeployDir(), options.getExtraDir(), precompileOptions);
Whereas DevMode uses a much terser static call, with a separate pass filling in an instance of 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);
...
}
Great! So, how do I fix it?
As accepted in the middle of writing this post, yair provides one such diagnosis for the issue, noting that the precompilation step is non-robust to conflicting class identities in the context of two versions of GWT. Other class visibility problems where precompilation.getGeneratedArtifacts(); pulls in wrong or insufficient objects may also cause this repro.
I will assume the issue has now been resolved, given yair was given accepted answer status. But it is conceivable for other people running across this post that other classpath or visibility issues may cause this exact issue to recur.
java.io.ObjectOutputStream class isn't supported by GWT compiler.
You have to refer to https://developers.google.com/web-toolkit/doc/latest/RefJreEmulation#Package_java_io before using Java classes to be sure GWT supports it.
You fork a JVM to run Gwt Compiler and the bin directory is in ClassPath.
As Eclipse compiles in development mode, a remaining class in bin may prevent the compiler to process properly some source files.
You should make sure the bin directory is empty before you invoke your Ant target. It may pass then.
I recommend you to use two target directories: one for classes compiled from Java sources and another one for GWT generated files. Then the target war will collect both into the WAR.
I can successfully compile the source, but when I hit this ant task:
<target name="gwtc" depends="javac" description="GWT compile to JavaScript">
<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
<classpath>
<pathelement location="src"/>
<path refid="project.class.path"/>
</classpath>
<jvmarg value="-Xmx256M"/>
<arg line="${gwt.args}"/>
<arg value="com.jwavro.jaguar.jaguar"/>
</java>
</target>
I'm getting these errors:
gwtc:
[java] Compiling module com.jwavro.jaguar.jaguar
[java] Scanning for additional dependencies: generated://9161C2B729E3521B2A51CBE6F2AE8A77/com/unnison/framework/client/GeneratedGinInjector.java
[java] Computing all possible rebind results for 'com.unnison.framework.client.GeneratedGinInjector'
[java] Rebinding com.unnison.framework.client.GeneratedGinInjector
[java] Invoking generator com.google.gwt.inject.rebind.GinjectorGenerator
[java] [ERROR] Generator 'com.google.gwt.inject.rebind.GinjectorGenerator' threw an exception while rebinding 'com.unnison.framework.client.GeneratedGinInjector'
[java] com.google.inject.CreationException: Guice creation errors:
[java]
[java] 1) No implementation for javax.inject.Provider was bound.
[java] while locating javax.inject.Provider
[java] for parameter 9 at com.google.gwt.inject.rebind.BindingsProcessor.(BindingsProcessor.java:209)
[java] at com.google.gwt.inject.rebind.GinjectorGeneratorModule.configure(GinjectorGeneratorModule.java:59)
GUICE binding is supposed to be automatic, any idea how to fix it ?
Guice can not be used directly with GWT. You need to use GIN.
javax.inject is a dependency that needs to be in your classpath.
If you downloaded Guice from Google, there should be a lib folder in the exploded zip with a javax.inject.jar file, or you can download it direct from trunk.
The key is this line:
[java] 1) No implementation for javax.inject.Provider was bound.
There are two things I can think of. First of all make sure you have properly inherited the GIN module in your GWT module xml:
<module>
...
<inherits name="com.google.gwt.inject.Inject"/>
...
</module>
Secondly you have to be carefull about versions of GIN and Guice. On the GIN homepage it says:
GIN 1.0 requires ... and Guice 2.0
For Gin 1.5 you'll need to use the Guice snapshot distributed with Gin or ... Guice 3.0
So make sure you have the appropriate Guice JAR in path.