I am using Com4J to interact with Microsoft Outlook. I have generated the Java type definitions as per the Com4J tutorial. Here is an example of some code that waits for the user to close an email.
// Registers my event handler
mailItem.advise(
ItemEvents.class,
new ItemEvents() {
#Override
public void close(Holder<Boolean> cancel) {
// TODO Auto-generated method stub
super.close(cancel);
System.out.println("Closed");
}
}
);
// Displays the email to the user
mailItem.display();
This code successfully displays the email to the user. Unfortunately, my program never prints "Closed" when the user closes the window.
When Com4J generates an event class (ItemEvents in my scenario), the default behavior for all generated methods is to throw an UnsupportedOperationException (see the com4j.tlbimp.EventInterfaceGenerator class for details).
For example, here is the close method of the ItemEvents class that my anonymous class overrides:
#DISPID(61444)
public void close(Holder<Boolean> cancel) {
throw new UnsupportedOperationException();
}
Therefore, when my anonymous class calls super.close(cancel);, the parent class throws an UnsupportedOperationException, preventing execution from reaching my System.out.println("Closed"); statement. Therefore, my anonymous class should really have looked like this:
mailItem.advise(
ItemEvents.class,
new ItemEvents() {
#Override
public void close(Holder<Boolean> cancel) {
System.out.println("Closed");
}
}
);
What surprised me is that Com4J appears to have simply ignored the UnsupportedOperationException thrown from the event handler altogether, leaving me no indication of what actually happened. I wrote this code to demonstrate:
mailItem.advise(
ItemEvents.class,
new ItemEvents() {
#Override
public void close(Holder<Boolean> cancel) {
System.out.println("Getting ready to throw the exception...");
throw new RuntimeException("ERROR! ERROR!");
}
}
);
The program emits this output:
Getting ready to throw the exception...
However, there is no indication that a RuntimeException was ever thrown.
Related
When Tomcat session times out, I want to redirect my user to the homepage of my GWT app, so that they can login again. To force this, I'm trying to use the StatusCodeException thrown by GWT when the user tries to perform any operation after their session times out -
SEVERE: com.google.gwt.user.client.rpc.StatusCodeException: 0
To achieve this, I'm using the following code -
public void onModuleLoad() {
GWT.UncaughtExceptionHandler uncaughtExceptionHandler = new GWT.UncaughtExceptionHandler() {
public void onUncaughtException(Throwable e) {
if (e instanceof StatusCodeException) {
logger.log(Level.ERROR, "Exception caught!");
logger.log(Level.ERROR, ((StatusCodeException) e).getStatusCode());
}
}
};
GWT.setUncaughtExceptionHandler(uncaughtExceptionHandler);
try {
// rest of the code in onModule() - I'm expecting any operation to throw StatusCodeException when session times out.
} catch (RuntimeException ex) {
uncaughtExceptionHandler.onUncaughtException(ex);
}
}
This is not working. Instead of getting caught by the code, the StatusCodeException is being displayed on the console. What am I doing wrong here?
The idea is to catch StatusCodeException and use its getStatusCode() method to find out if the HTTP error code is 403. If it is, I want to use Window.Location.assign("https://example.com/redirect"); to redirect them to a login page.
onFailure(Throwable caught) {
logger.error(caught);
}
Your AsyncCallback.onFailure is doing exactly what you asked it to do - it is logging the error, but not throwing it. Since it wasn't thrown, the uncaught exception handler doesn't handle it (it can't be not-caught, if it wasn't thrown... if that makes sense).
One option could be that you could populate the method with throw caught, but java won't like this. Instead, the easiest answer to your specific on is simply to pass it to the handler:
onFailure(Throwable caught) {
GWT.getUncaughtExceptionHandler().onUncaughtException(ex);
}
One other option you have: since no AsyncCallback will ever throw this, putting the StatusCodeException in the UncaughtExceptionHandler seems a bit odd. Instead, consider making your own AsyncCallback base class, something like this:
public abstract class NetworkAsyncCallback<T> implements AsyncCallback<T> {
#Override
public void onFailure(Throwable t) {
if (e instanceof StatusCodeException) {
logger.log(Level.ERROR, "Exception caught!");
logger.log(Level.ERROR, ((StatusCodeException) e).getStatusCode());
}
}
}
Now, when you make a call, you just have to pass in a new NetworkAsyncCallback<T> and only implement onSuccess. You can skip onFailure if all it was going to do was pass the exceptions to the uncaught handler. Or, if you have some other logic, you can override onFailure, handle the appropriate exceptions, and call super.onFailure(caught) with any other errors so that the superclass handles it.
myServer.getSomeData(param, new NetworkAsyncCallback<Result>() {
#Override
public void onSuccess(Result result) {
//...
}
// Skip onFailure, or if you need custom logic, implement it,
// and call super only if the exception isn't part of that logic
});
I'm new to Java & its design patterns, I have a scenario like this:
Method 1 calls Method 2.
Method 2 looks like the following:
public String createUser(String username, String password) {
someApi.do(config -> {
//code here with respect to someApi.
});
}
now the trick is I need to return the value to caller which is method 1. If there are no exceptions then that is fine. However the code block inside do can throw exception, which will be handled in a separate listener class like this:
public class TestListener implements SomeApiListener {
#Override
public void exception(Throwable cause) {
}
}
Now how should I send back the exception to method 1 from this listener? I'm really confused.
it's not clear what that API do, where the listener is assigned, and what other methods it has, like if there is also onSuccess() ?
what i got from this, is that, you are dealing with async call, which usually do not return a value directly, it deals with a CallBack which in your case is SomeApiListener
So, ... I would make createUser() receives extra arg, SomeApiListener, pass the listener as anonymous inner class (with implementation) when calling the method (from caller).
ex,
public String createUser(String username, String password, SomeApiListener listener) {
someApi.do(config -> {
//code here with respect to someApi.
//somewhere here you are creating a TestListener ?,
//well... don't, and use the one passed from caller (listener)
});
}
Caller part will look like this:
public void method1(){
//..some code ...
createUser(username, password, new SomeApiListener(){
#Override
public void exception(Throwable cause) {
//handle exception...
}
#Override
public void success(Response response) {
//handle response ...
}
});
}
Note: you can still pass TetstListern, if you want, in that case you will have to have a physical class (local class) defined and instantiated, the anonymous-inner-class is somehow a shortcut for that, you don't create a local class, just pass it as an arg.
You can't, at least not in any simple way. I'd expect the documentation for your someApi to demonstrate some common use cases, with exception handling included. If you're combining different ways of programming ("normal" java & functional programming), you can get into tricky situations.
Based on the information you've given, a clumsy solution could look something like this (code obviously not fit for compilation):
public class MyClass implements SomeApiListener {
private Throwable e;
public void exception(Throwable cause) {
e = cause;
}
public void method1() {
createUser("foo", "bar");
if(e != null) {
// Exception was thrown, do something with it
}
}
}
However this is in no way a recommendation. It's clumsy, hacky and bad in every way. A better solution would involve not trying to send the exception back to method1, but instead to modify your code to work in the way that someApi expects.
It depends on your design on how to handle exceptions. Normally, if the method 2 is an utility method then throw the exception back to method 1 and let it handle the exception. Else, if method 2 understands the use case for which it is called then handle the exception there. There are no hard and fast rules, but keep the utility classes clean and send the exception back to the caller so that caller can handle it.
I'm building a SWING application and also need to write a custom SecurityManager. If I write an empty class which extends SecurityManager like this
public class Sandbox extends SecurityManager {}
it works fine, meaning that the GUI is rendered correctly and all privileges like I/O are revoked.
However I need to customize the checkPermission method and whenever I override it nothing works anymore...
Why even something like this shouldn't work??
public class Sandbox extends SecurityManager {
#Overide
public void checkPermission(Permission perm) {
super.checkPermission(perm);
}
}
Update: a very basic example that shows the problem is this
public static void main(String[] args) {
System.setSecurityManager(new SecurityManager() {
#Override
public void checkPermission(Permission p) {
if (some_condition_here) {
// Do something here
} else {
// Resort to default implementation
super.checkPermission(p);
}
}
});
new JFrame().setVisible(true);
}
Removing the "checkPermission" method the application works correctly, but I really can't get my head around this.
The permissions are granted based on all the code on the stack. All callers must have the required permission. If you override the method and call the superclass method, your code is on the stack as well which implies that your codebase (where your custom SecurityManager belongs to) must have the permission you (your callers) ask for.
That’s the difference between overriding or not. If you don’t override that method only the (possibly privileged) caller’s code is on the stack and it will get the requested permission. If you override that method your code is also on the stack and must have the permission as well.
So if you want to implement a custom SecurityManager which invokes the inherited check method you must configure the inherited (policy based) logic to give your SecurityManager all permissions it should be able to grant. It’s recommended to separate the SecurityManager from the rest of the application into a different codebase so only the SecurityManager and nothing else gets the generous permissions.
If you call the superclass' checkPermission(p) you didn't have to override the class in the first place. Comment it out, then it works.
The superclas' calls java.security.AccessController.checkPermission(perm) and that seems to throw a java.security.AccessControlException, when not invoked by java.lang.SecurityManager
in my case it says:
Could not load Logmanager "null"
java.security.AccessControlException: access denied (java.util.PropertyPermission java.util.logging.manager read)
etc.
public class SecurityManagerExample
{
public static void main(String[] args)
{
System.setSecurityManager(new SecurityManager()
{
#Override
public void checkPermission(Permission p)
{
//super.checkPermission(p);
}
});
new JFrame().setVisible(true);
}
}
I found a tutorial on how to write a security manager. I'd also recommend you to go through the java doc and the examples provided by oracle.
UPDATE
Take a look at the method summary and override the functionality you want to forbid.
As I found out you also need to explicitly allow the functionality you want to have.
Here an example:
public class SecurityManagerExample
{
public static void main(String[] args)
{
System.setSecurityManager(new SecurityManager()
{
#Override
public void checkWrite(String file) {
// no exception is thrown, i. e. creating files is allowed in general
}
#Override
public void checkDelete(String file)
{
if (file.equals("test.xml"))
{
throw new SecurityException("Not allowed to delete test.xml!");
}
}
});
File f = new File("test.xml");
try
{
f.createNewFile();
}
catch (IOException e)
{
}
f.delete();
}
}
OUTPUT
Exception in thread "main" java.lang.SecurityException: Not allowed to delete test.xml!
at main.SecurityManagerExample$1.checkDelete(SecurityManagerExample.java:60)
at java.io.File.delete(File.java:902)
at main.SecurityManagerExample.main(SecurityManagerExample.java:74)
I want to override the global Exception Handling in my RCP app. Whenever an uncaught Exception happens I want to log it (using java logging) and then exit the app. I have already overwritten the eventLoopException(Throwable exception) method in the ApplicationWorkbenchAdvisor class. But this catches only the event loop exceptions. As of now I have also overwritten the postStartup() method like this:
public void postStartup()
{
Policy.setStatusHandler(new StatusHandler()
{
#Override
public void show(IStatus status, String title)
{
LOGGER.log(Level.SEVERE, "Uncaught Exception", status.getException());
UnexpectedErrorDialog();
PlatformUI.getWorkbench().close();
}
});
}
It logs the exception in my log file and exits the app. But it's obviously not right and the exception is shown twice in the console, cause all I do is intercepting the showing of the exception in a gui dialog to the user. So how can I properly overwrite/change the global exception handling, so that my code (log) is used instead of the default one?
I would suggest you to use org.eclipse.ui.statusHandlers extension point
Thanks to sambi reddy's tip i have now overwritten AbstractStatusHandler in the ApplicationWorkbenchAdvisor class
#Override
public synchronized AbstractStatusHandler getWorkbenchErrorHandler() {
if (myStatusHandler == null) {
myStatusHandler = new MyStatusHandler();
}
return myStatusHandler;
}
MyStatusHandler extends AbstractStatusHandler and i have overwritten the handle method like this:
#Override
public void handle(StatusAdapter statusAdapter, int style)
{
if(statusAdapter.getStatus().matches(IStatus.ERROR) && ((style != StatusManager.NONE)))
{
LOGGER.log(Level.SEVERE, "Uncaught Exception", statusAdapter.getStatus().getException());
UnexpectedErrorDialog();
PlatformUI.getWorkbench().close();
}
}
seems to work right, only downside is that i still get 2 console outputs.
In my program, I connect to an interpreter process for another language. I need the program sometimes to ask the interpreter several things and use it's response.
The process is stored in a IProcess variable and the communication is done via the IStreamsProxy of the process. to recieve the response, I added an IStreamListener to the IStreamsProxy.
However, when I write to the IStreamsProxy (with the write() method), I need the code to wait for the response, e.g. the streamAppend-method of the listener to be called.
I tried to use the wait() and notify() method, but I don't know on what objects I should call them.
The query class which makes the communication calls a method like this:
/**
* Sends a command to the interpreter. Makes the current thread wait for an answer of the interpreter.
* #throws IOException
*/
private synchronized void send(String command) throws IOException{
this.s48Proxy.write(command);
try {
System.out.println("waiting for reply");
this.wait();
} catch (InterruptedException e) {
System.out.println("interruption exception: "+e.getMessage());
}
}
and the listener:
private class Listener implements IStreamListener {
private Query query;
public Listener(Query query) {
super();
this.query = query;
}
#Override
public void streamAppended(String arg0, IStreamMonitor arg1) {
System.out.println("got interpreter answer");
query.setCurrentOutput(arg0.substring(0, arg0.lastIndexOf("\n")).trim());
query.notify();
}
}
The streamAppend() method calls the notify()-method on the query class. However, this does not work. "Waiting for reply" is the last response I get.
How can I do this? Or are there any other methods I could use to achieve this automatically?
You could use Object#wait & Object#notifiy.
// # IStreamsProxy
synchronized( someMonitor ) {
someMonitor.wait( /* time? */ );
}
// # Listener
synchronized( someMonitor ) {
someMonitor.notify();
}
-> Javadoc Link
Use a semaphore like boolean waitingForResponse. Set this to true when you make your call, then go into
while(waitingForResponse){
sleep(99) //should be your average response time from your call
}
In your listener, set waitinForResponse to false.