OSGI enabled Vaadin war

Hi,

Thanks for the great series of tutorials on creating modular Vaadin applications.

I followed the tutorials, with the following consequences:

  1. The vaadin 6.1.0 developmental version included in the source code has issues getting deployed in Glashfish v3.
    — I solved this by using the version vaadin-6.2.0.nightly-20091112-c9764.jar on the nightly builds.
  2. However, the examples (and my own application will not work). I am not sure how to resolve this issue because both vaadin and the example jars and wars show up as ACTIVE in Felix .

[ 215]
[Active ]
[ 1]
JSP caching taglib connector module (3.0.0.SNAPSHOT)
[ 216]
[Active ]
[ 1]
Apache Felix Declarative Services (1.0.8)
[ 217]
[Active ]
[ 1]
GlassFish Web Container (rfc #66) for OSGi Enabled Web Applications (3.0.0.SNAPSHOT)
[ 219]
[Active ]
[ 1]
OSGi HTTP Service Implementation for GlassFish Web Container (3.0.0.b72)
[ 220]
[Installed ]
[ 1]
Sun Java EE Engine (3.0.0.b72)
[ 221]
[Active ]
[ 1]
Admin Console Web Container Plugin localization (3.0.0.b70)
[ 224]
[Active ]
[ 1]
Vaadin (6.2.0.nightly-20091112-c9764)
[ 225]
[Active ]
[ 1]
Module Demo module 1 (1.0.0)
[ 226]
[Active ]
[ 1]
Module Demo module manager (1.0.0)
[ 227]
[Active ]
[ 1]
Module Demo module 2 (1.0.0)

When I then go to http://localhost:8080/moduledemo, Glassfish returns a 404 error.

Any pointers on what I am doing wrong? Btw, I am not using Glassfish Prelude, I am using the latest build from http://download.java.net/glassfish/v3/nightly/latest-glassfish.zip

I am going to retry the same with the promoted builds (b72) of glassfish and see if that helps matters…

Cheers,
Jay

I got this to the example to work by deploying the war file to the {glassfish-installation-dir}/glassfish/domains/domain1/autodeploy directory. Sorry missed this bit in my previous experiments and was creating a WAB (war osgi bundle) and was deploying the WAB into the {glassfish-installation-dir}/glassfish/domains/domain1/autodeploy/bundles directly.

Having now managed to solve the initial hiccups, I have now succesfully deployed the examples shown in the OSGI series on Glasshfish 3 (b72) and vaadin 6.2.0.nightly-20091112-c9764.

I have since tried to recreate the example from the maven archetype for vaadin 6.2. I have had some complaints in the ColorPickerWidgetSet class where I had to change both the overriden methods to include ApplicationConfiguration as one of the parameters. This was easy enough to fix it seemed. I then was forced to fix the getTag() method in the ColorPicker class which I did not find any way around unless I commented it out, which I did.

Now, when I run the example, I do not see a Color Picker widget. Instead I see a tree which starts like Client faced an unknown component type. Unrendered UIDL: I am attaching a screenshot for more info…

Appreciate any hints from the Vaadin gurus and developers on here, bearing in mind that I am using Vaadin 6.2 nightly…

Many thanks,
J
11121.png

With the 6.2 nightlies, I get those errors when I’m missing the init-param for the widget set in my web.xml

Hi Jean,

Thanks for the hint. Unfortunately, it did not solve my problem… :frowning:

Since I creating an OSGI enabled war, I can not use the web.xml to initialise any parameters. I am using a static servlet class to initialise the parameters as shown below:

@WebServlet(urlPatterns="/*")
public static class Servlet extends AbstractApplicationServlet {
	
	ColorPicker colorPicker = new ColorPicker();
	@Resource(mappedName="widgetService")
	WidgetService moduleService;

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

	@Override
	protected Application getNewApplication(HttpServletRequest request)
			throws ServletException {
		return new ModuleDemoApp(moduleService, colorPicker);
	}
	
}

Hmmm… not sure where else I am going wrong!

Cheers,
J

The way the mapping between client side widget and server side component has been changed in the 6.2 nightly versions. Previously a tag was used on both server and client side to map the server side class to the client side widget class and a widgetset java class was used to create instances of the client side widgets based on the tags.

Now this is handled automatically by Vaadin and instead of tags + a widgetset java class you only need to add a @ClientWidget annotation to the server class which maps to the widget class. So to get the ColorPicket to work you should remove the getTag method, remove the ColorPicketWidgetSet.java and add @ClientWidget(VColorPicker.class) to the ColorPicket class.

For more info see: http://dev.vaadin.com/wiki/WidgetSetRefactoring092009

Artur,

I made the changes you suggested. I deleted the ColorPickerWidgetSet.java class and added the annotation @ClientWidget(VColorPicker.class) on the ColorPicker.java class.

The war does deploy in Glassfish successfully, however, I get an Internal error (screenshot attached). Any suggestions where I am going wrong?

Cheers,
J

My class implementation looks like below:

public class ModuleDemoApp extends Application implements WidgetServiceListener {

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

// ColorPicker colorPicker = new ColorPicker();
@Resource(mappedName=“widgetService”)
WidgetService moduleService;

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

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

private WidgetService moduleService;

private TabSheet tabs;
/* The custom component. */
private ColorPicker colorselector;

/* Another component. */
private Label colorname;

/* Main window */
private Window main;

public ModuleDemoApp(WidgetService moduleService) {
	this.moduleService = moduleService;

// this.colorselector = colorPicker;
}

@Override
public void init() {
	
	// create components
	main = new Window("Modular Demo Application");
	colorselector = new ColorPicker();
	
    // Listen for value change events in the custom component,
    // triggered when user clicks a button to select another color.
    colorselector.addListener(new ValueChangeListener() {
        public void valueChange(ValueChangeEvent event) {
            // Provide some server-side feedback
            colorname.setValue("Selected color: "
                    + colorselector.getColor());
        }
    });
    main.addComponent(colorselector);

    // Add another component to give feedback from server-side code
    colorname = new Label("Selected color: " + colorselector.getColor());
    main.addComponent(colorname);

    // Server-side manipulation of the component state
    final Button button = new Button("Set to white");
    button.addListener(new Button.ClickListener() {
        public void buttonClick(ClickEvent event) {
            colorselector.setColor("white");
        }
    });
    main.addComponent(button);
    
    setTheme("mytheme");
	
	tabs = new TabSheet();
	tabs.setSizeFull();
	
	for (Widget module : moduleService.getWidgets()) {
		tabs.addTab(module.getComponent(), module.getName(), null);
	}

// setMainWindow(new Window(“Module Demo Application”, tabs));
setMainWindow(main);

	System.out.println("ModuleDemoApp: Application initializing, adding module service listener");
	moduleService.addListener(this);
}

@Override
public void close() {
	System.out.println("ModuleDemoApp: Application closing, removing module service listener");
	moduleService.removeListener(this);
	super.close();
}

public void moduleRegistered(WidgetService source, Widget module) {
	System.out.println("ModuleDemoApp: Module registered, adding tab");
	tabs.addTab(module.getComponent(), module.getName(), null);
}

public void moduleUnregistered(WidgetService source, Widget module) {
	System.out.println("ModuleDemoApp: Module unregistered, removing tab");
	tabs.removeComponent(module.getComponent());
}

11122.png

Hard to say from the code but an internal error is shown to the user when something throws an exception in the server side during the handling of a request. So you should have the exception+stacktrace in the server logs and this will hopefully help you find the cause of the problem.

I confess it was a little sloppy of me to just report an Internal error and not look at the logs… (been trying to get this darned thing to behave for a few days now… :D)

Turns out the error was being reported because GWT was not included… fixed that now but the original error still remains…which is a garbled component that reads :

Client faced an unknown component type. Unrendered UIDL:
com.vaadin.terminal.gwt.client.ui.VUnknownComponent id=PID14

I posted an attachment of the same in my earlier post… Any more ideas please? :slight_smile:

Cheers,
J

Looks like you are have created a custom widgetset, but is not deployed or used for some reason. Have you selected the custom widgetset in web.xml? Can it be found in the server?

May I suggest you try to deploy your application outside OSGi and see if the problem persists? That way we could narrow down the area of possible causes. Due to the class loading mechanism of OSGi, it is highly likely that not all parts of the current Vaadin library can be deployed in OSGi without problems.

Btw, you mentioned that the Vaadin library included in the module demo source code had issues getting deployed. I have not been able to reproduce this problem, what kind of issues are we talking about?

-Petter-

Hi,
I just migrated to the last nightly build (because of an issue with notifications that would not auto-wrap). However, during compiling of my code (which compiled with no errors with Vaadin 6.1.4), i get an error, saying that i try to override the getTag() method which is declared final now…

I’ve read something about adding the @ClientWidget annotation somewhere, but i don’t really understand where i should do that.

Here is my code that causes the compile-error:
(it’s a field with a certain amount of checkboxes (defined @ runtime), that fills a collection of Capabilities (which is an entity that i defined), belonging to a Usergroup (which is another entity containing a foreign key to a set of Capabilities)).


public class CapabilityCollectionField extends AbstractField {
    Vector capVector = new Vector();
    VerticalLayout layout = new VerticalLayout();
    Collection<CapabilityGroup> capGroups;
    ArrayList checkBoxes = new ArrayList();
    
    public CapabilityCollectionField(Collection<CapabilityGroup> capGroups) {
        super();
        this.capGroups = capGroups;
        layout.setMargin(true);
        layout.setSpacing(true);
        Iterator<CapabilityGroup> it = capGroups.iterator();
        while(it.hasNext()) {
            CapabilityGroup capGroup = it.next();
            layout.addComponent(new Label("<b>" + capGroup.getName() + "</b>",Label.CONTENT_XHTML));
            List<Capability> capGroupList = lookupCapabilityConfiguration().getCapabilitiesByGroupId(capGroup);
            Iterator<Capability> it2 = capGroupList.iterator();
            while(it2.hasNext()) {
                Capability cap = it2.next();
                CheckBox capCheck = new CheckBox(cap.getDescription(), new ClickListener() {
                    public void buttonClick(ClickEvent event) {
                        boolean ena = (Boolean)event.getButton().getValue();
                        Capability c = (Capability)event.getButton().getData();
                        if(ena) {
                            capVector.add(c);
                        } else {
                            capVector.remove(c);
                        }
                    }
                });
                capCheck.setData(cap);
                capCheck.setValue(capVector.contains(cap));
                checkBoxes.add(capCheck);
                layout.addComponent(capCheck);
            }
        }
    }


    @Override
    public void paintContent(PaintTarget target) throws PaintException {
        layout.paintContent(target);
    }

    @Override
    public Class getType() {
        return Collection.class;
    }

    @Override
    public String getTag() {
        return layout.getTag();
    }

    @Override
    public void setPropertyDataSource(Property newDataSource) {
        this.capVector = (Vector)newDataSource.getValue();
        if(this.capVector == null) {
            this.capVector = new Vector();
            newDataSource.setValue(this.capVector);
        }
        updateCheckBoxes();
    }

    @Override
    public Object getValue() {
        return capVector;
    }

    private void updateCheckBoxes() {
        Iterator<CheckBox> it = checkBoxes.iterator();
        while(it.hasNext()) {
            CheckBox capCheck = it.next();
            capCheck.setValue(capVector.contains(capCheck.getData()));
        }
        requestRepaint();
    }

    private CapabilityConfiguration lookupCapabilityConfiguration() {
        try {
            Context c = new InitialContext();
            return (CapabilityConfiguration) c.lookup("java:comp/env/CapabilityConfiguration");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    


}

Vaadin 6.2 will include a simpler widgetset packaging system (that does not need getTag anymore). Documentation is still under construction, but here are couple of pointers:


http://dev.vaadin.com/wiki/WidgetSetRefactoring092009


http://dev.vaadin.com/raw-attachment/wiki/WidgetSetRefactoring092009/new%20widgetsets.pdf

But these documents all talk about a server-side and a client-side component. I don’t really see that distinction in my code for the CapabilityCollectionField class. Or should i rewrite the complete component and not extending it anymore from AbstractField?

You have previously been using AbstractField as the server-side extension point, but VerticalLayout on the client-side (as you return layout.getTag() as the tag for your component).

I’d say you’d be fine just extending VerticalLayout on the server-side as well, but that would prevent you from using it in any forms (unless you implement the Field interface: loads of methods, not a pretty option).

So I guess you’re left with trying to add @ClientWidget(VVerticalLayout.class) before public class CapabilityCollectionField , and see what happens.

Thanks for the quick response!
I’ve tried to leave out the getTag() method and put @ClientWidget(VVerticalLayout.class) in front of the class definition, but still no luck…

When displaying the CapabilityCollectionField component, i get an error:

Client faced an unknown component type. Unrendered UIDL:
com.vaadin.terminal.gwt.client.ui.VUnknownComponent id=PID57 margins=15 spacing=true alignments={} expandRatios={}
com.vaadin.terminal.gwt.client.ui.VLabel id=PID58 width=100.0% mode=xhtml

Am i correct that displaying the first label inside the vertical layout gives the error? So adding only ClientWidget(VVerticalLayout.class) is not enough, but i should somehow also be able to add VLabel.class and VCheckBox.class…

Any suggestions?

p.s. you were correct in you assumption that i need to be able to use the CapabilityCollectionField in a form, so extending it from VerticalLayout is not an option…

Did you recompile the widgetset?

It is now required when making changes to the mapping between client and server side components (the @ClientWidget annotation). A GWT generator included in Vaadin 6.2 creates the client-side part of the mapping at widgetset compile time based on the annotations.

If you are using the latest
development version
of the Eclipse plugin with Vaadin 6.2, you can simply click the “Compile widgetset” button in the toolbar to achieve this.

I don’t think that should be necessary because i’m using a standard client side module (VVerticalLayout.class) to which i didn’t change anything, so i don’t think it’s necessary to recompile that. I’m just trying to link the standard VVerticalLayout as a client-side component to my own CapabilityCollectionField on the server-side…

Or am i seeing things wrong?

p.s. we are not working in Eclipse, but in NetBeans…