Steal UI components, between UIs or sessions

:slight_smile: Hi
It’s sometime now I know of Vaadin and I tell you: It was love at first sight!

I’m playing a bit with Vaadin. Right now I’m looking at the darkest winding of it. :vader:

The last of it is: what if my client machine crashes, or my client browser closes by mistake or crash?
I (apparently) lose my work, my vaadin UI/session state.
So I put together a (simplistic) vaadin UI that does steal a component from a different UI; with all actual state.

And It works! (quite)
Even between my desktop-browser and android-mobile-browser

First of all: is there a best practice to do it?
Some page to read out?

Something is already working, under the vaadin hood (I’m thinking on annotation @PreserveOnRefresh)

My issue is that after few theft between new sessions my client stops to show the stealed component.
This message is on the console: “A connector with id 6 is already registered”

The aim of all this is to programmatically choose to steal a UI. So hopefully, I’ll be able to show a user his/her sessions and re-take them (like ms rdp sessions)

Here it is the working but not stable code:


package pro.jako.stealui;

import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.server.*;
import com.vaadin.ui.*;

@PreserveOnRefresh
public class StealUI3 extends UI {

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        setContent(new Comp1());
    }
}

class Comp1 extends CustomComponent {
    static ComboBox combo = null;

    Comp1() {

        String id = String.format("ses=%d ui=%d"
                , System.identityHashCode(VaadinSession.getCurrent())
                , System.identityHashCode(UI.getCurrent()));

        synchronized (getClass())
        {
            if(combo == null){
                combo = new ComboBox() ;
                combo.setImmediate(true);
                combo.addItem("first");
                combo.addItem("second");
                combo.addItem("third");
                combo.addItem(id);

            }
        }

        AbstractOrderedLayout root = new VerticalLayout();
        root.addComponent(new Label("steal-ui"));
        root.addComponent(new Label(id + " (this new ui)"));
        final Button loginBtn = new Button("sign in (yes, without credentials)");
        loginBtn.addClickListener((evt) ->
                {
                    loginBtn.setVisible(false);
                    root.addComponent(combo);
                });
        root.addComponent(loginBtn);
        setCompositionRoot(root);
    }


}

I’m using vaadin7-beta11 and tomcat-33

As you can see I’m using lambdas with jdk8.
But I think it’s not the issue!
I was able to port to jdk8-vaadin7 a good portion of this awesome application
http://code.google.com/p/vdbc/

I’ve attached other two tests more stable but simpler than the previous. Plus the source of the previous

It’s my first post, and I’m glad to be here!
Best regards guys!
Great job!!
12711.java (1.05 KB)
12712.java (1.22 KB)
12713.java (1.43 KB)

To see how the toy works, you have to create a new Vaadin7 UI (in other words a Vaadin project).
Use the previous code (eg StealUI3.java) and open one browser.
Click and change the state of the application (click the ComboBox and choose an item)

Then open a new window or a different browser (so the session will be surely a newly created) and notice that you stealed the ComboBox from the previous UI.

best regards,
Simone Giacomelli

Didn’t try your code and actually didn’t really understand it either. But I would keep a serverside registry of running sessions (userid/password => JSESSIONID; maybe with a timestamp of last modification for easy cleanup) instead. That way you could just resend the old session-cookie by manipulating the response after the user has logged in again. Somehow a reverse Session-hijacking-attack ;).

Hi Tobias,
thanks for your answer.

Your suggestion made me dig more on vaadin UI-windows managing.
I discovered that JSESSIONID will not work alone. After a huge debug session I’ve discovered that (in vaadin-7-beta11 at least) the preserveOnRefresh is accomplished both with session (JSESSIONID) and the browser window.name (through the url parameter ‘v-wn’ used in AbstractCommunicationManager and vaadinBootstrap.js)

This means that to accomplish the ‘impersonating’ of a UI I need tochange the JSESSIONID and the dom window.name.

The trick in my first post was using a
static
ComboBox field (obviously, more sophisticated mechanism can be used)
So this ComboBox instance would be ‘stealed’ by the last created UI. And It works; but it is not stable.

Maybe I’ll give a try to both:
-mange to change the JSESSIONID cookie and store the window.name
-try to understand why I receive “A connector with id 6 is already registered”; right now, I’m thinking that it could be for something wrong in the de-registration of the ComboBox component from the previous parent. Anybody would point me in what direction to take to investigate further on this subject?

Best regards

Is there coming a stacktrace along with that message “A connector with id …”? Didn’t find that String while searching the JAR-Files.

The window-id / window-state should be managed by PreserveOnRefresh, calling the same URL and showing the same JSESSIONID-Cookie should lead to Vaadin showing the same UI in the same state. But that is only what I understand so far, I didn’t try it out as I don’t have a use-case for this.

Oh, by the way, using static references to components will give you a huge headache as soon as more than one user works with your application in the same JVM.

As I stated in my first post I put a simplistic example. I know the implications of static fields.

I searched for “A connector with id …” and I found it in the sources.

From the lack of response I think that the subject of the post is a not common issue.

best regards