Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Applet integration
A few times I have been asked about the integrating a Java applet to a Vaadin application. There are few things to bear in mind with that and I thought that is easier to create a package that you can use as a basis for your own integration.
So, here is a AppletIntegration add-on.
The package includes a base Java applet class that implements threaded communication with GWT component as well as base widget and server-side API to embed the applet.
AbstractApplet:
A base class for an applet. Implements a threaded JavaScript communication mechanism. The threading is needed if you want to integrate a privileged applet (i.e. access resources outside web sandbox). Just subclass this and implement the execute method.
VAppletIntegration:
Client-side Applet integration base for embedding and communicating with an applet. Implements GWT peer to for applet communication.
AppletIntegration:
Server-side applet integration class. This is intended to be subclassed to integrate a custom applet to your Vaadin application. Implements the server API for applet communication.
Remember, that to implement a privileged applet you need sign the applet jar.
Source code in contrib: http://dev.vaadin.com/svn/contrib/AppletIntegration/ and attached the add-on jar.
For online sample, see this: http://sami.virtuallypreinstalled.com/screenshot
Hi Sami,
is the source code of the example accessable ?
Thx,
Norman
Sami's link requires that you log in to the Trac (you can create an account here) but you can also browse the repository without logging in here: http://dev.vaadin.com/browser/contrib/AppletIntegration.
Hi all,
after askin on IRC I got the link to the source code of the example which was really helpful.
Anyway I can't make it work with my implementation. The init() method of my Applet is never called. Any idea what could be the cause of this ? The same is true for the doExecute(,,,) method.
Applet code:
package de.heagmobilo.dfi.manager.ui.streamer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.io.IOUtils;
import org.vaadin.applet.AbstractVaadinApplet;
import de.heagmobilo.dfi.manager.ui.data.WAVRecorder.RecorderException;
public class RecordSoundApplet extends AbstractVaadinApplet {
/**
*
*/
private static final long serialVersionUID = -3507633958558969641L;
public static final String CMD_SAVE = "post";
private static final int DEFAULT_HEIGHT = 1;
private static final int DEFAULT_WIDTH = 1;
private String postUrl;
private String postParamName;
private String sessionCookie;
private static final String POST_PARAM_SUFFIX = "_file";
public static final String CMD_RECORD = "record";
public static final String CMD_STOP = "stop";
private de.heagmobilo.dfi.manager.ui.data.WAVRecorder recorder = new de.heagmobilo.dfi.manager.ui.data.WAVRecorder();
@Override
public void init() {
super.init();
resize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
postUrl = super.getApplicationURL();
postParamName = getPaintableId();
postParamName += POST_PARAM_SUFFIX;
sessionCookie = getApplicationSessionCookie();
System.out.println("LOADED");
}
@Override
protected void doExecute(String command, Object[] params) {
System.out.println("CMD=" +command);
if (command.equals(CMD_SAVE)) {
postSoundToServer();
} else if (command.equals(CMD_RECORD)) {
recordSound();
} else if (command.equals(CMD_STOP)) {
stopRecordSound();
}
}
private synchronized void stopRecordSound() {
recorder.stop();
}
private synchronized void recordSound() {
try {
recorder.record();
} catch (RecorderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private synchronized void postSoundToServer() {
if (postUrl == null) {
System.out.println("URL missing. Cancel post.");
return;
}
// Send in separate thread
Thread t = new Thread() {
@Override
public void run() {
try {
System.out.println("Post to server: " + postUrl);
System.out.println("Cookie: " + sessionCookie);
final ByteArrayOutputStream bo = new ByteArrayOutputStream();
IOUtils.copy(recorder.getRecordedStream(), bo);
PostMethod filePost = new PostMethod(postUrl);
filePost.getParams().setBooleanParameter(
HttpMethodParams.USE_EXPECT_CONTINUE, false);
filePost.setRequestHeader("Cookie", sessionCookie);
HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams()
.setConnectionTimeout(5000);
int status = client.executeMethod(filePost);
vaadinSync();
} catch (MalformedURLException e) {
System.out.println(e);
} catch (IOException e) {
System.out.println(e);
}
}
};
t.start();
}
}
Widget code:
package de.heagmobilo.dfi.manager.ui.streamer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.vaadin.applet.client.ui.VAppletIntegration;
import com.vaadin.Application;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.StreamResource;
import com.vaadin.terminal.StreamResource.StreamSource;
import com.vaadin.terminal.gwt.server.WebApplicationContext;
import com.vaadin.ui.Upload;
@com.vaadin.ui.ClientWidget(org.vaadin.applet.client.ui.VAppletIntegration.class)
public class RecordSound extends Upload {
private static final long serialVersionUID = 7348838270779907095L;
private static final String APPLET_CLASS = "de.heagmobilo.dfi.manager.ui.streamer.RecordSoundApplet";
private static final String[] APPLET_ARCHIVES = new String[] {
"screenshot.jar", "appletintegration-1.0.2.jar",
"commons-httpclient-3.1.jar", "commons-codec-1.3.jar",
"commons-logging-1.1.1.jar" };
public ByteArrayOutputStream data;
public boolean ready;
private boolean record = false;
private boolean stop = false;
private boolean save = false;
private List<Listener> listeners = new ArrayList<Listener>();
private String name;
/**
* Creates new screenshot component.
*
*/
public RecordSound() {
super(null, null);
setReceiver(new SoundRecordReceiver());
addListener(new UploadReadyListener());
}
/**
* Take a screenshot. Screenshots are taken interactively so that user
* selects an area from screen.
*
*/
public void record() {
record = true;
save = false;
stop = false;
requestRepaint();
}
public void stop() {
stop = true;
save = false;
record = false;
requestRepaint();
}
public void save(String name) {
save = true;
stop = false;
record = false;
this.name = name;
requestRepaint();
}
public void paintContent(PaintTarget target) throws PaintException {
System.out.println("paint!!!");
target.addUploadStreamVariable(this, "stream");
// Because we don't inherit the AppletIntegration component on the
// server-side, we have to add the attributes explicitly here:
String sid = getHttpSessionId();
if (sid != null) {
target.addAttribute(VAppletIntegration.ATTR_APPLET_SESSION, sid);
}
target.addAttribute(VAppletIntegration.ATTR_APPLET_CLASS, APPLET_CLASS);
target.addAttribute(VAppletIntegration.ATTR_APPLET_ARCHIVES,
APPLET_ARCHIVES);
if (record) {
System.out.println("RECORD!!!");
target.addAttribute(VAppletIntegration.ATTR_CMD, RecordSoundApplet.CMD_RECORD);
record = false;
} else if (save){
System.out.println("SAVE!!!");
target.addAttribute(VAppletIntegration.ATTR_CMD, RecordSoundApplet.CMD_SAVE);
save = false;
} else if (stop) {
System.out.println("STOP!!!");
target.addAttribute(VAppletIntegration.ATTR_CMD, RecordSoundApplet.CMD_STOP);
stop = false;
}
// super.paint(target);
}
/**
* Read the HTTP session id.
*
* This method cannot be called if this component has not been attached to
* the application.
*
* @return
*/
protected String getHttpSessionId() {
Application app = getApplication();
if (app != null) {
WebApplicationContext ctx = ((WebApplicationContext) app
.getContext());
if (ctx != null) {
return ctx.getHttpSession().getId();
}
}
return null;
}
private class SoundRecordReceiver implements Receiver {
private static final long serialVersionUID = 1828017160390445637L;
public OutputStream receiveUpload(String filename, String MIMEType) {
ready = false;
return data = new ByteArrayOutputStream();
}
}
private class UploadReadyListener implements FinishedListener {
private static final long serialVersionUID = -580474682420247918L;
@Override
public void uploadFinished(FinishedEvent event) {
ready = true;
save = false;
invokeListeners();
}
}
public String getSoundName() {
return name;
}
/**
* Listener for screenhot uploads. Invoked when a new screenshot has been
* trasfered to the server.
*
* @author Sami Ekblad
*
*/
public interface Listener {
void recordSoundReady(RecordSound screenshot);
}
/**
* Add new listener.
*
*/
public void addListener(Listener listener) {
listeners.add(listener);
}
private void invokeListeners() {
for (Listener l : listeners) {
l.recordSoundReady(this);
}
}
/**
* Remove a listener.
*
*/
public void removeListener(Listener listener) {
listeners.remove(listener);
}
/**
* Get current screenshot data as a Resource. Screenshots are PNG images.
*
* @see Resource
*/
public Resource getRecordSoundResource() {
StreamSource ss = new StreamSource() {
@Override
public InputStream getStream() {
return getRecordSoundInputStream();
}
};
StreamResource sr = new StreamResource(ss, name + ".wav", getApplication());
return sr;
}
/**
* Get current screenshot data as InputStream. Screenshots are PNG images.
*
* @see #getScreenshotResource()
*/
public InputStream getRecordSoundInputStream() {
return new ByteArrayInputStream(data != null ? data.toByteArray()
: new byte[] {});
}
}
Hi,
Your code looks quite ok, but if the applet init does not get called, the reason is simply that the applet is not instantiated on the web page correctly. VAppletIntegration is responsible of this part.
I cannot say what is causing this, but the Java console is something that can help here. It shows what classes it tries to load and from where. My guess is that the applet class/jar is not in the correct place i.e. under the GWT public folder next to (generated) .gwt.xml file.
Hi Sami,
thx for the tip now I see whats the problem ..
java.security.AccessControlException: access denied (javax.sound.sampled.AudioPermission record)
I thought I should be able to use this in a applet once it is signed ...
Bye,
Norman
Good to hear! You are right about the signing - just don't use self-signed certificate as I did. That's a bad practice :)
Hi Sami,
thats the problem I signed it and it still not work (I used a self signed to test it)... :(
Thx,
Norman
No problem, this is how to solve it: one step at the time.
Please, if you have any data from the console that you can share here, I can try to help you a bit further.
One thing I remembered one generic applet development tip:
You are sure you changed the code, but the changes are simply not reflected. You have cleared the class loader cache from the Java console, but still no effect. You should restart your browser.
At least FF very persistently caches the jar files and they simply are not reloaded from the server until you restart the browser.
Good add-on! Can you provide simpler example, just calling applet frame with some parameters (vaadin textbox -> applet textbox). I have trouble with Screenshot add-on. Thanks and sorry for my English.
Hi!
Can I use this applet integration to from inside the applet programatically change the value from a textfield on the page?
/luis
Currently this is not officially supported as long as there is no client-side API for Vaadin components. It will most likely to to be in Vaadin 7 and something like this has been discussed at Uservoice too.
However, here is a some workaround that you might be using today.
- Pass the component reference to applet (component id) at the server-side paintContent
- Subclass VAppletIntegration and pass the component id to applet)
- Store the component id in your applet
- Call changeVariable function with provided from applet
This will effectively send the variable to server which will change the TextField content back to browser.
I have seen some errors arround result retrieve.
Indeed, in AbstractVaadinApplet, Line 280, "result" operation variable is set insteadof class variable.
So "getResult" always return "null".
Can you fix that, or give to me write access.
I would like add some features around Thread management like "join" calls.
Thanks.
Hi,
I updated the add-on and fixed the result handling along the way. The main new feature is ability change Vaadin variables from the applet directly. http://vaadin.com/addon/appletintegration
Test with the latest package and let us know. I would have no problems giving commit access too, but we have to ask the svn administrator that. Maybe it is easier for both of us to use email and patches?
hi
How to call applet and how can i pass parameters to applet in Vaadin App ?
(i need call method form applet code by passing parameters )
anybody know how to do it?
please help me?
Hi,
For normal applet parameters there is setAppletParams method in the AppletIntegration class. It is a protected method, but to use it just subclass the AppletIntegration class.
Hi Sami,
I'm trying to run a simple applet from vaadin application as described in the example from addon page:
AppletIntegration applet = new AppletIntegration() {
private static final long serialVersionUID = 1L;
@Override
public void attach()
{
setAppletArchives(Arrays.asList(APPLET_ARCHIVES));
setCodebase("VAADIN/");
setAppletClass(APPLET_CLASS);
}
};
addComponent(applet);
where APPLET_CLASS = "com.alee.sca.authorization.AuthorizationApplet"; and APPLET_ARCHIVES = new String[] { "AuthorizationApplet.jar" };
When I run my application I recieve the following error:
SEVERE: Requested resource [VAADIN/com.alee.sca.authorization.AuthorizationApplet] not found from filesystem or through class loader. Add widgetset and/or theme JAR to your classpath or add files to WebContent/VAADIN folder.
But I can reach AuthorizationApplet.jar from the browser so it exists on the server. I compiled widgetset and it is on classpath, AuthorizationApplet.jar is placed in folder web/VAADIN.
I also noticed that in screenshot addon not only applet jar is added to applet archives but also some libraries including applet integration addon jar. Is it necessary to add additional libraries to applet archives? And where should I put these jar files?
Thanks,
Alexander
It seems that I solved the problem, applet is working now, but I have another question: how can I receive variables from applet back to vaadin application if I send them to server using vaadinUpdateVariable method? Should I implement a receiver like it is done in screenshot application or there is another way to do it?
Thanks,
Alexander
Yes, you can receive the variables in the server. The receiver function you have to implement is changeVariables. To do this you must inherit the AppletIntegration class and override it like:
@Override
public void changeVariables(Object source, Map variables) {
super.changeVariables(source, variables);
if (variables.containsKey("mydata")) {
String mydata = (String) variables.get("mydata");
}
}
And in your applet you would send this like:
vaadinUpdateVariable("mydata", "somevalue", true);
Hi Sami,
Do you know, why this add-on not supported Safari v5 and Google Chrome browsers?
After calling server side method "executeCommand", applet side method "doExecute" never is called. Why?
Thanks,
Michael
I just haven't taken look what is needed for the webkit based browsers to get applets running. I guess that there may be some differences in the Java-JS bridge implementation at least. Currently this is multithreaded to make applet privileges to work.
Any help investigating this is very much appreciated.
Hi Sami,
We made a workaround to be able to make AppletIntegration work on Safari & Chrome. Instead of executing applet commands from doExecute method via executeCommand we used setAppletParams on the server side & moved all logic from doExecute method to method run() wich is called from applet's start() method. The call to run is as follows:
@Override
public void start()
{
...
run(getParameter("mode"));
}
Applet parameter is set in attach() method:
@Override
public void attach() {
setAppletArchives(Arrays.asList(APPLET_ARCHIVES));
setCodebase("VAADIN/applets/");
setAppletClass(APPLET_CLASS);
setAppletParams("mode", mode);
}
This works fine for Firefox, Safari & Chrome, but doesn't work good on IE. The problem is that after running applet on IE Out of sync error always appears with the following log message: SEVERE: Warning: Ignoring variable change for non-existent component, VAR_PID=PID15. We use changeVariables method on server side & vaadinUpdateVariable from applet to update variables values from client side. Could you please advise what can cause Out of sync problem in this case (only on IE)?
Thanks,
Alexander
This could be an application-level problem. The OOS comes when client tries to send a variable for a component that has been already removed from the server-side.
I tried to find out what component causes OOS warning & according to debug information it was some component inside AppletIntegration. Could you please tell is there any possibility to exactly find out what component has PID that is specified in OOS warning or how to get component PID from the code?
There should not be anything "inside" the AppletIntegration, so it must the the component itself.
The PID is assigned by the communication servlet and I think there is n easy way of getting it in your application. You can set the debugId for the component to force the id to be something. Like comp.setDebugId("something") then the variable will have the name "PID_something".
However, if it is only IE causing this it might be completely something else. It might be a delay when applet sends something back (i.e. calls js) or double-post situation or something...
I'm sorry I cannot figure out what could it be without seeing, but I'll post here if I come up with some more debugging ideas.
I developed a workaround for this IE problem & found other interesting fact: I created another thread that is started when applet is needed to be removed from layout, in this thread applet is detached & removed after some delay (about 5 seconds) to be sure that all requests are already sent & received. In this case applet works fine, after it is removed from the layout & switching to another layout no out of sync warning appears. But when I try to perform any action in new layout (e.g. button press or tree expand) I get this warning with debug id that I assigned to AppletIntegration component. Even if a lot of time passed since applet was removed. Also I stopped applet manually from the inside calling System.exit from applet class, but the result is the same. May be you can give some explanation to this strange behavior.
Strange indeed. Sounds like there is some event sent during the client-side detach that is reflected back to the server a bit too late. Why it is only on IE? Probably because of some GWT behavior or because of a delay when removing applets from DOM. Anyway, I'm pretty sure this can be fixed in the client-side VApplicatIntegration somehow...
Hello All,
Is it possible to use arbitrary applet via AppletIntegration add-on, or it should be an applet, subclassed from AbstractApplet ?
Is just subclassing AppletIntegration and setting jar details sufficient to use it as Vaadin component ? The reason for asking is using a subclass of AppletIntegration (and adding maven dependency on the add-on) gives the following error:
"Widgetset does not contain implementation for org.vaadin.applet.AppletIntegration. Check its @ClientWidget mapping, widgetsets GWT module description file and re-compile your widgetset. In case you have downloaded a vaadin add-on package, you might want to refer to add-on instructions. Unrendered UIDL:
org.vaadin.applet.AppletIntegration(NO CLIENT IMPLEMENTATION FOUND)"
Obviously, the configuration of client widget (VApletIntegration) is missing. Could you please point to example or documentation how to include it?
Please excuse me if this was already answered elsewhere.
Is it possible to use arbitrary applet via AppletIntegration add-on, or it should be an applet, subclassed from AbstractApplet ?
It is possible. The AbstractApplet just implements the communication between Vaadin so that you don't have to worry about the details. If you don't need that you can use different applet class altogether.
You still have to compile the widgetset once to get the thing working. That what you are missing here. Take a look at instructions here: http://vaadin.com/directory/help/using-vaadin-add-ons
Unfortunately I don't have extensive documentation available currently, but now that I have some clear use-cases I could set up a wiki page or something to answer the most important questions.
Thank you, mvn vaadin:update-widgetset install was indeed what was missing.
Once the widgetset is compiled, and not going to be changed is it sufficient to copy them into VAADIN/widgetsets folder and switch off the GWT compilation?
And one more question - it seems the applet integration component shows nothing if embedded in a popup window ? (which is reasonable to expect if popup windows are overlays).
Sorry, another question - do I understand right , there is no easy way to client side scripting (e.g. invoke arbitrary applet method and change a text field) ?
Vaadin works mainly at the server-side and that is where the application control should be.
With applets you can call back to server using the AbstractVaadinApplet.vaadinUpdateVariable and catch that in the
There is also a way to call arbitrary JavaScript using the jsCallAsync and jsCallSync methods in the AbstractVaadinApplet.
If you wish to send something to the applet you should use the executeCommand in AppletIntegration (server-side) component. That can be handled in you applet by implementing the abstract doExecute method.
Currently there is no support for calling arbitraty applet methods from the server, but maybe that would make sense too.
About the problem with subwindow: I would have thought it works, but maybe browsers somehow prevent the z-indexing of applets properly.
[indent]Hello,
I have developed a project in which 3D graphics rendering is possible in the web browser using a combination of Vaadin , JMonkeyEngine game platform, ICEPush and the AppletIntegration add-on.
You can see an online demo here
Vaadin was used to create the main application and user interface. The AppletIntegration add-on was used to add the applet to the Vaadin Application. Inside my main applet class which extended "AbstractVaadinApplet" (provided on AppletIntegration add-on) , I added the code to be able to render 3D graphics inside the Java Applet using the JMonkeyEngine game Engine. The communication between vaadin and the Applet was done through the mechanism offered in this Add-on along with a combination of the mechanism offered by the ICEPush add-on found in the Vaadin Add-on repository.
I have created a google code project in which I committed the code used for the online demo as well as the code used to create the 3D graphics in the applet.
You can check it out at the jmonkeyengine-vaadin-integration google code web site
You can also visit the Whole Brain Catalog web application,a 3D Neuroscience tool, which makes use of this strategy and is more developed than the online demo provided above.
So far it works well in Windows (Firefox, Chrome, IE, Opera), Mac (Firefox, Safari 4).
The AppletIntegration seems to be having problems in Safari 5, the doExecute() method receives null parameters even though the Vaadin application sends the Applet non-null parameters. The issue is also reproduced in Firefox and Chrome in Ubuntu Linux.[/indent]
Hi! As an old fan of the jMonkeyEngine I'd say that you have a very interesting project there :)
What you say about the disappearing applet parameters, I have to take a look. Effectively, it is a JavaScript call to document.applets[ID].execute(name, params), but maybe there is something different between the browsers. Although, I must say this use case hasn't been too extensively tested in my applications...
Btw: the setup seems fails to install the native ljwgl libraries under OS X.
Thanks for letting me know it fails to install the libraries, I just fix this for the online demo and should work this time around.
I also created a video demonstrating the interaction between vaadin and jme. Demo Video
Hello :)
I'm trying to use AppletIntegration with Vaadin 6.53 but I can't make it work.
I need to send image to server-side from applet and then get it back to vaadin application, like you do in Screenshot add-on. I tried to run Screenshot demo but it doesn't work for me and in Java Console I have:
security: resource name "org/apache/commons/httpclient/methods/multipart/PartSource.class" in http://sami.virtuallypreinstalled.com/screenshot/VAADIN/widgetsets/org.vaadin.screenshot.widgetset.ScreenshotApplicationWidgetset/commons-httpclient-3.1.jar : java.lang.SecurityException: trusted loader attempted to load sandboxed resource from http://sami.virtuallypreinstalled.com/screenshot/VAADIN/widgetsets/org.vaadin.screenshot.widgetset.ScreenshotApplicationWidgetset/commons-httpclient-3.1.jar
Exception in thread "AWT-EventQueue-2" java.lang.SecurityException: trusted loader attempted to load sandboxed resource from http://sami.virtuallypreinstalled.com/screenshot/VAADIN/widgetsets/org.vaadin.screenshot.widgetset.ScreenshotApplicationWidgetset/commons-httpclient-3.1.jar
at com.sun.deploy.security.CPCallbackHandler$ParentCallback.check(Unknown Source)
at com.sun.deploy.security.CPCallbackHandler$ParentCallback.access$1500(Unknown Source)
at com.sun.deploy.security.CPCallbackHandler$ChildElement.checkResource(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.checkResource(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.getResource(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
....
I supposed this is because signing issues so I toked the source and signed this jar, but again there was no success.
In server log I have got:
10:41:31,504 ERROR [STDERR] 18.03.2011. 10.41.31 com.vaadin.terminal.gwt.server.AbstractApplicationServlet serveStaticResourcesInVAADIN
[exec] INFO: Requested resource [VAADIN/widgetsets/com.ecsmon.scanapplet.widgetset.EcsscanappletWidgetset/META-INF/services/org.apache.commons.logging.LogFactory] not found from filesystem or through class loader. Add widgetset and/or theme JAR to your classpath or add files to WebContent/VAADIN folder.
[exec] 10:41:31,622 ERROR [STDERR] 18.03.2011. 10.41.31 com.vaadin.terminal.gwt.server.AbstractApplicationServlet serveStaticResourcesInVAADIN
[exec] INFO: Requested resource [VAADIN/widgetsets/com.ecsmon.scanapplet.widgetset.EcsscanappletWidgetset/org/apache/log4j/Category.class] not found from filesystem or through class loader. Add widgetset and/or theme JAR to your classpath or add files to WebContent/VAADIN folder.
and from Java Console I can see that PID and SID are OK such as postUrl http://localhost:8080//app_name
I tried to add missing files ("META-INF/services/org.apache.commons.logging.LogFactory" , "org/apache/log4j/Category.class" ) manually but it keeps giving me same result.
Because Screenshot extends Upload I was reading source of Upload component and I saw there is no "stream" variable which was called from Screenshot paintContent method (target.addUploadStreamVariable(this, "stream");), and then I realized that in Vaadin 6.53 Upload component have different implementation then Vaadin 6.24. Because of that I tried like this:
public void paintContent(PaintTarget target) throws PaintException {
super.paintContent(target);
// target.addUploadStreamVariable(this, "stream");
// target.addVariable(this, "action", getStreamVariable());
// Because we don't inherit the AppletIntegration component on the
// server-side, we have to add the attributes explicitly here:
String sid = getHttpSessionId();
if (sid != null) {
target.addAttribute(VAppletIntegration.ATTR_APPLET_SESSION, sid);
}
target.addAttribute(VAppletIntegration.ATTR_APPLET_CLASS, APPLET_CLASS);
target.addAttribute(VAppletIntegration.ATTR_APPLET_ARCHIVES, APPLET_ARCHIVES);
target.addAttribute(VAppletIntegration.ATTR_APPLET_PARAM_NAMES, APPLET_ARCHIVES);
if (screenshot) {
target.addAttribute(VAppletIntegration.ATTR_CMD, CMD_SCAN);
screenshot= false;
}
}
but it doesn't work again.
Then I used firebug to see what happens when uploading files and in response I got something like this:
for(;;);[{"changes":[["change",{"format": "uidl","pid": "PID167"},["14",{"id": "PID167","width": "100.0%"},"Uploaded file contained 716 linebreaks"]],["change",{"format": "uidl","pid": "PID166"},["15",{"id": "PID166","caption": "Upload a file","tabindex":0,"state":false,"buttoncaption": "Upload","nextid":1,"v":{"action":"http:\/\/localhost:8080\/app_name\/APP\/UPLOAD\/PID166\/action\/6b9ee76f-b43f-4a8e-995b-e8a3356ad07f"}}]]], "meta" : {}, "resources" : {}, "locales":[]}]
so I conclude that http:\/\/licalhost:8080\/app_name\/APP\/UPLOAD\/PID166\/action\/6b9ee76f-b43f-4a8e-995b-e8a3356ad07f is postUrl (am I wrong?) Here I'm stacked :)
Basically I need applet to do same thing as upload but with file (in this case image ) that is generated with applet and that file needs to be somehow displayed in vaadin application.
What am I missing?
Is there another way to do this in latest version of Vaadin, or there is another add-on or something?
Sorry for bad English :)
Thanks in advance!
Hello everyone :)
I have found the solution. I modified VAppletIntegration, AbstractVaadinApplet and paintContent method from ScreenShot. Here are modifications:
VAppletIntegration:
-aded fields:
-- protected static final String PARAM_ACTION = "action";
-- public static final String ATTR_APPLET_ACTION = "action";
-- private String action;
-updateFromUIDL(...)
-- if(uidl.hasVariable(ATTR_APPLET_ACTION)){
action = uidl.getStringVariable(ATTR_APPLET_ACTION);
}
-private Map<String, String> getDefaultIntegrationParameters()
-- added line res.put(PARAM_ACTION,action);
public class VAppletIntegration extends HTML implements Paintable {
protected static final String PARAM_APP_SESSION = "appSession";
protected static final String PARAM_APP_URL = "appUrl";
protected static final String PARAM_APP_DEBUG = "appDebug";
protected static final String PARAM_PAINTABLE_ID = "paintableId";
protected static final String PARAM_APPLET_ID = "appletId";
protected static final String PARAM_ACTION = "action"; //this is added
/** Client-server communication attributes. */
public static final String ATTR_APPLET_SESSION = "appletSession";
public static final String ATTR_APPLET_CLASS = "appletClass";
public static final String ATTR_APPLET_ARCHIVES = "appletArchives";
public static final String ATTR_APPLET_PARAM_NAMES = "appletParamNames";
public static final String ATTR_APPLET_PARAM_VALUES = "appletParamValues";
public static final String ATTR_APPLET_CODEBASE = "appletCodebase";
public static final String ATTR_APPLET_ACTION = "action"; //this is added
public static final String ATTR_CMD = "cmd";
public static final String ATTR_CMD_PARAMS = "cmdParams";
/** Set the CSS class name to allow styling. */
public static final String CLASSNAME = "v-applet";
/** The client side widget identifier */
protected String paintableId;
/** Reference to the server connection object. */
protected ApplicationConnection client;
/** Generated applet id. Unique across the application. */
private String appletId;
/** Has the applet been initialized. Applet is initialized only once. */
private boolean appletInitialized;
private String appletClass;
private String[] archives = new String[] {};
private Map<String, String> appletParameters;
private String appletSession;
private String height = "0";
private String width = "0";
private String codebase;
private String action; //this is added
/**
* The constructor should first call super() to initialize the component and
* then handle any initialization relevant to Vaadin.
*/
public VAppletIntegration() {
// The content will be changed in update function
setHTML("");
// Temporary applet id. Should not be needed.
appletId = CLASSNAME;
// This method call of the Paintable interface sets the component
// style name in DOM tree
setStyleName(CLASSNAME);
}
/**
* Called whenever an update is received from the server
*/
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
// This call should be made first.
// It handles sizes, captions, tooltips, etc. automatically.
if (client.updateComponent(this, uidl, true)) {
// If client.updateComponent returns true there has been no changes
// and we do not need to update anything.
return;
}
// Save reference to server connection object to be able to send
// user interaction later
this.client = client;
// Export client reference for applet use
exportClientUpdateVariable(client);
// Save the client side identifier (paintable id) for the widget
paintableId = uidl.getId();
appletId = CLASSNAME + paintableId;
// Create the Java applet using HTML
if (!appletInitialized) {
// Applet class
if (!uidl.hasAttribute(ATTR_APPLET_CLASS)) {
VConsole.log("Missing attribute " + ATTR_APPLET_CLASS);
return;
}
appletClass = uidl.getStringAttribute(ATTR_APPLET_CLASS);
// Applet session
if (!uidl.hasAttribute(ATTR_APPLET_SESSION)) {
VConsole.log("Missing attribute " + ATTR_APPLET_SESSION);
return;
}
appletSession = uidl.getStringAttribute(ATTR_APPLET_SESSION);
// Applet archives
if (!uidl.hasAttribute(ATTR_APPLET_ARCHIVES)) {
VConsole.log("Missing attribute " + ATTR_APPLET_ARCHIVES);
return;
}
// Allow overriding of the default codebase
if (uidl.hasAttribute(ATTR_APPLET_CODEBASE)) {
codebase = uidl.getStringAttribute(ATTR_APPLET_CODEBASE);
}
// Width and height if provided
if (uidl.hasAttribute("width")) {
setWidth(uidl.getStringAttribute("width"));
} else {
setWidth("0");
}
if (uidl.hasAttribute("height")) {
setHeight(uidl.getStringAttribute("height"));
} else {
setHeight("0");
}
//this is added
if(uidl.hasVariable(ATTR_APPLET_ACTION)){
action = uidl.getStringVariable(ATTR_APPLET_ACTION);
}
archives = uidl.getStringArrayAttribute(ATTR_APPLET_ARCHIVES);
// Applet appletParameters
appletParameters = getDefaultIntegrationParameters();
if (uidl.hasAttribute(ATTR_APPLET_PARAM_NAMES)) {
ValueMap map = uidl.getMapAttribute(ATTR_APPLET_PARAM_NAMES);
Set<String> keys = map.getKeySet();
for (String key : keys) {
appletParameters.put(key, map.getString(key));
}
}
// Create the HTML
setHTML(getAppletHTML());
appletInitialized = true;
}
// Execute the command
String cmd = null;
String[] cmdParams = null;
if (uidl.hasAttribute(ATTR_CMD)) {
cmd = uidl.getStringAttribute(ATTR_CMD);
}
if (uidl.hasAttribute(ATTR_CMD_PARAMS)) {
cmdParams = uidl.getStringArrayAttribute(ATTR_CMD_PARAMS);
}
if (cmd != null) {
execute(cmd, cmdParams);
}
}
private native static void exportClientUpdateVariable(ApplicationConnection client)
/*-{
var c = client;
$wnd.vaadin.appletUpdateBooleanVariable = function(pid, variableName, newValue, immediate) {
c.@com.vaadin.terminal.gwt.client.ApplicationConnection::updateVariable(Ljava/lang/String;Ljava/lang/String;ZZ)(pid, variableName, newValue, immediate);
};
$wnd.vaadin.appletUpdateIntVariable = function(pid, variableName, newValue, immediate) {
c.@com.vaadin.terminal.gwt.client.ApplicationConnection::updateVariable(Ljava/lang/String;Ljava/lang/String;IZ)(pid, variableName, newValue, immediate);
};
$wnd.vaadin.appletUpdateDoubleVariable = function(pid, variableName, newValue, immediate) {
c.@com.vaadin.terminal.gwt.client.ApplicationConnection::updateVariable(Ljava/lang/String;Ljava/lang/String;DZ)(pid, variableName, newValue, immediate);
};
$wnd.vaadin.appletUpdateStringVariable = function(pid, variableName, newValue, immediate) {
c.@com.vaadin.terminal.gwt.client.ApplicationConnection::updateVariable(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)(pid, variableName, newValue, immediate);
};
}-*/;
/**
* Execute a command in applet using AbstractVaadinApplet.execute method.
* Note that this requires that the applet has a method called "execute"
*
* @param cmd
* @param cmdParams
*/
public void execute(String cmd, String[] cmdParams) {
VConsole.log("Applet command: " + getAppletId() + ",'" + cmd + "','" + cmdParams + "'");
if (cmdParams != null && cmdParams.length > 0) {
internalAppletExecute(getAppletId(), cmd, cmdParams);
} else {
internalAppletExecute(getAppletId(), cmd);
}
}
/**
* This is the internal method that invokes the execute method in applet.
* Note that this requires that the applet has a method called "execute"
*
* @param id
* @param cmd
*/
private native void internalAppletExecute(String id, String cmd)
/*-{
if ($doc.applets[id]) {
$doc.applets[id].execute(cmd);
}
}-*/;
/**
* This is the internal method that invokes the execute method in applet.
* Note that this requires that the applet has a method called "execute"
* with string parameters.
*
* @param id
* @param cmd
* @param cmdParams
*/
private native void internalAppletExecute(String id, String cmd, String[] cmdParams)
/*-{
if ($doc.applets[id]) {
$doc.applets[id].execute(cmd,cmdParams);
}
}-*/;
/**
* Get paintable id of this widget.
*
* @return
*/
protected String getPaintableId() {
return paintableId;
}
/**
* Get applet HTML needed to initalize applet.
*
* Note: the default implementation does not return anything.
*
* @return String containing the APPLET tag needed to initialize the Java
* applet.
*/
protected String getAppletHTML() {
// Compose dependency JAR files
List<String> archives = getArchives();
String archiveAttribute = "";
if (archives != null) {
boolean first = true;
for (String a : archives) {
if (!first) {
archiveAttribute += ",";
} else {
first = false;
}
archiveAttribute += a;
}
}
// Compose applet appletParameters
Map<String, String> appletParams = getAppletParameters();
String appletParamStr = "";
if (appletParams != null) {
for (String name : appletParams.keySet()) {
appletParamStr += "<param name=\"" + name + "\" value=\"" + appletParams.get(name) + "\" />";
}
}
return "<applet mayscript=\"true\" code=\"" + "" + getAppletClass() + "" + "\" codebase=\"" + getCodebase() + "\" width=\"" + getWidth() + "\" height=\"" + getHeight() + "\" id=\"" + getAppletId() + "\" name=\"" + getAppletId() + "\" archive=\"" + archiveAttribute + "\">" + appletParamStr + "</applet>";
}
/**
* Get codebase of this applet. By default the code base points to
* GWT.getModuleBaseURL().
*
* @return
*/
private String getCodebase() {
return codebase == null ? GWT.getModuleBaseURL() : codebase;
}
protected String getHeight() {
return height;
}
protected String getWidth() {
return width;
}
@Override
public void setWidth(String w) {
super.setWidth(w);
width = w;
}
@Override
public void setHeight(String h) {
super.setHeight(h);
height = h;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
/**
* Get appletParameters for the applet as a Map.
*
* @return
*/
protected Map<String, String> getAppletParameters() {
return appletParameters;
}
/**
* Get id for this applet.
*
* @return
*/
protected String getAppletId() {
return appletId;
}
/**
* Get list of archives needed to run the applet.
*
* @return
*/
protected List<String> getArchives() {
ArrayList<String> res = new ArrayList<String>();
for (int i = 0; i < archives.length; i++) {
res.add(archives[i]);
}
return res;
}
/**
* Get name of the applet class.
*
* @return
*/
protected String getAppletClass() {
return appletClass;
}
/**
* Get default appletParameters for the applet.
*
* @return
*/
private Map<String, String> getDefaultIntegrationParameters() {
Map<String, String> res = new HashMap<String, String>();
// Add default appletParameters
res.put(PARAM_APPLET_ID, "" + getAppletId());
res.put(PARAM_PAINTABLE_ID, "" + getPaintableId());
String sessionId = appletSession;
if (sessionId == null) {
sessionId = Cookies.getCookie("JSESSIONID");
}
res.put(PARAM_APP_SESSION, "JSESSIONID=" + sessionId);
res.put(PARAM_APP_DEBUG, ApplicationConfiguration.isDebugMode() ? "true" : "false");
res.put(PARAM_APP_URL, GWT.getHostPageBaseURL() + client.getAppUri());
res.put(PARAM_ACTION,action); //this is added
return res;
}
}
AbstractVaadinApplet:
- fields added
-- protected static final String PARAM_ACTION = "action";
-- private String action; - added getter and setter for this field
- init() method added line setAction(getParameter(PARAM_ACTION));
public abstract class AbstractVaadinApplet extends Applet {
private static final long serialVersionUID = -1091104541127400420L;
protected static final String PARAM_APP_SESSION = "appSession";
protected static final String PARAM_APP_URL = "appUrl";
protected static final String PARAM_APPLET_ID = "appletId";
protected static final String PARAM_PAINTABLE_ID = "paintableId";
protected static final String PARAM_APP_DEBUG = "appDebug";
protected static final String PARAM_ACTION = "action";
protected static long MAX_JS_WAIT_TIME = 10000;
private boolean debug = false;
private JsPollerThread pollerThread;
private Object pollerLock = new Object[] {};
public boolean runPoller = true;
private String applicationURL;
private String sessionCookie;
private String paintableId;
private String appletId;
private String action;
@Override
public void init() {
setDebug("true".equals(getParameter(PARAM_APP_DEBUG)));
setAppletId(getParameter(PARAM_APPLET_ID));
setPaintableId(getParameter(PARAM_PAINTABLE_ID));
setApplicationURL(getParameter(PARAM_APP_URL));
setApplicationSessionCookie(getParameter(PARAM_APP_SESSION));
setAction(getParameter(PARAM_ACTION));
// Start the poller thread for JS commands
pollerThread = new JsPollerThread();
pollerThread.start();
}
/**
* Set the id of the applet in DOM.
*
* @param paintableId
*/
private void setAppletId(String appletId) {
this.appletId = appletId;
debug("appletId=" + appletId);
}
/**
* Get the id of the applet in DOM.
*
* @return The id of this applet in the Vaadin application DOM document.
*/
protected String getAppleteId() {
return appletId;
}
/**
* Set the paintable id of the applet widget.
*
* @param paintableId
* The id of this applet widget in the Vaadin application.
*/
private void setPaintableId(String paintableId) {
this.paintableId = paintableId;
debug("paintableId=" + paintableId);
}
/**
* Get the paintable id of the applet widget.
*
* @return The id of this applet widget in the Vaadin application.
*/
protected String getPaintableId() {
return paintableId;
}
/**
* Set the application session cookie. Called from init.
*
* @param appUrl
*/
private void setApplicationSessionCookie(String appSessionCookie) {
sessionCookie = appSessionCookie;
debug("sessionCookie=" + sessionCookie);
}
/**
* Get the application session cookie.
*
* @return The session cookie needed to communicate back to the Vaadin
* application instance.
*/
protected String getApplicationSessionCookie() {
return sessionCookie;
}
/**
* Set the application URL. Called from init.
*
* @param appUrl
*/
private void setApplicationURL(String appUrl) {
applicationURL = appUrl;
debug("applicationURL=" + applicationURL);
}
/**
* Get the application URL.
*
* @return The URL of the Vaadin application.
*/
protected String getApplicationURL() {
return applicationURL;
}
public String getAction() {
return action;
}
public void setAction(String action) {
System.out.println("AbstractVaadinApplet: "+action);
this.action = action;
}
/**
* Debug a string if debugging has been enabled.
*
* @param string
*/
protected void debug(String string) {
if (!isDebug()) {
return;
}
System.err.println("debug: " + string);
}
/**
* Stop the poller and destroy the applet.
*
*/
@Override
public void destroy() {
runPoller = false;
super.destroy();
}
/**
* Invokes vaadin.forceSync that synchronizes the client-side GWT
* application with server.
*
*/
public void vaadinSync() {
jsCallAsync("vaadin.forceSync()");
}
/**
* Invokes vaadin.appletUpdateVariable sends a variable to server.
*
* @param variableName
* @param newValue
* @param immediate
*/
public void vaadinUpdateVariable(String variableName, boolean newValue,
boolean immediate) {
jsCallAsync("vaadin.appletUpdateBooleanVariable('" + getPaintableId()
+ "','" + variableName + "'," + newValue + "," + immediate
+ ")");
}
/**
* Invokes vaadin.appletUpdateVariable sends a variable to server.
*
* @param variableName
* @param newValue
* @param immediate
*/
public void vaadinUpdateVariable(String variableName, int newValue,
boolean immediate) {
jsCallAsync("vaadin.appletUpdateIntVariable('" + getPaintableId()
+ "','" + variableName + "'," + newValue + "," + immediate
+ ")");
}
/**
* Invokes vaadin.appletUpdateVariable sends a variable to server.
*
* @param variableName
* @param newValue
* @param immediate
*/
public void vaadinUpdateVariable(String variableName, double newValue,
boolean immediate) {
jsCallAsync("vaadin.appletUpdateDoubleVariable('" + getPaintableId()
+ "','" + variableName + "'," + newValue + "," + immediate
+ ")");
}
/**
* Invokes vaadin.appletUpdateVariable sends a variable to server.
*
* @param variableName
* @param newValue
* @param immediate
*/
public void vaadinUpdateVariable(String variableName, String newValue,
boolean immediate) {
jsCallAsync("vaadin.appletUpdateStringVariable('" + getPaintableId()
+ "','" + variableName + "','" + newValue + "'," + immediate
+ ")");
}
/*
* TODO: Variable support missing for: String[], Object[], long, float,
* Map<String,Object>, Paintable
*/
/**
* Execute a JavaScript asynchronously.
*
* @param command
*/
public void jsCallAsync(String command) {
JSCallThread t = new JSCallThread(command);
t.start();
}
/**
* Execute a JavaScript synchronously.
*
* @param command
* @throws InterruptedException
*/
public Object jsCallSync(String command) throws InterruptedException {
JSCallThread t = new JSCallThread(command);
t.start();
t.join(MAX_JS_WAIT_TIME);
return t.getResult();
}
/**
* Thread for polling incoming JavaScript commands. Threading is used to
* change the call stack. If an applet function is invoked from JavaScript
* it will always use JavaScript permissions regardless of applet signing.
*
* This thread allows commands to be sent to the applet and executed with
* the applet's privileges.
*
* @author Sami Ekblad
*/
public class JsPollerThread extends Thread {
private static final long POLLER_DELAY = 100;
private String jsCommand;
private Object[] jsParams;
@Override
public void run() {
debug("Poller thread started.");
while (runPoller) {
// Check if a command was received
String cmd = null;
Object[] params = null;
synchronized (pollerLock) {
if (jsCommand != null) {
cmd = jsCommand;
params = jsParams;
jsCommand = null;
jsParams = null;
debug("Received JavaScript command '" + cmd + "'");
}
}
if (cmd != null) {
doExecute(cmd, params);
}
try {
Thread.sleep(POLLER_DELAY);
} catch (InterruptedException e) {
}
}
debug("Poller thread stopped.");
}
}
/**
* Thread for executing outgoing JavaScript commands. This thread
* implementation is used to asynchronously invoke JavaScript commands from
* applet.
*
* @author Sami Ekblad
*
*/
public class JSCallThread extends Thread {
private String command = null;
private Object result = null;
private boolean success = false;
/**
* Constructor
*
* @param command
* Complete JavaScript command to be executed including
*/
public JSCallThread(String command) {
super();
// SE: We need to remove all line changes to avoid exceptions
this.command = command.replaceAll("\n", " ");
}
@Override
public void run() {
debug("Call JavaScript '" + command + "'");
String jscmd = command;
try {
Method getWindowMethod = null;
Method evalMethod = null;
Object jsWin = null;
Class<?> c = Class.forName("netscape.javascript.JSObject");
Method ms[] = c.getMethods();
for (int i = 0; i < ms.length; i++) {
if (ms[i].getName().compareTo("getWindow") == 0) {
getWindowMethod = ms[i];
} else if (ms[i].getName().compareTo("eval") == 0) {
evalMethod = ms[i];
}
}
// Get window of the applet
jsWin = getWindowMethod.invoke(c,
new Object[] { AbstractVaadinApplet.this });
// Invoke the command
result = evalMethod.invoke(jsWin, new Object[] { jscmd });
if (!(result instanceof String) && result != null) {
result = result.toString();
}
success = true;
debug("JavaScript result: " + result);
}
catch (InvocationTargetException e) {
success = true;
result = e;
debug(e);
} catch (Exception e) {
success = true;
result = e;
debug(e);
}
}
/**
* Get result of the execution.
*
* @return
*/
public Object getResult() {
return result;
}
/**
* Get the result of execution as string.
*
* @return
*/
public String getResultAsString() {
if (result == null) {
return null;
}
return (String) (result instanceof String ? result : result
.toString());
}
/**
* Get the exception that occurred during JavaScript invocation.
*
* @return
*/
public Exception getException() {
return (Exception) (result instanceof Exception ? result : null);
}
/**
* Check if the JavaScript invocation was an success.
*
* @return
*/
public boolean isSuccess() {
return success;
}
}
public void setDebug(boolean debug) {
boolean change = this.debug != debug;
this.debug = debug;
if (change) {
debug("" + isDebug());
}
}
public void debug(Exception e) {
if (!isDebug()) {
return;
}
System.err.println("debug: Exception " + e);
e.printStackTrace();
}
public boolean isDebug() {
return debug;
}
/**
* Execute method that should be invoked from a JavaScript. This invokes a
* second thread (with applet's permission) to execute the command.
*
* @param command
* @param params
*/
public void execute(String command) {
execute(command, null);
}
/**
* Execute method that should be invoked from a JavaScript. This invokes a
* second thread (with applet's permission) to execute the command.
*
* @param command
* @param params
*/
public void execute(String command, Object[] params) {
if (pollerThread == null) {
debug("Poller thread stopped. Cannot execute: '" + command + "'");
return;
}
synchronized (pollerLock) {
pollerThread.jsCommand = command;
pollerThread.jsParams = params;
}
}
/**
* Function to to actually execute a specific command.
*
* The inheriting applet must implement this to execute commands sent from
* JavaScript.
*
* Implementation may be empty if no JavaScript initiated commands are
* supported.
*
* @param command
*/
protected abstract void doExecute(String command, Object[] params);
}
Screenshot addon:
-paintContent() line target.addUploadStreamVariable(this, "stream") removed and line
target.addVariable(this, VAppletIntegration.ATTR_APPLET_ACTION,getStreamVariable()) added.
getStreamVariable() is method from Upload.class
With those changes I got in action parameter path for http post method, so in ScreenShot applet I replaced postUrl with action which is something like http://localhost:8080/app_name/APP/UPLOAD/PID*/action/*
Applet init() method:
added
action = getAction();
Applet doPostToServer() method:
PostMethod filePost = new PostMethod(postUrl); replaced with PostMethod filePost = new PostMethod(action);
Finally it works :)
I hope this is helpful :D
I think I found a couple of bugs in the Applet integration AddOn.
1)
If I update several variables and syncronize them afterwards, then sometimes not all variables are sent.
Example:
vaadinUpdateVariable("var1", "value", false);
vaadinUpdateVariable("var2", "value", false);
vaadinUpdateVariable("var3", "value", false);
vaadinUpdateVariable("var4", "value", false);
vaadinSync();
...sometimes it work. Sometimes one of them is missing when data is recieved serverside.
2)
If data contains backslashes then they tend to dissappear:
Example:
vaadinUpdateVariable("path", "\\server\folder", false);
..then on the serverside I get: "\\serverfolder"
...but temporarily this fixes the bugs:
1)
try {
Thread.sleep(50);
} catch (InterruptedException ex) { }
vaadinSync();
2)
@Override
public void vaadinUpdateVariable(String variableName, String newValue, boolean immediate) {
super.vaadinUpdateVariable(variableName, escapeString(newValue), immediate);
}
private String escapeString(String text) {
text = text.replace("\"", "\\\"");
text = text.replace("\\", "\\\\");
text = text.replace("\n", "\\n");
return text;
}