WidgetSet compilation: my widgets not complied while external well.

As my goal was to integrate the RatingStars component, I’ve added the radingstars-1.2.jar, changed my gwt.xml file and I’m recompiling my widgetset with this script:


	<property name="compilationOutput" value="${java.io.tmpdir}/widgetset" />

	<target name="compile-widgetset">
		<mkdir dir="${compilationOutput}" />
		<java classname="com.google.gwt.dev.Compiler" failonerror="yes" fork="yes" maxmemory="600m">
	        <jvmarg value="-Xss8M" />
	        <jvmarg value="-Djava.awt.headless=true" />
			
			<arg value="-war" />
			<arg value="${compilationOutput}" />
			<arg value="blackbelt.ui.widgetset.BlackBeltWidgetset" />
			<classpath>
				<pathelement location="${basedir}/src/main/java" />
				<pathelement location="${basedir}/externallib/gwt-dev-windows.jar" />
				<pathelement location="${basedir}/externallib/gwt-user.jar" />
				<pathelement location="${basedir}/WebRoot/WEB-INF/lib/vaadin-6.2.3.jar" />
				<pathelement location="${basedir}/WebRoot/WEB-INF/lib/googleanalyticstracker-1.0.1.jar" />
				<pathelement location="${basedir}/WebRoot/WEB-INF/lib/ratingstars-1.2.jar" />
			</classpath>
		</java>
		<delete dir="${compilationOutput}/.gwt-tmp" includeemptydirs="true" />
	</target>

Everything is fine, and as you can see in the console output below, the RatingStars component has been compliled:


     [java]
 Compiling module blackbelt.ui.widgetset.BlackBeltWidgetset
     [java]
    Scanning for additional dependencies: jar:file:/C:/javadev/prj/JavaBlackBelt/WebRoot/WEB-INF/lib/vaadin-6.2.3.jar!/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java
     [java]
       Computing all possible rebind results for 'com.vaadin.terminal.gwt.client.WidgetMap'
     [java]
          Rebinding com.vaadin.terminal.gwt.client.WidgetMap
     [java]
             Invoking <generate-with class='com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator'/>
     [java]
                Detecting Vaadin components in classpath to generate WidgetMapImpl.java ...
     [java]
                Widget set will contain implementations for following components: 
     [java]
                	com.vaadin.ui.AbsoluteLayout
     [java]
                	com.vaadin.ui.Accordion
     [java]
                	com.vaadin.ui.Button
     [java]
                	com.vaadin.ui.CheckBox
     [java]
                	com.vaadin.ui.ComboBox
     [java]
                	com.vaadin.ui.CssLayout
     [java]
                	com.vaadin.ui.CustomComponent
     [java]
                	com.vaadin.ui.CustomLayout
     [java]
                	com.vaadin.ui.DateField
     [java]
                	com.vaadin.ui.Embedded
     [java]
                	com.vaadin.ui.Form
     [java]
                	com.vaadin.ui.FormLayout
     [java]
                	com.vaadin.ui.GridLayout
     [java]
                	com.vaadin.ui.HorizontalLayout
     [java]
                	com.vaadin.ui.Label
     [java]
                	com.vaadin.ui.Link
     [java]
                	com.vaadin.ui.ListSelect
     [java]
                	com.vaadin.ui.MenuBar
     [java]
                	com.vaadin.ui.NativeButton
     [java]
                	com.vaadin.ui.NativeSelect
     [java]
                	com.vaadin.ui.OptionGroup
     [java]
                	com.vaadin.ui.OrderedLayout
     [java]
                	com.vaadin.ui.Panel
     [java]
                	com.vaadin.ui.PopupView
     [java]
                	com.vaadin.ui.ProgressIndicator
     [java]
                	com.vaadin.ui.RichTextArea
     [java]
                	com.vaadin.ui.Select
     [java]
                	com.vaadin.ui.Slider
     [java]
                	com.vaadin.ui.SplitPanel
     [java]
                	com.vaadin.ui.TabSheet
     [java]
                	com.vaadin.ui.Table
     [java]
                	com.vaadin.ui.TextField
     [java]
                	com.vaadin.ui.Tree
     [java]
                	com.vaadin.ui.TwinColSelect
     [java]
                	com.vaadin.ui.Upload
     [java]
                	com.vaadin.ui.UriFragmentUtility
     [java]
                	com.vaadin.ui.VerticalLayout
     [java]
                	com.vaadin.ui.Window
     [java]
                	org.vaadin.googleanalytics.tracking.GoogleAnalyticsTracker
     [java]
                	org.vaadin.teemu.ratingstars.RatingStars
     [java]
                Done. (11seconds)
     [java]
    Compiling 6 permutations
     [java]
       Permutation compile succeeded
     [java]
    Linking into C:\Users\John\AppData\Local\Temp\widgetset
     [java]
       Link succeeded
     [java]
    Compilation succeeded -- 64,325s

The problem is that my components are not included anymore:

  • BlackBeltTextArea
  • Refresher

When I execute the application on the screen where they are supposed to be, I see the classic:


Widgetset does not contain implementation for blackbelt.ui.widgetset.BlackBeltTextArea. Check its @ClientWidget mapping, widgetsets GWT module descrioption file and re-compile your widgetset. Unrendered UIDL:
	blackbelt.ui.widgetset.BlackBeltTextArea(NO CLIENT IMPLEMENTATION FOUND)

The last time we have run the Ant compile script (weeks ago), my coworker thinks that he remembers it did not work better, also because our components not included. He gave up and could compile with the Eclipse plugin (instead of the Ant script).

I’d like to make the Ant script work again.

Note that in the Ant script, I tell to compile my WidgetSet:


			<arg value="blackbelt.ui.widgetset.BlackBeltWidgetset" />

Which is found in our src folder, added to the classpath:


				<pathelement location="${basedir}/src/main/java" />

BlackBeltWidgetset.gwt.xml:


<module>
 	<!-- Inherit super widgetset -->
	<inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />  
    <inherits name="org.vaadin.googleanalytics.tracking.widgetset.GoogleanalyticswidgetApplicationWidgetset" />
    <inherits name="org.vaadin.teemu.ratingstars.gwt.RatingStarsWidgetset" />
    
	<!-- Entry point -> not needed anymore ?    This would cause the double screen bug ?????? 
	<entry-point class="blackbelt.ui.widgetset.client.BlackBeltWidgetset"/>
	-->
</module>

Do you have any idea, why our components are not included in the compilation anymore (since Vaadin 6.2 ??) ?

Many thanks.

I’d like to add that my server-side class (in the same directory as my gwt.xml file) is annotated:


package blackbelt.ui.widgetset;

import...

@ClientWidget(VBlackBeltTextArea.class)
public class BlackBeltTextArea extends TextField {

Since 6.2, you shouldn’t need to mess with the gwt.xml file anymore. Instead, make sure that a) your server-side components are properly annotated and b) the build-script has access to the relevant classes. Check
this
for an example.

Hi!

gwt.xml file needs to be edited, but the task can be delegated to automatic helper that usually does the thing just fine. However, using it should not be necessary in your case. Do you have that server side class of the component also on GWT compilers class path?

Own entry points should not be needed anymore since 6.2, so you should remove that line.

cheers,
matti

Thanks for your suggestions, Risto.

If I omit this line in my gwt.xml file, the compiler does not find the RatingStars component:

    <inherits name="org.vaadin.teemu.ratingstars.gwt.RatingStarsWidgetset" />

According to what you say, it’s not normal. Maybe bound to the source of my problem?

This seems correct, see code from post above.

I guess it’s my problem. But when I remove this line from my ant file, it does not work at all

   <pathelement location="${basedir}/src/main/java" />

It makes me believe that GWT has access to my source code.
If I change the path to the src code, to the compiled code instead, then GWT compliler complains that my client.ui class is not found and the component will not be created.

   <pathelement location="${basedir}/WebRoot/WEB-INF/classes" />

Result (note the 2 warnings):


     [java]
 Compiling module blackbelt.ui.widgetset.BlackBeltWidgetset
     [java]
    Scanning for additional dependencies: jar:file:/C:/javadev/prj/JavaBlackBelt/WebRoot/WEB-INF/lib/vaadin-6.2.3.jar!/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java
     [java]
       Computing all possible rebind results for 'com.vaadin.terminal.gwt.client.WidgetMap'
     [java]
          Rebinding com.vaadin.terminal.gwt.client.WidgetMap
     [java]
             Invoking <generate-with class='com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator'/>
     [java]
                Detecting Vaadin components in classpath to generate WidgetMapImpl.java ...
     [java]
                [WARN]
 Widget class blackbelt.ui.widgetset.client.ui.VRefresher was not found. The component blackbelt.ui.widgetset.Refresher will not be included in the widgetset.
     [java]
                [WARN]
 Widget class blackbelt.ui.widgetset.client.ui.VBlackBeltTextArea was not found. The component blackbelt.ui.widgetset.BlackBeltTextArea will not be included in the widgetset.
     [java]
                Widget set will contain implementations for following components: 
     [java]
                	com.vaadin.ui.AbsoluteLayout
     [java]
                	com.vaadin.ui.Accordion
     [java]
                	com.vaadin.ui.Button
     [java]
                	com.vaadin.ui.CheckBox
     [java]
                	com.vaadin.ui.ComboBox
     [java]
                	com.vaadin.ui.CssLayout
     [java]
                	com.vaadin.ui.CustomComponent
     [java]
                	com.vaadin.ui.CustomLayout
     [java]
                	com.vaadin.ui.DateField
     [java]
                	com.vaadin.ui.Embedded
     [java]
                	com.vaadin.ui.Form
     [java]
                	com.vaadin.ui.FormLayout
     [java]
                	com.vaadin.ui.GridLayout
     [java]
                	com.vaadin.ui.HorizontalLayout
     [java]
                	com.vaadin.ui.Label
     [java]
                	com.vaadin.ui.Link
     [java]
                	com.vaadin.ui.ListSelect
     [java]
                	com.vaadin.ui.MenuBar
     [java]
                	com.vaadin.ui.NativeButton
     [java]
                	com.vaadin.ui.NativeSelect
     [java]
                	com.vaadin.ui.OptionGroup
     [java]
                	com.vaadin.ui.OrderedLayout
     [java]
                	com.vaadin.ui.Panel
     [java]
                	com.vaadin.ui.PopupView
     [java]
                	com.vaadin.ui.ProgressIndicator
     [java]
                	com.vaadin.ui.RichTextArea
     [java]
                	com.vaadin.ui.Select
     [java]
                	com.vaadin.ui.Slider
     [java]
                	com.vaadin.ui.SplitPanel
     [java]
                	com.vaadin.ui.TabSheet
     [java]
                	com.vaadin.ui.Table
     [java]
                	com.vaadin.ui.TextField
     [java]
                	com.vaadin.ui.Tree
     [java]
                	com.vaadin.ui.TwinColSelect
     [java]
                	com.vaadin.ui.Upload
     [java]
                	com.vaadin.ui.UriFragmentUtility
     [java]
                	com.vaadin.ui.VerticalLayout
     [java]
                	com.vaadin.ui.Window
     [java]
                	org.vaadin.googleanalytics.tracking.GoogleAnalyticsTracker
     [java]
                	org.vaadin.teemu.ratingstars.RatingStars
     [java]
                Done. (29seconds)
     [java]
    Compiling 6 permutations
     [java]
       Permutation compile succeeded
     [java]
    Linking into C:\Users\John\AppData\Local\Temp\widgetset
     [java]
       Link succeeded
     [java]
    Compilation succeeded -- 80,695s

Now, your remark gives me the idea of putting both:

  • compiled code directory
  • source code directory

in the classpath.
It’s logical: how could Vaadin detect annotation on source code?
And on the other hand, GWT needs the client.ui source code to compile to JavaScript.

and … it works now.

I just don’t understand:

  • where it is documented,
  • why hell it worked before.

That would be Book of Vaadin, chapter 10.8.4 Compiling GWT Widget Sets

The mapping was previously done runtime using the old “tags” which needed to be specified for each component. As of 6.2.0 the mapping is generated compile time based on the @ClientWidget annotations (from the .class files)

Thank you Matti for the solution, we were writing out post simultaneously.
Thank you Artur for this clear explanation.

So, next time I want to use an extenal component with client-side widget, I need to:

  • add the jar in WEB-INF/lib
  • add an line in the gwt.xml file
  • recompile wy widgetset

Note: if I omit modifying the gwt.xml file from my working situation, the compiler does not fine the component anymore.

Running the class com.vaadin.terminal.gwt.widgetsetutils.WidgetSetBuilder before the GWT compiler (with the same classpath as the GWT compiler) should update an already existing widgetset, adding/removing any required “inherits” statements.

If there no widgetset is found, one is created in the first directory (not JAR) on the classpath, so in this case having the project source directory first is a good idea.

Oh, interesting Henri, thank you.

Let’s recap: when I want to use a component from the add-on repository, I just

  • download the jar and put it in my WEB-INF/lib directory
  • run my Ant script (that will first create the gwt.xml file for my widgetset, then start the gwt compiler)

Here is my full Ant build file, in case a reader needs it in a few weeks/months (don’t think the documentation one does everything I do):


<?xml version="1.0" encoding="UTF-8"?>

<project name="Widgetset Compiler" default="update-widgetset" basedir=".">
	<!--
		To build client side GWT code into GWT compiled javascript (for our
		own Vaadin widgets)
	-->
	
	<property name="compilationOutput" value="${java.io.tmpdir}/widgetset" />

	<target name="compile-widgetset">
		<!-- Construct and check classpath -->
		<!-- Includes paths required for both server and client-side compilation -->
		<path id="compile.classpath">
			<pathelement location="${basedir}/src/main/java" />
			<pathelement location="${basedir}/WebRoot/WEB-INF/classes" />
			<pathelement location="${basedir}/externallib/gwt-dev.jar" />
			<pathelement location="${basedir}/externallib/gwt-user.jar" />
		    <fileset dir="${basedir}/WebRoot/WEB-INF/lib/">   <!-- vaadin-x.x.x.jar, RatingStars.jar, GoogleAnalyticsTracker.jar -->
		    	<include name="**/*.jar"/>
		    </fileset>
		</path>
		
        <!-- Create the *.gwt.xml files -->	
		<java classname="com.vaadin.terminal.gwt.widgetsetutils.WidgetSetBuilder" failonerror="yes" fork="yes" maxmemory="600m">
	        <jvmarg value="-Xss8M" />
	        <jvmarg value="-Djava.awt.headless=true" />
			<arg value="blackbelt.ui.widgetset.BlackBeltWidgetset" />
			<classpath>
				 <path refid="compile.classpath"/>
			</classpath>
		</java>

		
		<mkdir dir="${compilationOutput}" />

		<!-- Starts GWT compiler -->
		<java classname="com.google.gwt.dev.Compiler" failonerror="yes" fork="yes" maxmemory="600m">
	        <jvmarg value="-Xss8M" />
	        <jvmarg value="-Djava.awt.headless=true" />
			
			<arg value="-war" />
			<arg value="${compilationOutput}" />
			<arg value="blackbelt.ui.widgetset.BlackBeltWidgetset" />
			<classpath>
				 <path refid="compile.classpath"/>
			</classpath>
		</java>
		<delete dir="${compilationOutput}/.gwt-tmp" includeemptydirs="true" />
	</target>

	

	<!-- We need to play with the directories in order to not make SVN miserabily fail -->
	<target name="update-widgetset"   depends="compile-widgetset" >
		<!-- delete old widgetset files -->
		<delete includeemptydirs="true" failonerror="false">
			<fileset dir="./WebRoot/VAADIN/widgetsets/blackbelt.ui.widgetset.BlackBeltWidgetset"
				includes="**/*" excludes=".svn" />
		</delete>
		<!-- copy new widgetset files -->
		<copy todir="./WebRoot/VAADIN/widgetsets">
			<fileset dir="${compilationOutput}">
				<include name="**/*" />
				<exclude name="**/.*" />
			</fileset>
		</copy>
	</target>

</project>