Reputation: 13
I am trying to call an external windows application (i.e. calc.exe) when a user clicks on a button in a GWT web application. Is there a way on how to do it?
Below are what I have already tried so far:
1.) Tried Runtime.exec and ProcessBuilder but I end up having a GWT compile error
Runtime.exec Code:
Process winCalc;
try {
winCalc = Runtime.getRuntime().exec("\"C:/Windows/System32/calc.exe\"");
winCalc.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
Runtime.exec Code - GWT Compile Error:
Rebinding dir.ClientGinjector
Checking rule <generate-with class='org.jsonmaker.gwt.rebind.JsonizerGenerator'/>
[ERROR] Errors in 'file:/C:/Users/blahblah/framework/Toolbar.java'
[ERROR] Line 962: No source code is available for type java.lang.Process; did you forget to inherit a required module?
[ERROR] Line 964: No source code is available for type java.lang.Runtime; did you forget to inherit a required module?
[ERROR] Line 969: No source code is available for type java.lang.InterruptedException; did you forget to inherit a required module?
[ERROR] Unable to find type 'dir.ClientGinjector'
[ERROR] Hint: Previous compiler errors may have made this type unavailable
[ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly
[ERROR] Errors in 'file:/C:/Users/blahblah/gin/ClientGinjector.java'
[ERROR] Line 60: Failed to resolve 'dir.ClientGinjector' via deferred binding
ProcessBuilder Code:
ProcessBuilder pbWinCalc = new ProcessBuilder ("C:/Windows/System32/calc.exe");
try {
Process pWinCalc = pbWinCalc.start();
System.out.println("[dan]: pWinCalc.exitValue() = " + pWinCalc.exitValue());
} catch (IOException e) {
System.out.println("[dan]: stacktrace = " + e.getMessage().toString());
}
ProcessBuilder Code - GWT Compile Error:
Rebinding dir.ClientGinjector
Checking rule <generate-with class='org.jsonmaker.gwt.rebind.JsonizerGenerator'/>
[ERROR] Errors in 'file:/C:/Users/blahblah/framework/Toolbar.java'
[ERROR] Line 974: No source code is available for type java.lang.ProcessBuilder; did you forget to inherit a required module?
[ERROR] Line 977: No source code is available for type java.lang.Process; did you forget to inherit a required module?
[ERROR] Unable to find type 'dir.ClientGinjector'
[ERROR] Hint: Previous compiler errors may have made this type unavailable
[ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly
[ERROR] Errors in 'file:/C:/Users/blahblah/gin/ClientGinjector.java'
[ERROR] Line 60: Failed to resolve 'dir.ClientGinjector' via deferred binding
2.) Tried calling ProcessBuilder in a separate class that extends RemoteServiceServlet as per suggestion in this link (GWT + ProcessBuilder).
ProcessBuilder Code:
import java.io.IOException;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
public class WinCalcServiceImpl extends RemoteServiceServlet {
private static final long serialVersionUID = 7495421224005326634L;
public void getWinCalculator(){
//Dan - Using ProcessBuilder
final ProcessBuilder pbWinCalc = new ProcessBuilder ("C:/Windows/System32/calc.exe");
try {
final Process pWinCalc = pbWinCalc.start();
System.out.println("[dan]: pWinCalc.exitValue() = " + pWinCalc.exitValue());
} catch (final IOException e) {
System.out.println("[dan]: stacktrace = " + e.getMessage().toString());
}
// p.waitFor();
}
}
ProcessBuilder - GWT Compile Error:
Rebinding com.gwtplatform.dispatch.shared.DispatchService
Invoking generator com.google.gwt.user.rebind.rpc.DlServiceInterfaceProxyGenerator
Running DLProxyCreator
[ERROR] An internal compiler exception occurred
com.google.gwt.dev.jjs.InternalCompilerException: Failed to get JNode
at com.google.gwt.dev.jjs.impl.TypeMap.get(TypeMap.java:140)
at com.google.gwt.dev.jjs.impl.TypeMap.get(TypeMap.java:71)
at com.google.gwt.dev.jjs.impl.BuildTypeMap.getType(BuildTypeMap.java:730)
at com.google.gwt.dev.jjs.impl.BuildTypeMap.process(BuildTypeMap.java:814)
at com.google.gwt.dev.jjs.impl.BuildTypeMap.access$700(BuildTypeMap.java:99)
at com.google.gwt.dev.jjs.impl.BuildTypeMap$BuildDeclMapVisitor.process(BuildTypeMap.java:325)
at com.google.gwt.dev.jjs.impl.BuildTypeMap$BuildDeclMapVisitor.visit(BuildTypeMap.java:244)
at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.traverse(TypeDeclaration.java:1198)
at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.traverse(CompilationUnitDeclaration.java:687)
at com.google.gwt.dev.jjs.impl.BuildTypeMap.createPeersForNonTypeDecls(BuildTypeMap.java:637)
at com.google.gwt.dev.jjs.impl.BuildTypeMap.exec(BuildTypeMap.java:514)
at com.google.gwt.dev.jjs.impl.BuildTypeMap.exec(BuildTypeMap.java:523)
at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler.precompile(JavaToJavaScriptCompiler.java:599)
at com.google.gwt.dev.jjs.JavaScriptCompiler.precompile(JavaScriptCompiler.java:33)
at com.google.gwt.dev.Precompile.precompile(Precompile.java:284)
at com.google.gwt.dev.Precompile.precompile(Precompile.java:233)
at com.google.gwt.dev.Precompile.precompile(Precompile.java:145)
at com.google.gwt.dev.Compiler.run(Compiler.java:232)
at com.google.gwt.dev.Compiler.run(Compiler.java:198)
at com.google.gwt.dev.Compiler$1.run(Compiler.java:170)
at com.google.gwt.dev.CompileTaskRunner.doRun(CompileTaskRunner.java:88)
at com.google.gwt.dev.CompileTaskRunner.runWithAppropriateLogger(CompileTaskRunner.java:82)
at com.google.gwt.dev.Compiler.main(Compiler.java:177)
[ERROR] <no source info>: public class com.google.gwt.user.server.rpc.RemoteServiceServlet
extends com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet
implements : com.google.gwt.user.server.rpc.SerializationPolicyProvider
/* fields */
private final [unresolved] java.lang.Object delegate
private final [unresolved] Map<java.lang.String,Unresolved type com.google.gwt.user.server.rpc.SerializationPolicy> serializationPolicyCache
/* methods */
public void <init>()
[unresolved] public void <init>(java.lang.Object)
[unresolved] protected void checkPermutationStrongName() throws Unresolved type java.lang.SecurityException
[unresolved] protected Unresolved type com.google.gwt.user.server.rpc.SerializationPolicy doGetSerializationPolicy(Unresolved type javax.servlet.http.HttpServletRequest, java.lang.String, java.lang.String)
[unresolved] private Unresolved type com.google.gwt.user.server.rpc.SerializationPolicy getCachedSerializationPolicy(java.lang.String, java.lang.String)
[unresolved] public final Unresolved type com.google.gwt.user.server.rpc.SerializationPolicy getSerializationPolicy(java.lang.String, java.lang.String)
[unresolved] static Unresolved type com.google.gwt.user.server.rpc.SerializationPolicy loadSerializationPolicy(Unresolved type javax.servlet.http.HttpServlet, Unresolved type javax.servlet.http.HttpServletRequest, java.lang.String, java.lang.String)
[unresolved] protected void onAfterResponseSerialized(java.lang.String)
[unresolved] protected void onBeforeRequestDeserialized(java.lang.String)
[unresolved] public java.lang.String processCall(java.lang.String) throws Unresolved type com.google.gwt.user.client.rpc.SerializationException
public final void processPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) throws java.io.IOException, javax.servlet.ServletException, com.google.gwt.user.client.rpc.SerializationException
[unresolved] private void putCachedSerializationPolicy(java.lang.String, java.lang.String, Unresolved type com.google.gwt.user.server.rpc.SerializationPolicy)
[unresolved] protected boolean shouldCompressResponse(Unresolved type javax.servlet.http.HttpServletRequest, Unresolved type javax.servlet.http.HttpServletResponse, java.lang.String)
[unresolved] private void writeResponse(Unresolved type javax.servlet.http.HttpServletRequest, Unresolved type javax.servlet.http.HttpServletResponse, java.lang.String) throws java.io.IOException
org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding
[ERROR] at WinCalcServiceImpl.java(7): class WinCalcServiceImpl
com.google.gwt.dev.jjs.ast.JClassType
Upvotes: 1
Views: 2761
Reputation: 46841
Use Java Applet to call an external application in GWT using JSNI
.
Please have a look at below links for sample code.
Invoking Applet Methods From JavaScript Code
Call Java Applet function from Javascript
How to call Applet method from javascript
Upvotes: 0
Reputation: 13
I see. Thanks for the answers guys. I'm still a newbie in GWT. Your answers helped me understand more about GWT and how it compiles classes to javascript as well as the idea behind why webapp should not be allowed access to local resources. However, I think there are still exceptions though depending on the need and scenarios; in my case, my webapp is only used and accessed in a closed group/network and not for public/anyone's use.
For anyone who is also interested, What I did is I created a javascript code that uses an ActiveXObject implementation to run the external apps, in my case a windows calculator. Then using this code, I run this in an IE browser since only IE fully supports ActiveX implementation.
I haven't tried Braj's suggestion above but I think it's also one alternative that will work. Maybe I'll try playing with that approach this weekend.
Upvotes: 0
Reputation:
A webapp should not and can not call a local program..
GWT compiles client classes to javascript and there's no support for Runtime
, so GWT doesn't know how to transform your Runtime
usage to JS.
For a list of GWT supported classes (client side), see http://www.gwtproject.org/doc/latest/RefJreEmulation.html
Upvotes: 2
Reputation: 41089
You cannot do it. Browsers do not allow access to executable files on a user's computer. It would have been a dream-come-true for every hacker out there.
Upvotes: 2