gwt serialization policy hosted mode out of sync - java

When running my GWT application (gwt 2.0.4) in hosted mode, calling RPC methods running on remote Tomcat, I get GWT serialization exception:
INFO: GwtRpcEventSrvc: ERROR: The serialization policy file '/84EC7BA65AF8175BAA99B47877FDE163.gwt.rpc' was not found; did you forget to include it in this deployment?
SEVERE: GwtRpcEventSrvc: WARNING: Failed to get the SerializationPolicy '84EC7BA65AF8175BAA99B47877FDE163' for module 'http://host:19980/MYAPP/'; a legacy, 1.3.3 compatible, serialization policy will be used. Youmay experience SerializationExceptions as a result.
SEVERE: Exception while dispatching incoming RPC call
Throwable occurred: com.google.gwt.user.client.rpc.SerializationException: java.lang.reflect.InvocationTargetException
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeWithCustomSerializer(ServerSerializationStreamWriter.java:760)
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeImpl(ServerSerializationStreamWriter.java:723)
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:612)
.at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:129)
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:152)
...
Caused by: com.google.gwt.user.client.rpc.SerializationException: Type 'com.mypackage.data.MyData' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer.For security purposes, this type will not be serialized.: instance = com.mypackage.data.MyData#1b061b06
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:610)
.at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:129)
.at com.google.gwt.user.client.rpc.core.java.util.Collection_CustomFieldSerializerBase.serialize(Collection_CustomFieldSerializerBase.java:43)
.at com.google.gwt.user.client.rpc.core.java.util.LinkedList_CustomFieldSerializer.serialize(LinkedList_CustomFieldSerializer.java:36)
.... 33 more
Hosted mode generates serializations policy files (*.gwt.rpc) with different md5 that those that were created during GWT compilation - these are deployed on my server. GWT is missing serialization policy file that hosted mode client wants.
When running in non-hosted mode everything is fine.
I tried to launch hosted mode via Ant or Eclipse debug configuration with the same results. GWT compilation classpath and hosted mode classpath (including) are the same.
GWT Compilation Ant script:
<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
<classpath>
<pathelement location="${basedir}/src" />
<pathelement location="${dir.build.root}/ProjectA/src" />
<pathelement location="${dir.build.root}/ProjectB/src" />
<pathelement location="${dir.build.root}/ProjectC/src" />
<pathelement location="${dir.build.root}/ProjectD/src" />
<pathelement location="${dir.build.root}/ProjectE/src" />
<pathelement location="${dir.root}/ProjectD/src" />
<pathelement location="${dir.root}/THIRDPARTY/build/athirdparty.jar" />
<pathelement location="${dir.commons.gwtcompiler}/gwt-user.jar" />
<pathelement location="${dir.commons.gwtcompiler}/gwt-dev.jar" />
<pathelement location="../ExternalLibs/libs/gwt-log-3.0.0.jar" />
<!-- JAXB API sources needed for GWT compilation of JAXB annotated classes -->
<pathelement location="../ExternalLibs/nonshipjars/jaxb-api-src.zip" />
</classpath>
<jvmarg value="-Xmx1g" />
<jvmarg value="-Dgwt.nowarn.metadata" />
<arg line="-localWorkers 2 -style OBF" />
<arg line="-war ${basedir}/www" />
<arg line="-extra ${basedir}/build" />
<arg value="com.myapp.Main" />
</java>
Hosted mode launch - Ant script:
<target name="hosted" description="Run hosted mode">
<java failonerror="true" fork="true" classname="com.google.gwt.dev.HostedMode">
<classpath>
<pathelement location="${basedir}/src" />
<pathelement location="${dir.build.root}/ProjectA/src" />
<pathelement location="${dir.build.root}/ProjectB/src" />
<pathelement location="${dir.build.root}/ProjectC/src" />
<pathelement location="${dir.build.root}/ProjectD/src" />
<pathelement location="${dir.build.root}/ProjectE/src" />
<pathelement location="${dir.root}/ProjectD/src" />
<pathelement location="${dir.root}/THIRDPARTY/build/athirdparty.jar" />
<pathelement location="${dir.commons.gwtcompiler}/gwt-user.jar" />
<pathelement location="${dir.commons.gwtcompiler}/gwt-dev.jar" />
<pathelement location="../ExternalLibs/libs/gwt-log-3.0.0.jar" />
<!-- JAXB API sources needed for GWT compilation of JAXB annotated classes -->
<pathelement location="../ExternalLibs/nonshipjars/jaxb-api-src.zip" />
</classpath>
<jvmarg value="-Xmx1g" />
<jvmarg value="-Dgwt.nowarn.metadata" />
<arg line="com.myapp.Main" />
<arg line="-startupUrl" />
<arg line=" http://host:19980/MYAPP/Main.html" />
<arg line="-whitelist" />
<arg line="^http[:][/][/]host[:]19980" />
<arg line="-whitelist" />
<arg line=" ^http[:][/][/]localhost" />
<arg line="-whitelist" />
<arg line="^http[:][/][/]127.0.0.1" />
<arg line="-port" />
<arg line="8080" />
<arg line="-noserver" />
<arg line="-logLevel" />
<arg line="DEBUG" />
</java>
</target>
RPC method signature:
public List<MyData> getSmpeWorkDddefZonesData(String processId);
MyData definition (declared in ProjectE that is non-GWT project - data tier):
package com.mypackage.data;
import java.io.Serializable;
public interface MyData extends Serializable {...
MyData is linked in module inherited from another GWT module:
com.mypackage.Data.gwt.xml:
<module>
<source path="data" />
</module>
Main module com.myapp.Main.gwt.xml:
...
<inherits name="com.mypackage.Data" />
...
How to make hosted generate the same serialization policy files?

I've been having the same problem. The only solution I see, is to make sure you have the same .gwt.rpc files on both sides.
That means, everytime you start or reload Dev Mode, you have to replace the old .gwt.rpc files deployed on your web server with the newly generated ones.
Or you point the Dev Mode war output directory to the web server context. And make sure the web server has auto-deploy turned on. So every time the files are changed by Dev Mode, the web server automatically reloads the files.

Based on what I see in com.google.gwt.user.rebind.rpc.ProxyCreator GWT generates the names of the serialization policy .gwt.rpc files by their content (md5).
So for some reason the serialization policy in the Super Dev Mode is different than the one generated during the normal build.
The following approach fixed the problem for me:
Open the serialization policy .gwt.rpc file generated for the regular build
Open the serialization policy .gwt.rpc file generated for the Super Dev Mode. You can find where it is by looking into the work directory printed at Super Dev Mode startup. E.g. in my case it was: "workDir: C:\Users\your_user\AppData\Local\Temp\gwt-codeserver-5658052675265790575.tmp"
Compare the 2 files - this could give you a pretty good hint regarding where the problem might be. In my case 2 unneeded types were getting added to the serialization policy and I could simply remove them from the project completely.
After fixing the discrepancies the .gwt.rpc files name should be identical again and the problem will be fixed :)

Related

How to give System Properties as Parameters in Ant JunitLauncher

I am trying to migrate my test suite from Junit4 to Junit5. Have a bunch of System Properties given as parameters in the older targets which run tests on Junit4 but now as i am migrating to Junit5, JunitLauncher doesn't support this parameter .
Older Target which runs tests on Junit4:
<target name="test">
<mkdir dir="${junit_reports.dir}" />
<junit printsummary="${junit.printsummary}" haltonfailure="${junit.haltonfailure}" haltonerror="${junit.haltonerror}" showoutput="${junit.showoutput}" fork="true" forkmode="once" failureProperty="failed">
<sysproperty key="clover.initstring" value="${clover.dbdir}/${clover.dbfile}" />
<sysproperty key="rules.location" value="${classes.dir}/rules/impl" />
<classpath>
<path refid="classes.classpath" />
<path refid="test.classpath" />
<pathelement path="${basedir}/../../.." />
<pathelement path="${test.classes.dir}" />
<path location="${basedir}/../common/target/test_classes" />
<pathelement location="${3rdparty.dir}/prime-server-framework/framework-core-mock.jar" />
</classpath>
<formatter type="${unittest.output.type}" />
<batchtest fork="true" todir="${junit_reports.dir}">
<fileset dir="${test.classes.dir}" includes="${tests.patternset}" />
</batchtest>
</junit>
</target>
New Target which runs tests on Junit5:
<target name = "sampletest">
<mkdir dir="${junit_reports.dir}" />
<junitlauncher>
<classpath>
<path refid="classes.classpath" />
<path refid="test.classpath" />
<pathelement path="${basedir}/../../.." />
<pathelement path="${test.classes.dir}" />
<path location="${basedir}/../common/target/test_classes" />
</classpath>
<!--<testclasses outputdir="${junit_reports.dir}">
<fileset dir="${test.classes.dir}">
<include name = "**/*Test.class"/>
</fileset>
</testclasses>-->
<test name = "impl.RulesEngineValidationTest"/>
</junitlauncher>
</target>
How do i give system properties in new target?
Ant 1.10.4 does support JUnit 5. However, it does not support all the features that Ant integration JUnit 4 does. In particular, it does not support forking the junit process and therefore passing system properties.
I found this question because I was trying to do the same thing. I found a workaround though. You can set the system properties in code before calling junitlauncher.
This code is what I used to set a single system property for file encoding. You could do something similar for your properties.
<script language="javascript">
<![CDATA[
var imports = new JavaImporter(java.lang.System);
imports.System.setProperty('file.encoding', 'ISO8859_1')
]]>
</script>
Yours is a little more complicated since your properties use others. You can read an Ant variable from inside the code. (I don't know how to read one with a dot in the name so I got rid of the dot in this example)
<property name="cloverdbdir" value="clover-dir-property-value" />
<property name="cloverdbfile" value="clover-db-file-property-value" />
<script language="javascript">
<![CDATA[
var imports = new JavaImporter(java.lang.System);
imports.System.setProperty('clover.initstring', cloverdbdir + '/' + cloverdbfile);
print(imports.System.getProperty('clover.initstring'));
]]>
</script>
There are a few things to be aware of if you use this technique:
Nashorn is deprecated for removal. It is definitely in Java 11. However, it isn't guaranteed to all future versions. It seems likely that Ant will add the system property functionality natively by then so I'm not worried about it.
The system property remains set for the remainder of the build. This doesn't look like a problem for you. If it is, you'd need another script block after calling JUnit to null it out.

How do I run a pitest ant script

I'm trying to create an ant script to run pitest to be able to automate my mutation testing. I am getting the error:
Could not find or load main class org.pitest.mutationtest.commandline.MutationCoverageReport
This is my MutationTest.xml ant script
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="mutationCoverage" name="PhoneBook">
<property name="ECLIPSE_HOME" value="C:/Program Files/eclipse/"/>
<path id="JUnit 4.libraryclasspath">
<pathelement location="${ECLIPSE_HOME}plugins/org.junit_4.11.0.v201303080030/junit.jar"/>
<pathelement location="${ECLIPSE_HOME}plugins/org.hamcrest.core_1.3.0.v201303031735.jar"/>
</path>
<path id="PhoneBook.classpath">
<pathelement location="bin"/>
<path refid="JUnit 4.libraryclasspath"/>
</path>
<path id="pit.path">
<pathelement location="lib/pitest-1.1.4.jar" />
<pathelement location="lib/pitest-ant-1.1.4.jar" />
</path>
<taskdef name="pitest" classname="org.pitest.ant.PitestTask" classpathref="pit.path" />
<target name="mutationCoverage">
<pitest
pitClasspath="PhoneBook.path"
classPath="PhoneBook.path"
targetClasses="pbook.*"
targetTests="pbook.*"
reportDir="MutationReports"
sourceDir="src"/>
</target>
</project>
What is causing this error, and how can I fix it?
Edit: I changed pitClasspath="PhoneBook.path" to pitClasspath="pit.path" and now I have a new error:
[pitest] Exception in thread "main" org.pitest.util.PitError: Unable to load class content for org.pitest.boot.HotSwapAgent
[pitest] Please copy and paste the information and the complete stacktrace below when reporting an issue
[pitest] VM : Java HotSpot(TM) 64-Bit Server VM
[pitest] Vendor : Oracle Corporation
[pitest] Version : 25.25-b02
[pitest] Uptime : 370
[pitest] Input ->
[pitest] BootClassPathSupported : true
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.classBytes(JarCreatingJarFinder.java:124)
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.addClass(JarCreatingJarFinder.java:113)
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.createJarFromClassPathResources(JarCreatingJarFinder.java:98)
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.createJar(JarCreatingJarFinder.java:74)
[pitest] at org.pitest.mutationtest.tooling.JarCreatingJarFinder.getJarLocation(JarCreatingJarFinder.java:63)
[pitest] at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:70)
[pitest] at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:43)
[pitest] at org.pitest.mutationtest.commandline.MutationCoverageReport.runReport(MutationCoverageReport.java:72)
[pitest] at org.pitest.mutationtest.commandline.MutationCoverageReport.main(MutationCoverageReport.java:43)
I don't know if that is better or worse, but hopefully it will be helpful in finding the problem.
A working example of a pitest ant build is provided at
https://github.com/hcoles/pitest-ant-example
I suggest you start with this and edit it until you have a working build for your codebase.
One difference I can see is that you have not included junit on the pitest path.
Your build looks a little strange as it seems to be tied to eclipse. If you are running from the IDE why not use the eclipse plugin?
Also, if you are not tied to Ant, you might want to consider maven as an alternative.
I believe much of your problem is that you're trying to use the Eclipse generated build.xml file, which doesn't contain the mutation testing target, and the target which you've added to remedy this has some errors.
I would suggest starting with the project here and attempting to understand how it works, and then changing their build.xml file to fit your needs.
However if this doesn't work, judging from your other question, the following build.xml should work if:
You divide your files into two source directories "src" and "test"
Both src and test folders contain the package "pbook"
You change the name of your tests to end in "Test" rather than begin in it
<?xml version="1.0" encoding="UTF-8"?>
<project name="Phonebook">
<property name="classOutputDir" value="build" />
<!-- classpath for pitest and any plugins -->
<path id="pitest.path">
<!-- must currently include the test library on the tool classpath. this will be fixed in a future version-->
<pathelement location="lib/junit-4.9.jar" />
<pathelement location="lib/pitest-0.33.jar" />
<pathelement location="lib/pitest-ant-0.33.jar" />
</path>
<taskdef name="pitest" classname="org.pitest.ant.PitestTask" classpathref="pitest.path" />
<target name="clean">
<delete dir="${classOutputDir}" />
</target>
<target name="compile" depends="clean">
<mkdir dir="${classOutputDir}/classes" />
<!-- Essential that line numbers and filenames are included in order for PIT to work -->
<javac srcdir="src" includeantruntime="false" debug="true" debuglevel="source,lines" destdir="${classOutputDir}/classes" />
</target>
<!-- classpath for compiling and testing the code. Note it does not include pitest and it's dependencies -->
<path id="test.path">
<pathelement location="${classOutputDir}/classes" />
<pathelement location="${classOutputDir}/test-classes" />
<pathelement location="lib/junit-4.9.jar" />
</path>
<target name="test" depends="compile">
<mkdir dir="${classOutputDir}/test-result" />
<mkdir dir="${classOutputDir}/test-classes" />
<javac includeantruntime="false" srcdir="test" destdir="${classOutputDir}/test-classes">
<classpath refid="test.path" />
</javac>
<junit>
<classpath refid="test.path" />
<batchtest todir="${classOutputDir}/test-result">
<!-- set test classes -->
<fileset dir="test">
<include name="**/*Test.java" />
</fileset>
<formatter type="xml" />
</batchtest>
</junit>
<junitreport todir="${classOutputDir}/test-result">
<fileset dir="${classOutputDir}/test-result">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${classOutputDir}/test-result/report" />
</junitreport>
</target>
<!-- run pitest. note that the filters for tests and classes refer to package/class names, not source file named -->
<target name="pit" depends="test">
<path id="mutation.path">
<path refid="pitest.path"/>
<path refid="test.path"/>
</path>
<pitest pitClasspath="pitest.path" threads="2" classPath="mutation.path" targetTests="pbook.*" targetClasses="pbook.*" reportDir="pitReports" sourceDir="src" />
</target>
</project>

Ant - build script does not find pathelement defined in a properties file

I have an ant build script that has the following targets:
<target name="_initLiveProps">
<property file="buildscripts/live.properties"/>
</target>
<target name="buildLive" depends="_initLiveProps">
<property file="buildscripts/live.properties"/>
</target>
Within the build script i have several pathelements declared as shown below:
<path id="project.class.path">
<pathelement location="./../lib/log4j-1.2.16.jar" />
<pathelement location="${product-def.jar}"/>
</path>
The product-def.jar definition is defined in the buildscripts/live.properties file as
product-def.jar=./../lib/product-def/live/product-def.jar
When i build the project (using ant buildLive) i get compilation errors and mainly because it cannot find classes defined within product-def.jar.
I tried to print out the classpath as shown below
<property name="myclasspath" refid="project.class.path"/>
<echo message="${myclasspath}" />
And the output comes out as c:\product\lib\log4j-1.2.16.jar;c:\product\${product-def.jar}
The above suggests that the following definition is not correct
<pathelement location="${product-def.jar}"/>
What is the correct way of defining a path element that is defined in a properties file?
Edit
I think the issue is that the definition for project.class.path is initialised before the properties file is loaded in the buildLive target.
Is there a way to delay the initialisation of project.class.path until after buildLive target has completed?
Is there a way to delay the initialisation of project.class.path until after buildLive target has completed?
Put the <path> definition inside the <target>
<target name="_initLiveProps">
<property file="buildscripts/live.properties"/>
<path id="project.class.path">
<pathelement location="./../lib/log4j-1.2.16.jar" />
<pathelement location="${product-def.jar}"/>
</path>
</target>
The <path> will be visible to all targets that depend (directly or indirectly) on this one.
If you have several different targets that load different properties, e.g. _initLiveProps, _initDevProps, etc. then you could put the <path> definition into a common target as follows
<target name="classpath">
<path id="project.class.path">
<pathelement location="./../lib/log4j-1.2.16.jar" />
<pathelement location="${product-def.jar}"/>
</path>
</target>
<target name="_loadLiveProps">
<property file="buildscripts/live.properties"/>
</target>
<target name="_initLiveProps" depends="_loadLiveProps, classpath" />
<target name="_loadDevProps">
<property file="buildscripts/dev.properties"/>
</target>
<target name="_initDevProps" depends="_loadDevProps, classpath" />

Compile GWT project with GWT project dependencies

I'd love to ask about my issue with ant script. I have two GWT projects and one depends on the other. I'm trying to compile them with ant script, but I'm failing due to:
[java] [ERROR] Errors in 'file:/$PATH/$CLASS_NAME.java'
[java] [ERROR] Line 29: No source code is available for type $INHERITED_INTERFACE; did you forget to inherit a required module?
while $INERITED_INTERFACE is from the library the compiled project depends on and $CLASS_NAME is a class that implements the interface.
I tried it simple, but it's not working:
<target name="gwtcomp" depends="javacomp" description="GWT to JS">
<echo message="Building GWT" />
<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
<classpath>
<pathelement location="${basedir}/src" />
<path refid="project.class.path" />
</classpath>
<jvmarg value="-Xmx512M" />
<arg value="-strict" />
<arg value="${project.dep.gwt.config}" />
<arg value="${project.gwt.config}" />
</java>
</target>
but it can't go pass the errors. I've also inherited the GWT library with:
<module rename-to='project'>
...
<inherits name='my.lib.common.Common'/>
</module>
Not really sure what's wrong. Common.gwt.xml is there and it points client and shared as source packages. Could anyone help with that?
I guess you have to add the location for the sources of your my.lib.common.Common library to your classpath in your ant script.
Something like this:
<classpath>
<pathelement location="${basedir}/src" />
<path refid="project.class.path" />
<pathelement location="LOCATION_TO_MY.LIB.COMMON.COMMON"/>
</classpath>

JSP compilation and Weblogic 10.3.4

We are in the process of upgrading from BEA Weblogic and ALSB to Oracle Weblogic and OSB 10.3.4. One of the things that are failing is our ant task for compiling jsp pages for our WAR.
This is the part of the ant build file that is failing now:
<!-- Compile the JSP files -->
<path id="workshop.classpath">
<fileset dir="${env.WL_HOME}/workshop/lib">
<include name="*.jar"/>
</fileset>
<pathelement location="${env.ORACLE_HOME}/tools/eclipse_pkgs/1.1/pkgs/eclipse/plugins/com.bea.workshop.wls.ant_1.0.20.200802230117/workshop-wls-antlib.jar"/>
</path>
<taskdef
name="jspc"
classname="com.bea.workshop.wls.antlib.tasks.JspcTask" classpathref="workshop.classpath"/>
<path id="jspc.classpath">
<path refid="java.classpath"/>
<pathelement location="${env.ORACLE_HOME}/jdk150_11/lib/tools.jar" />
<pathelement location="${env.WL_HOME}/server/lib/weblogic.jar" />
</path>
<jspc source="#{war.staging.dir}" classpathref="jspc.classpath" failonerror="true" />
It cannot resolve the jar file with JspcTask since Workshop does not exist in 10.3.4. So the question is, how should this ant script be changed to work under 10.3.4?
The taskdef with the classname below works with WLS 10.3.3
<taskdef name="jspc"
classname="weblogic.ant.taskdefs.j2ee.Jspc" classpath="{ORACLE_MIDDLEWARE_HOME}\wlserver_10.3\server\lib\weblogic.jar">
</taskdef>
Check your weblogic.jar with winzip/winrar to see if the above classname exists in 10.3.4, and it should be fine.
Update:
You're getting the NullPointer because jspc does not allow a directory in the source attribute. It should be srcdir as per the docs, in fact I dont see a source attribute at all.
The jspc task is deprecated, so I think it's better you use the weblogic.appc like below
<target name="compileapp">
<java classname="weblogic.appc" fork="yes">
<arg line="-webapp ${src.gui}" />
<arg value="-compiler javac" />
<arg line="-classpath D:\Oracle\Middleware_Jdev11_1_1_4\wlserver_10.3\server\lib\weblogic.jar" />
<arg value="-depend" />
<arg value="-nowarn" />
</java>
</target>
Choose the attributes you want from this list, I havent tried this myself yet.

Categories

Resources