custom widget under glassfish v3

Hi, is there anyone that has experience with deploying custom widgets on glassfish v3 (using netbeans 6.8) ? My app is deployed, but the custom widget is not shown, instead i get following text:
"Widgetset does not contain implementation for com.excentis.monitoring.gui.components.selectfromsearch.SelectFromSearch. Check its @ClientWidget mapping, widgetsets GWT module descrioption file and re-compile your widgetset. Unrendered UIDL:

com.excentis.monitoring.gui.components.selectfromsearch.SelectFromSearch(NO CLIENT IMPLEMENTATION FOUND)"

The widgetset is compiled ‘by hand’ using ant and an adjusted build-widgetset.xml

In my war i deploy i have

  • the VAADIN/widgetsets/ folder that includes the output of the widget compiler (a folder called com.excentis.monitoring.gui.components.selectfromsearch.gwt.SelectFromSearchWidgetSet with in it the javascript code and some other stuff)
  • the WEB-INF folder with in it:
    • the classes folder with the compiled classes (server-side and client-side)
    • the lib folder with the vaadin-6.2.5.jar and selectfromsearch.jar that i made using the adjusted build-widgetset.xml
    • the src folder with the src code for client and server side and also the SelectFromSearchWidgetSet.gwt.xml that just contains:

 <module>
	<!-- WS Compiler: manually edited  -->

	<!-- Inherit DefaultWidgetSet -->
	<inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" /> 
	
	
	<!-- WidgetSet default theme -->	
	<stylesheet src="selectfromsearch/styles.css"/>

</module>

the web.xml file contains following:


 <servlet>
        <servlet-name>HelloVaadin</servlet-name>
        <servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
        <init-param>
            <param-name>application</param-name>
            <param-value>com.excentis.helloVaadin.HelloVaadin</param-value>
        </init-param>
        <init-param>
            <description>Application widgetset</description>
            <param-name>widgetset</param-name>
            <param-value>com.excentis.monitoring.gui.components.selectfromsearch.gwt.SelectFromSearchWidgetSet</param-value>
        </init-param>
    </servlet>

Anyone an idea on why the widget does not find the client implementation?
To me it appears as if the application is just using the default widget set, instead of the one that is described in the init-param in the web.xml file, but i don’t know why it is doing that…

Regards,
Jan

Two things to check: correctness of the widgetset and caching.

First check (e.g. by looking at the application HTML source code) if the application is using the correct widgetset.

If it is, check carefully the widgetset compilation output. One possible culprit could be the package structure - GWT assumes by default that client side classes are within a “client” subpackage of the package containing the widgetset GWT module file. However, based on your comments elsewhere, the widgetset compilation seems not to have problems.

If the browser is using DefaultWidgetSet instead of your own:

I would suspect caching of some files (by the server or by the browser) could be behind the problem, resulting perhaps in that your updated web.xml (the widgetset parameter) is not used.

This could be tested by undeploying the application, restarting the server, clearing the browser cache and cookies for that domain and redeploying the application.

Another possible reason could be a typo in your web.xml where you declare the widgetset to use, but I did not spot one.

I did not have any issues with compiling the widget, however, the gwt module file is not where you say that it should be. Let me try and picture the package (~folder) structure for you:

  • client side:
    WEB-INF/src/com/vaadin/terminal/gwt/client/ui/VSelectFromSearch.java
  • server side:
    WEB-INF/src/com/excentis/monitoring/gui/components/selectfromsearch/SelectFromSearch.java
    WEB-INF/src/com/excentis/monitoring/gui/components/selectfromsearch/gwt/SelectFromSearchWidgetSet.gwt.xml
    WEB-INF/src/com/excentis/monitoring/gui/components/selectfromsearch/gwt/public/selectfromsearch/styles.css

Maybe it’s best to include the build-widgetset.xml also:


<?xml version="1.0"?>

<!-- 

Client-side code is compiled by using GWTCompiler which compiles client-side Java code into
JavaScript. Generated files are located under WebContent/VAADIN/widgetsets/*.

Client-side compilation is required if you create new or modify existing widgets.
You may use either this script or Vaadin Hosted Mode Browser.launch (in Eclipse)
to compile your client-side java code. 

By default Vaadin first tries to serve widgetset resources from the file system, if that
fails then files are streamed from vaadin-6.2.5.jar. 

See configure target to adjust this buildfile.

-->

<project name="Widgetset compile SelectFromSearch" basedir="." default="compile-widgetset">

	<!-- 
		Update based on your project structure, by default this buildfile assumes that you 
		1. use WebContent under your project's root directory
		2. WebContent/WEB-INF/lib/vaadin-6.2.5.jar exists
		3. WebContent/WEB-INF/src contains your project source files
		4. gwt directory contains extracted GWT distribution for your platform (windows, linux or mac)
	-->
	<target name="configure">
		
		<!-- Path from this file to the project root -->
		<property name="base"
			      value="./" />
		
		<!-- The platform (windows, linux, mac, or oophm) -->
		<property name="gwt-platform"
			      value="windows" />
		
		<!-- Location of platform-specific GWT distribution -->
		<property name="gwt-location"
			      value="${base}gwt" />
		
		<!-- Location of Vaadin JAR -->
		<property name="toolkit-jar-location"
			      value="${base}web/WEB-INF/lib/vaadin-6.2.5.jar" />
		
		<!-- Location of project source code -->
		<property name="src-location"
			      value="${base}web/WEB-INF/src" />

		<!-- Target where to compile server-side classes -->
		<property name="server-side-destination"
			      value="${base}web/WEB-INF/classes"/>
		
		<!-- Target where to compile the widget set -->
		<property name="client-side-destination"
			      value="${base}web/VAADIN/widgetsets" />
	</target>
		
    <!-- NOTE: Modify this example to compile your own widgetset -->
    <target name="configure-widgetset">
        <echo>Modify this example Ant script to compile your own widget sets.</echo>

        <!-- Name of the widget set -->
        <property name="widgetset" value="com.excentis.monitoring.gui.components.selectfromsearch.gwt.SelectFromSearchWidgetSet"/>

        <!-- Define if the widget set be generated automatically -->
        <!-- from all widget sets included in the class path.    -->
        <property name="generate.widgetset" value="1"/>    
        
        <!-- Path to the widgetset directory. Required only for -->
        <!-- generated widget sets. Must be relative to         -->
    	<!-- $src-location, that is, under the first entry in   -->
    	<!--  class path.                                       -->
        <property name="widgetset-path" value="com/excentis/monitoring/gui/components/selectfromsearch/gwt"/>
    </target>

    <!-- Note: Modify this example to compile your own widgetset Jar. -->
    <target name="configure-jar">
        <!-- The compiled JAR name -->
        <property name="jar-destination" value="${base}selectfromsearch.jar"/>

        <!-- Title of the widget set (for JAR) -->
        <property name="widgetset-title" value="SelectFromSearch"/>
        
        <!-- Version of the widget set (for JAR) -->
        <property name="widgetset-version" value="1.0"/>
        
        <!-- Vendor of the widget set (for JAR) -->
        <property name="widgetset-vendor" value="Excentis NV"/>
    </target>
	
	<!-- ================================================== -->
	<!-- Build Targets                                      -->
    <!-- ================================================== -->
	
	<target name="init" depends="configure">

		<echo>Configured for ${gwt-platform} platform.</echo>
		<echo>Requirements for classpath:</echo>
		<echo>  ${gwt-location}/gwt-dev-${gwt-platform}.jar</echo>
		<echo>  ${gwt-location}/gwt-user.jar</echo>
		<echo>  ${toolkit-jar-location}</echo>
		<echo>  ${src-location}</echo>
		<echo>Output will be written into ${client-side-destination}</echo>

		<!-- Check that files exist -->
		<fail message="Some of the required files (listed above) are missing.">
			<condition><not><resourcecount count="3">
				<filelist files="${gwt-location}/gwt-dev-${gwt-platform}.jar,${gwt-location}/gwt-user.jar,${toolkit-jar-location}"/>
			</resourcecount></not></condition>
		</fail>

		<!-- Construct and check classpath -->
		<!-- Includes paths required for both server and client-side compilation -->
		<path id="compile.classpath">
			<!-- The source location must be first, as required by generate-widgetset. -->
            <pathelement path="${src-location}" />
			<pathelement path="${server-side-destination}" />
			<pathelement path="${toolkit-jar-location}" />
			<pathelement path="${gwt-location}/gwt-user.jar" />
			<pathelement path="${gwt-location}/gwt-dev-${gwt-platform}.jar" />
		    <fileset dir="${base}web/WEB-INF/lib/">
		    	<include name="**/*.jar"/>
		     </fileset>
		</path>
	</target>

	<!-- Compiled server-side components are needed for building the client-side -->
	<target name="compile-server-side" depends="init">
		<javac srcdir="${src-location}" destdir="${server-side-destination}">
			<compilerarg value="-g"/>
			<classpath>
				<path refid="compile.classpath"/>
			</classpath>
		</javac>
	</target>

    <!-- Generates a combined widget set from all widget    -->
    <!-- sets in the class path, including project sources. -->
    <!-- Updates the configuration if it already exists.    -->
    <target name="generate-widgetset"
            depends="compile-server-side, configure-widgetset"
            if="generate.widgetset">
        
        <!-- Create the directory if it does not already exist. -->
        <mkdir dir="${src-location}/${widgetset-path}"/>
        
        <java classname="com.vaadin.terminal.gwt.widgetsetutils.WidgetSetBuilder"
              failonerror="yes" fork="yes" maxmemory="256m">
            <arg value="${widgetset}"/>
            <jvmarg value="-Xss1024k"/>
            <jvmarg value="-Djava.awt.headless=true"/>
            <classpath>
                <path refid="compile.classpath"/>
            </classpath>
        </java>
    </target>

	<!-- Build the widget set. -->
	<target name="compile-widgetset"
            depends="compile-server-side, generate-widgetset">
		<echo>Compiling ${widgetset}...</echo>
		
		<java classname="com.google.gwt.dev.Compiler"
			  failonerror="yes" fork="yes" maxmemory="256m">
			<arg value="-war" />
			<arg value="${client-side-destination}" />
			<arg value="${widgetset}" />
            <jvmarg value="-Xss1024k"/>
            <jvmarg value="-Djava.awt.headless=true"/>
			<classpath>
				<path refid="compile.classpath"/>
			</classpath>
		</java>
	</target>

    <!-- Build JAR -->
    <target name="package-jar"
            depends="init, configure-widgetset, configure-jar">
        <jar jarfile="${jar-destination}" compress="true">
            <manifest>
                <attribute name="Vaadin-Package-Version" value="1" />
                <attribute name="Vaadin-Widgetsets" value="${widgetset}" />
                <attribute name="Implementation-Title" value="${widgetset-title}" />
                <attribute name="Implementation-Version" value="${widgetset-version}" />
                <attribute name="Implementation-Vendor" value="${widgetset-vendor}" />
                
                <!-- The following are Vaadin-specific. -->
                <attribute name="Vaadin-License-Title" value="Apache2" />
                <attribute name="Vaadin-License-File" value="http://www.apache.org/licenses/LICENSE-2.0" />
            </manifest>
            
            <!-- The built server-side classes are here. -->
            <fileset dir="${server-side-destination}">
                <patternset>
                    <include name="**/*" />
                </patternset>
            </fileset>

            <!-- Especially all the widget set source files are required. -->
            <fileset dir="${src-location}">
                <patternset>
                    <include name="**/*" />
                </patternset>
            </fileset>
        </jar>
    </target>
</project>

i’ve tried and redeploy while clearing the browser cache, but helas, no succes…

if i look to the html-source code when the application is loaded, i see:


document.write("<script language='javascript' src='/HelloVaadin-war/VAADIN/widgetsets/com.vaadin.terminal.gwt.DefaultWidgetSet/com.vaadin.terminal.gwt.DefaultWidgetSet.nocache.js?1268917702296'><\/script>");
}

so i still think that the defaultwidgetset is loaded instead of mine…

Normally, you would have your VSelectFromSearch under the package of your own widgetset, in this case in WEB-INF/src/com/excentis/monitoring/gui/components/selectfromsearch/gwt/client/VSelectFromSearch.java . However, I believe it is also found correctly from under the Vaadin standard widget path.

Yes, the default widgetset is clearly loaded instead of yours. Unless there is some error in web.xml, it seems AbstractApplicationServlet.getApplicationProperty() might be misbehaving in your environment.

If nothing else helps, you could try to put a breakpoint in it. If that is indeed the culprit, you could create a problem report in
our trac
with more details about the environment in which you see the problem, and use your own subclass of AbstractApplicationServlet as a temporary workaround.

Very good suggestion!!!

It was indeed the AbstractApplicationServlet class that could not get the correct application property (‘widgetset’).
I’ve overwritten the getApplicationProperty(String parameterName)-method and then it works under glassfish v3…

To got any Vaadin-app working under glassfish v3, i had allready written the following (something i also found on this forum i think):


public class HelloVaadin extends Application {

    @WebServlet(urlPatterns="/*")
    public static class Servlet extends AbstractApplicationServlet {

        @Override
        protected Class<? extends Application> getApplicationClass() {
            return HelloVaadin.class;
        }

        @Override
        protected Application getNewApplication(HttpServletRequest request) throws ServletException {
            return new HelloVaadin();
        }

    }

    @Override
    public void init() {
        Window mainWindow = new Window("Hello World Application");
        Label label = new Label("Greetings, Vaadin user!");
       .....
    }

}

So now i also overwrote the getApplicationProperty(String parameterName)-method in the Servlet-class.

I’m not sure what i should add on Trac?

Regards and thanks!!!

Jan

When you are using this approach to configuring the servlet, you should also set the init parameters with annotations. With this approach, you should not need any web.xml file unless it is not necessary to configure other servlets.


@WebServlet(urlPatterns="/*", initParams = { @InitParam(name="widgetset", value="mywidgetset") })
public static class Servlet extends AbstractApplicationServlet {

If I remember correctly, if you do want to override something with a web.xml file, you should give the “name” parameter to @WebServlet and use the matching name in your web.xml .

EDIT: corrected name of @WebServlet parameter.