Sometimes I get an error (exception):
java.lang.IllegalStateException: Dispatch not hooked to windows memory
What does it mean? How to prevent it?
This is a sample code that results in this error:
import com.jacob.activeX.*;
import com.jacob.com.*;
public class Hooked {
public static void main(String[] args) {
ActiveXComponent e = new ActiveXComponent("Excel.Application");
ActiveXComponent sh = new ActiveXComponent(
e.getProperty("ActiveSheet").toDispatch());
System.out.println(sh.getPropertyAsString("Name"));
}
}
That means that Dispatch = nothing using vba syntax, it's empty. The same dispatch that you receive with new Dispatch(). Unfortunately Jacob 1.17 does not provide any method to explicitly check whether the Dispatch is empty or not. So I see 3 possible solutions:
1) Use Variant.isNull() after receiving the Variant from COM call, before converting it to Dispatch. So it requires 1 additional line:
Variant vsh = e.getProperty("ActiveSheet");
if (vsh.isNull()) {
System.out.println("Null dispatch received.");
}
ActiveXComponent sh = new ActiveXComponent(vsh.toDispatch());
2) Catch IllegalStateException when using suspected Dispatch for the first time.
3) Write a custom isNull(Dispatch d) function
public static boolean isNull(Dispatch d)
{
try {
Dispatch.call(d, "");
}
catch (IllegalStateException ise) {
return true;
}
catch (ComFailException cfe) {
// that's ok, we didn't expect this call to succeed
}
return false;
}
In the specific example in the question the call was just a mistake, because Excel has no ActiveSheet if no workbook is open or created.
Related
Im trying to use olingo with Flutter on Android. I set up my channel and I can call the library but I keep getting this message:
E/AndroidRuntime(28391): FATAL EXCEPTION: main
E/AndroidRuntime(28391): Process: com.example.odata, PID: 28391
E/AndroidRuntime(28391): org.apache.olingo.client.api.http.HttpClientException: android.os.NetworkOnMainThreadException
E/AndroidRuntime(28391): at org.apache.olingo.client.core.communication.request.AbstractODataRequest.doExecute(AbstractODataRequest.java:312)
So it looks like it is running on the main thread - which is a no go as this would block. I tried the looper to ask Java to run on the UI Thread:
public void onMethodCall(MethodCall call, Result result) {
// Note: this method is invoked on the main thread.
Log.i("test", "using " + call.method);
String serviceUrl = "http://services.odata.org/OData/OData.svc/";
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
if (call.method.equals("getMetaData")) {
String metadata;
final Edm edm = ODataClientFactory.getClient().getRetrieveRequestFactory().getMetadataRequest(serviceUrl).execute().getBody();
metadata = edm.toString();
if (metadata != "") {
result.success(metadata);
} else {
result.error("UNAVAILABLE", "Metadata cannot read.", null);
}
} else {
result.notImplemented();
}
}
});
But Im still getting the same error.
So how exactly can I deal with external JAR Library which are doing blocking operations ? To my understanding an external call is a Future anyway so it will not block my Flutter thread anyway - but Android Java does not think so ...
This is my method call in flutter
Future<void> _getMetaData() async {
String metadata;
try {
final String result = await platform.invokeMethod('getMetaData');
metadata = result;
} on PlatformException catch (e) {
metadata = e.message;
}
setState(() {
_metadata = metadata;
});
}
Thanks for the answer, this is the solution for anyone that may be interested:
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("getMetaData")) {
class MetadataLoader extends AsyncTask<String , Integer, String> {
#Override
protected String doInBackground(String... urls) {
// call your Java library method here, including blocking methods
return your_return_value;
}
protected void onPostExecute(String _result) {
// your_return_value is now passed in _result
result.success(_result);
}
}
new MetadataLoader().execute(); // Start the Async
}
On the flutter side,
Future<void> _getMetaData() async {
String metadata;
try {
final String result = await platform.invokeMethod('getMetaData');
// do something with the result
// the Flutter thread will stop at the await and resume when the Java
// will call result.success
}
}
You will need to create a new Java thread or Worker. (Note that the "main" thread and the "UI" thread are the same thing - so by posting to the main looper you've ended up in the same place - trying to do network i/o on the main thread.)
Yes, the Flutter engine is running in different threads, but you still need to leave the main native thread unblocked as it is responsible for detecting user input, etc.
Also note that when your blocking activity completes - on its non-main thread - it will likely want to deliver the response to Dart. To do this it will need to use part of your code above - to post the results back to the main thread, which can then invoke method channel operations.
You'll probably want to use your method channel bi-directionally. From flutter to native to request an operation (returning, say, a sequence number), and from native to flutter to deliver the results (quoting the sequence number so that the result can be tied back to the request).
I'm trying to learn Threads and Tasks for days now ... but still can't implement it in my app ... help plz.
I want to run all Database operations in a background thread other than the application thread.
I have a class that manages the Database queries ... in this class i surrounded the executeQuery statement with a task:
public class Database {
ResultSet rs;
public ResultSet execQuery(PreparedStatement stmnt) throws SQLException {
Task<ResultSet> task = new Task<ResultSet>() {
#Override protected ResultSet call() throws Exception {
if (isCancelled()) {
}
ResultSet execRs = stmnt.executeQuery();
return execRs;
}
};
task.run();
task.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
#Override
public void handle(WorkerStateEvent event) {
rs = task.getValue();
}
});
return rs;
}
// remaining Code
}
As you can see the method should return a ResultSet but when i call this from another place it raise a null pointer ... the result set returned by this method is null.
So what did i do wrong here?
Update #1
#James_D Thank you for this great link ... i think i finally understand the concept ... but still have a small problem with implementing it ... for example in my authentication method after the user is authenticated i want to check if that user has an open shift ... so following your link i changed the method to this:
private boolean isShiftOpen(int userId, int branchId, int comId) throws SQLException, ClassNotFoundException {
// final boolean success = false;
Task<Shift> task = new Task<Shift>(){
#Override
protected Shift call() throws Exception {
return ShiftDAO.getShift(userId, branchId, comId);
}
};
task.setOnFailed(e -> {
System.out.println("isShiftOpenTask Faild!!");
success = false;
});
task.setOnSucceeded(e -> {
System.out.println("isShiftOpenTask Succeeded!!");
Shift shift1 = task.getValue();
System.out.println("User Open Shift Exists ... returning true");
SessionBean.setShiftId(shift1.getShiftId());
SessionBean.setUserId(shift1.getUserId());
SessionBean.setUserBranch(branchId);
success = true;
});
exec.execute(task);
return success;
}
I have two problems:
1- The exec.execute(task) raise a nullpoint exception.
2- I wanted to use a boolean variable returned by this method ... the only way i could access such a variable is to define it outside the method ... but then if i want to use another method like this one i must declare another boolean variable for it to ... does this sound right to you?
Thank you for your time
Gado
You call
task.run();
which executes the task on the current thread, i.e. that statement will not complete until the task finishes. Then you call
task.setOnSucceeded(...);
which essentially says "when the task succeeds, set the instance variable rs to the result of the task. However, by the time you call this, the task has already succeeded (or possibly failed), so there is no way for the handler to be invoked.
You could fix the null result by reversing the order of these calls, i.e. do
public ResultSet execQuery(PreparedStatement stmnt) throws SQLException {
Task<ResultSet> task = new Task<ResultSet>() {
#Override protected ResultSet call() throws Exception {
if (isCancelled()) {
}
ResultSet execRs = stmnt.executeQuery();
return execRs;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
#Override
public void handle(WorkerStateEvent event) {
rs = task.getValue();
}
});
task.run();
return rs;
}
However, since you are executing the task on the current thread, it's not really clear what the point of using a task at all is: you may as well just execute the database query directly in your execQuery method and return the result directly. In other words, the above code is equivalent to
public ResultSet execQuery(PreparedStatement stmnt) throws SQLException {
rs = stmnt.executeQuery();
return rs;
}
Good night guys!
I'm having the following problem ...
I have a web application that runs a "thread" that takes messages from the queue (MSMQ) ... Everything works correctly .. the problem is when I get this message, I can not display .. because the method that returns the message content is a "static" ..
I need to perform a function in JS to display this message.
conclusion:
The method "ProcessMessage" can not be named because he is not a static method ...
My main goal is to call a function in JS passing as parameter (m.Body.ToString ()) which is the content of the message.
Can anyone help me?
Thank you for sharing your knowledge!
This is my code.
public void StartThread()
{
try
{
while (true)
{
PrepareQueue();
}
}
catch (Exception)
{ }
}
public static void PrepareQueue()
{
MessageQueue myQueue = new MessageQueue(".\\private$\\CTIQueue");
myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });
// Add an event handler for the ReceiveCompleted event.
myQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(MyReceiveCompleted);
// Define wait handles for multiple operations.
WaitHandle[] waitHandleArray = new WaitHandle[10];
for (int i = 0; i < 10; i++)
{
// Begin asynchronous operations.
waitHandleArray[i] = myQueue.BeginReceive().AsyncWaitHandle;
}
// Specify to wait for all operations to return.
WaitHandle.WaitAll(waitHandleArray);
return;
}
private static void MyReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult)
{
try
{
Thread.Sleep(2000);
MessageQueue mq = (MessageQueue)source;
// End the asynchronous receive operation.
System.Messaging.Message m = mq.EndReceive(asyncResult.AsyncResult);
ProcessMessage(m.Body.ToString()); <-- MY PROBLEM
}
catch (MessageQueueException)
{ }
return;
}
public void ProcessMessage(string message)
{
ScriptManager.RegisterStartupScript(this, GetType(), "popup", "NewCaller('" + message + "');", true);
}
Why not instantiate an object of the class and call ProcessMessage on it? Static methods can instantiate an object of the enclosing class and invoke instance methods on it.
private static void MyReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult)
{
try
{
Thread.Sleep(2000);
MessageQueue mq = (MessageQueue)source;
// End the asynchronous receive operation.
System.Messaging.Message m = mq.EndReceive(asyncResult.AsyncResult);
new MyClass().ProcessMessage(m.Body.ToString()); <-- MY PROBLEM
}
catch (MessageQueueException)
{ }
return;
}
But if you are planning to invoke a client side code from server side, with reactive action happening at the server's end(which I think is your case) -- then I would prefer you use ASP.NET SignalR to signal the client that something interesting has happened at the server's end.
I'm making a small game in LibGDX. I'm saving the player's username locally as well as on a server. The problem is that the application is not waiting for the result of the call so the online database's ID is not saved locally. Here's the overall flow of the code:
//Create a new user object
User user = new User(name);
//Store the user in the online database
NetworkService networkService = new NetworkService();
String id = networkService.saveUser(user);
//Set the newly generated dbase ID on the local object
user.setId(id);
//Store the user locally
game.getUserService().persist(user);
in this code, the id variable is not getting set because the saveUser function is returning immediately. How can I make the application wait for the result of the network request so I can work with results from the server communication?
This is the code for saveUser:
public String saveUser(User user) {
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("action", "save_user");
parameters.put("json", user.toJSON());
HttpRequest httpGet = new HttpRequest(HttpMethods.POST);
httpGet.setUrl("http://localhost:8080/provisioner");
httpGet.setContent(HttpParametersUtils.convertHttpParameters(parameters));
WerewolfsResponseListener responseListener = new WerewolfsResponseListener();
Gdx.net.sendHttpRequest (httpGet, responseListener);
return responseListener.getLastResponse();
}
This is the WerewolfsResponseListener class:
class WerewolfsResponseListener implements HttpResponseListener {
private String lastResponse = "";
public void handleHttpResponse(HttpResponse httpResponse) {
System.out.println(httpResponse.getResultAsString());
this.lastResponse = httpResponse.getResultAsString();
}
public void failed(Throwable t) {
System.out.println("Saving user failed: "+t.getMessage());
this.lastResponse = null;
}
public String getLastResponse() {
return lastResponse;
}
}
The asynchrony you are seeing is from Gdx.net.sendHttpRequest. The methods on the second parameter (your WerewolfsResponseListener) will be invoked whenever the request comes back. The success/failure methods will not be invoked "inline".
There are two basic approaches for dealing with callbacks structured like this: "polling" or "events".
With polling, your main game loop could "check" the responseListener to see if its succeeded or failed. (You would need to modify your current listener a bit to disambiguate the success case and the empty string.) Once you see a valid response, you can then do the user.setId() and such.
With "events" then you can just put the user.setId() call inside the responseListener callback, so it will be executed whenever the network responds. This is a bit more of a natural fit to the Libgdx net API. (It does mean your response listener will need a reference to the user object.)
It is not possible to "wait" inline for the network call to return. The Libgdx network API (correctly) assumes you do not want to block indefinitely in your render thread, so its not structured for that (the listener will be queued up as a Runnable, so the earliest it can run is on the next render call).
I would not recommend this to any human being, but if you need to test something in a quick and dirty fashion and absolutely must block, this will work. There's no timeout, so again, be prepared for absolute filth:
long wait = 10;
while(!listener.isDone())
{
Gdx.app.log("Net", "Waiting for response");
try
{
Thread.sleep(wait *= 2);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static class BlockingResponseListener implements HttpResponseListener
{
private String data;
private boolean done = false;
private boolean succeeded = false;
#Override
public void handleHttpResponse(HttpResponse httpResponse)
{
Gdx.app.log("Net", "response code was "+httpResponse.getStatus().getStatusCode());
data = httpResponse.getResultAsString();
succeeded = true;
done = true;
}
#Override
public void failed(Throwable t)
{
done = true;
succeeded = false;
Gdx.app.log("Net", "Failed due to exception ["+t.getMessage()+"]");
}
public boolean succeeded()
{
return succeeded;
}
public boolean isDone()
{
return done;
}
public String getData()
{
return data;
}
}
I have a function in Flex which has three function in it.
public function update():void
{
A(); \\Dispatches a event with Remote Call
B(); \\Dispatches another event with Remote Call
C();
}
I wan't to call C() after both A() and B() have returned from their call and set particular variables. How can i do that?
If you find yourself doing this often (esp. with more than 2 remote calls), you might want to write your own custom class that handles AsyncTokens from remote calls with a final result() function that is invoked when all remote calls end in success.
If not, since ActionScript is single-threaded, you can just use a local variable to track whether both calls have succeeded.
private var resultFromRemoteCallA:Object;
private var resultFromRemoteCallB:Object;
private function handleRemoteCallA(event:ResultEvent):void {
resultFromRemoteCallA = event.result;
C();
}
private function handleRemoteCallB(event:ResultEvent):void {
resultFromRemoteCallB = event.result;
C();
}
private function C():void {
if (resultFromRemoteCallA && resultFromRemoteCallB) {
// do some thing with the results.
}
}
private function update():void {
resultFromRemoteCallA = resultFromRemoteCallB = null;
A(); B();
}
If you expect null values, you might want to use a boolean variable to track the invocation of the result handler instead.
EDIT: since the author indicated that the dispatch happens in another class, another way to do it would be to pass along a responder and attach it to the AsyncToken like so (in the callee):
private function dispatchRemoteCall(resultHandler:Function, faultHandler: Function): void {
var resultToken: AsyncToken = remoteObject.foo('bar'); // remoteObject may or may not have a result/fault handler
resultToken.addResponder(new mx.rpc.Responder(resultHandler, faultHandler));
}
Then, you can pass along listeners to be invoked when the remote call finishes (at which point you can choose to let the dispatching class store the result or handle it in the caller), like so:
private function update(): void {
classA.dispatchRemoteCall(handleRemoteCallA, handleRemoteCallAFault);
}
If you find yourself doing this a lot, you may also want to look into having a framework do global event routing, like Parsley or Spring Actionscript.