Share component between sessions of an user. A connector with id XX is alr

I need to share a component between sessions of an user. But when I get the old component used in a previous session i get this error:

09:43:55,477 SEVERE [com.vaadin.server.DefaultErrorHandler]
(http-/0.0.0.0:8080-6) : java.lang.RuntimeException: A connector with id 98 is already registered!

I saw that this component (with isConnectorEnabled()) has already a connector (I think made from the last/first session.
Can i remove old connectors to component and make it as a new instance?

No solution for this?

This is an interesting use case, but unfortunately not really something that Vaadin components are designed for. However, it
might
work as long as you serialize the component before it’s attached to the application (ie. before it’s added to a parent component). It might also work after detaching the component, except that currently the connector id is not cleared on detach, leading to the exception you got - this might be worth fixing.

An attached component should never be serialized; it will end up serializing the whole application at the same time, due to the parent references.

Anyway, there might be dragons. Please do report back if you get it to work, or if you encounter other issues - as I said, this is an interesting use case and perhaps worth officially supporting at some point.

If I serialize my instance first of the use and then i will deserialize it i cannot see the change that are made after the use
I can do other test? Or I have no other possibility, I must save the status of component and recreate it.

Yeah, true, serializing before attaching is not actually very useful :confused:

I created
ticket #12302
for unsetting the connector id on detach.

My point of view: sharing an actual component is not something Vaadin supports. A component has a state (which includes both visible things and internal details) which is in many ways specific to where it is used.

Wanting to share a component is usually a symptom of either duplicating the approach that was taken with another system that supports such, or requested based on one idea how to solve a problem without actually specifying what is the original problem and looking into other alternatives. What one usually wants to share is the underlying data that the component displays.

Note that also the standard Vaadin containers are not well suited for being shared because of their listeners possibly keeping everything related to all the UIs sharing the container in memory (and being updated), so sharing a common data model under non-shared Vaadin container instances is usually a better option.

It would probably be better to have an ability to save and load the shared state only - currently what is missing is the ability to assign the loaded state to a new object, although one could do a field-by-field copy using reflection. This has the advantage that only those things that are usually useful to serialize are actually saved; the main disadvantage is that not nearly all Vaadin components use the shared state mechanism yet. Also, there might be server-side-only state, such as registered listeners, that might be useful to serialize but won’t be if only shared state is saved.

Storing components with children would also require special handling. The hierarchy is stored separately, not in the shared state. However, many component containers store metadata about their child components and use connector ids to refer to the children - after deserialization these would somehow need to be resynchronized. This might not be at all trivial in the general case.

All in all, it appears that doing this Right would require quite a few changes to the framework itself.

Thank you both for your interest.
I’m using for now the solution described earlier, I store the status of data and I recreate the component when it is necessary. But a feature that solve the problem with a good tradeoff in the framework not is a bad idea.

My point was that the real root
problem
is not sharing components but some higher level requirement that you have. Sharing components was a
solution
you chose to address the original problem, but that approach turned out to have its own technical problems.

I think trying to address sharing components in general in Vaadin is not a good idea - it might have been one if designed in carefully when the development of the framework started, but it cannot be bolted on cleanly on top of the current framework and APIs without breaking a lot of things.

Therefore, if something should be done, it should be done based on the application level requirements that triggered the idea of maybe sharing components - why did you want to share components in the first place?

The reason is that I do not need to maintain a state of what I’m doing, so I would have an advantage in terms of rapid development. I’m just at the beginning of the development of my project so I have no problem to change and probably is the right thing to do with the client-server approach. Thanks for your interest.

public class PCTTextBoxState extends AbstractTextFieldState {
public String text;
}
public class VPCTTextBox extends VTextField {
public VPCTTextBox() {
super();
}
}
@Connect(value = WrappedTextField.class, loadStyle = LoadStyle.EAGER)
public class VPCTTextBoxConnector extends TextFieldConnector {

@Override
protected Widget  createWidget() {
    return GWT.create(VTextField.class);
}

@Override
public VPCTTextBox getWidget() {
return (VPCTTextBox) super.getWidget();
}
@Override
public PCTTextBoxState getState() {
return (PCTTextBoxState) super.getState();
}
@OnStateChange(“text”)
void updateText() {
getWidget().setText(getState().text);
}
}

@SuppressWarnings(“serial”)
public class WrappedTextField extends TextField {

public WrappedTextField() {
    super();
}

public WrappedTextField(String caption) {
    this();
    setCaption(caption);
}
 @Override
    public PCTTextBoxState getState() {
        return (PCTTextBoxState) super.getState();
    }

    public void setText(String text) {
        getState().text = text;
    }
  public String getText() {
        return getState().text;
    }

}

Gives follwing exception-

java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:881)
at com.vaadin.server.LegacyCommunicationManager.encodeState(LegacyCommunicationManager.java:105)
at com.vaadin.server.AbstractClientConnector.encodeState(AbstractClientConnector.java:264)
at com.vaadin.server.communication.SharedStateWriter.write(SharedStateWriter.java:62)
at com.vaadin.server.communication.UidlWriter.write(UidlWriter.java:132)
at com.vaadin.server.communication.UIInitHandler.getInitialUidl(UIInitHandler.java:285)
at com.vaadin.server.communication.UIInitHandler.synchronizedHandleRequest(UIInitHandler.java:80)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:350)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:662)