API updates

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

API updates

aalmiray
Administrator
Hello everyone,

Just to let you know that yesterday night during Zurich Hackergarten we added a new concept to the `Application` interface, based on a exchange Tom Schindl and I had at JavaOne: the ability of `shutdown` to return a value that can be used to signal `System.exit`.

Other updates include:
 - file headers and some javadoc.
 - full definition for MessageSource and NoSuchMessageSourceException.

Please comment on these new updates. My next goal is to document all these new updates in the spec before the end of the year.

Cheers,
Andres
Reply | Threaded
Open this post in threaded view
|

Re: API updates

Hendrik Ebbers
Why is "boolean canShutdown()" defined in the Application interface and the ExitState Interface?
Reply | Threaded
Open this post in threaded view
|

Re: API updates

doychin
In reply to this post by aalmiray
HI,

I can't find anything in the list where to check the progress of your work. I only found link to github, but there is no changes for the last 10 months.

Is there a web site where I can look at the changes you do ?

thanks in advance

On 3.12.2015 г. 10:02 ч., aalmiray [via jsr377-api] wrote:
Hello everyone,

Just to let you know that yesterday night during Zurich Hackergarten we added a new concept to the `Application` interface, based on a exchange Tom Schindl and I had at JavaOne: the ability of `shutdown` to return a value that can be used to signal `System.exit`.

Other updates include:
 - file headers and some javadoc.
 - full definition for MessageSource and NoSuchMessageSourceException.

Please comment on these new updates. My next goal is to document all these new updates in the spec before the end of the year.

Cheers,
Andres


If you reply to this email, your message will be added to the discussion below:
http://jsr377-api.40747.n7.nabble.com/API-updates-tp168.html
To start a new topic under jsr377-api, email [hidden email]
To unsubscribe from jsr377-api, click here.
NAML


-- 
Doychin Bondzhev
dSoft-Bulgaria Ltd.
PowerPro - billing & provisioning solution for Service providers
PowerStor - Warehouse & POS
http://www.dsoft-bg.com/
Mobile: +359888243116

doychin.vcf (280 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: API updates

aalmiray
Administrator
In reply to this post by Hendrik Ebbers
Good catch. During the discussing we had a `canShutdown()` or `canExit()` method on the `ExitState` interface because the reasoning was that implementors will issue a call to`Application.shutdown()` which would call `Application.canShutdown()`. But later we changed our mind to have `Application.canShutdown()` be called at any time from anywhere, if the result was `true` then `Application.shutdown()` can be called "safely".

However there lies the problem. Implementors may ignore calls to `Application.canShutdown()` and go directly with `Application.shutdown()`, which will be very bad, as `ShutdownHandlers` wont be called at all!

But if `Application.canShutdown()` is called by `Application.shutdown()` then we need an `ExitState` that signals shutdown was aborted (at least one `ShutdownHandler` returned falseform its `canShutdown()`). Perhaps `ExitState.canShutdown()` should be renamed to `ExitState.canExit()`.

Thoughts?
Reply | Threaded
Open this post in threaded view
|

Re: API updates

aalmiray
Administrator
In reply to this post by doychin
Our work at the ML and the github repository has been very slow indeed. Apologies for that.
However we're rekindling the interest in the JSR and making efforts to push information at a constant and steady pace starting this month.

You're more than welcome to join the discussions :-)
Reply | Threaded
Open this post in threaded view
|

Re: API updates

Hendrik Ebbers
In reply to this post by aalmiray
As far as I understand your description this would end in 3 methods that checks the shutdown:
Application.canShutdown()
ShutdownHandler.canShutdown() (method still missing)
ExitState.canShutdown() (will be renamed in canExit())

For me this looks too complex at the first moment. In addition I ask myself what ExitState.exitCode() returns if ExitState.canExit() returns false?

How would an implementation look like? Does a container call a 3 methods (checks the application, iterate over all handlers and then check the exit state)? Or will Application.canShutdown() normally iterate over all handlers and returns false if a handler returns false?
Reply | Threaded
Open this post in threaded view
|

Re: API updates

Hendrik Ebbers
Talking about shutdown handlers. I think it would make sense to add 2 methods:
boolean canShutdown()
void shutdown()

In this case each dialog / MVG group can register a handler that will be called before shutdown (for example to show a save dialog own shutdown) and on shutdown (autosave, disconnects, etc.).

If the Application now provides a "ExitState shutdown()" method this can internally iterate over all handlers and first checks if the app can be shutdown. If all handlers return "true" the shutdown() method is called for all handlers. If any method call throws an exception the ExitState.exitCode() will return a value != 0. If any canShutdown() method of the handlers return false the ExitState.canShutdown() will return false and the application won't be closed.
Reply | Threaded
Open this post in threaded view
|

Re: API updates

aalmiray
Administrator
Just noticed I didn't commit the latest changes as I thought, where `ShutdownHandler`sports those missing methods you mention Hendrik.

Here's a bit more of information regarding `ExitHandler`and its current design:

It's desirable for an application to specify a hint to the calling process regarding its exist status. Usually in POSIX environments this status (an integer) is used to determine a successful shutdown or some other condition. Tom brought the subject during JavaOne, letting us know that Eclipse RPC uses this number to signal other conditions such as restart.

The JSR can't know for sure which numbers should be used to signal exit conditions because those numbers have application specific semantics, thus we thought it would be better to provide an abstraction that would let developers or frameworks decide what an exist state would be, at the same time expecting an integer value to be used by `System.exit()`. This is the meaning of the `exitCode` method.

Implementing frameworks would have to provide the following workflow for the shutdown sequence:

  void quitTheApplication() {
      if(canShutdown()) {
          ExitCode code = shutdown();
          System.exit(code.exitCode());
      }
  }

Thus the typical implementation for `canShutdown` and `shutdown` would be something like this

  boolean canShutdown() {
    // ask all ShutdownHandlers
  }

  ExitCode shutdown() {
    // invoke all ShutdownHandlers and calculate an ExitCode
  }

As you can see the important method is `quitTheApplication` while the other two are hooks into the shutdown sequence. One solves the question "can the application quit?" while the other provides the behavior of what to do if the application does quit. I'd leaning towards having `shutdown` behave like `quitTheApplication` and have a 3rd method named `onShutdown` (mirroring `ShutdownHandler`)  to take care of the quit behavior. So we could end up with the following scheme:

  class Application {
     void shutdown()
     boolean canShutdown()
     ExitCode onShutdown()
  }

  class ShutdownHandler {
     boolean canShutdown()
     ExitCode onShutdown()
  }


Given the repetition we could argue that `Application` may extend `ShutdownHandler` and be treated in a special way by the framework, that is, the application instance is registered as a shutdown handler with itself, making sure it's the first handler and that it cannot be unregistered for example.
What bothers me about this approach is the fact that a developer may call `canShutdown` and `onShutdown` on the application instance at any time, while I'd wish they could only call `shutdown`.

Thoughts?
Reply | Threaded
Open this post in threaded view
|

Re: API updates

Hendrik Ebbers
I see several problems here since developers will create custom implementations of the Application interface. By doing so they can implement the methods in any way. By doing so maybe the "shutdown()" or "onShutdown()" methods never call the handlers. I think the lifecycle should be defined by the JSR. To do so we need something like an ApplicationHandler.

ApplicationHandler.shutdown(Application a);

The handler calls the "boolean canShutdown()" for all ShutdownHandlers and if all return "true" it will call the "onShutdown" for all handlers. In that case the Application Interface can extend the ShutdownHandler interface and will automatically called as the first handler (or maybe as the last? - Could be configured by an enum). In this case the big question is how the exit code will be calculated. This is application / framework specific.
Maybe we can do something like this (that is far away from a good API and only a raw idea):

Interface ExitCodeMerge {

     int createExitCode(int... exitCodes);
}
 
Enum ShutdownOrder {
     START_WITH_APP, END_WITH_APP;
}


//General configuration
ApplicationHandler.configureExitCodeMerge(ExitCodeMerge merge);
ApplicationHandler.configureShutdown(ShutdownOrder order);

//Application based configuration
ApplicationHandler.configureExitCodeMerge(Application application, ExitCodeMerge merge);
ApplicationHandler.configureShutdown(Application application, ShutdownOrder order);

//Shutdown an application
ApplicationHandler.shutdown(Application a);

It's defined that ApplicationHandler.shutdown(..) calls the "canShutdown()" for the application and all handlers (order defined by the enum) and then calls "onShutdown()" for the application and all handlers (order defined by the enum). All the exitCodes that are returned from the "onShutdown()" calls will be merged to one global exit code by using the "ExitCodeMerge" instance.

Reply | Threaded
Open this post in threaded view
|

Re: API updates

aalmiray
Administrator
Indeed. If we only deliver interfaces then anyone is free to implement said interfaces in the way they deem fit. This means a framework may provide a custom base implementation for the Application interface (which handles ShutDownHandler correctly) while at the same time a developer may implement said interface in a totally different manner.

The thing is, the framework should be compliant to the TCK if it wants to advertise itself as an inplementation of JSR377, so we can ensure the behavior is correct. The developer on the other hand is free to choose his own path, so he may or may not apply the TCK to his own application if he chooses to write his own impls instead of choosing a "sanctioned" framework.

The first situation is what's expected of implementors, so that case is covered. The second case is not covered and already exists, see for example Afterburnerfx and JSR330. Afterburnerfx provides a minimalist implementation of JSR330 but does not claim to be TCK compliant. Is Afterburnerfx doing "the wrong thing" here by skipping TCK compliance? Is it a broken or incomplete implementation of JSR330? Frankly it doesn't matter too much as long as the framework stays true to its offerings. Then we've got Eclipse platform4 which also bends some of the rules of JSR330 mixed with @Optional, @PreDestroy, and @PostConstruct.

My point is, we can't stop developers from creating their own implementations that may break the specified contracts. So, how much do we close down the APIs while making sure they are usable enough is the interesting question. A balancing act after all.

Regarding the exit code merge strategy, that's definitely application specific. That strategy would have to be defined somewhere, and probably injected at the right time.

If the `Application` interface provides the aforementioned 3 methods

    void shutdown()
    boolean canShutdown()
    ExitCode onShutdown()

then I'd expect their behavior to be along the following lines

   void shutdown() {
       if(canShutdown()) {
          ExitCode code = onShutdown();
          System.exit(code.exitCode());
       }
   }

   boolean canShutdown() {
     for(ShutdownHandler sh : resolveShutdownHandlers()) {
         if(!sh.canShutdown()) return false;
     }
     return true;
   }

   ExitCode onShutdown() {
     ExitCode code = null; // or a fw specific constant such as ExitCodes.SUCCESS
     for(ShutdownHandler sh : resolveShutdownHandlers()) {
         code = sh.onShutdown(code);
     }
     return code != null ? code : ExitCodes.SUCCESS;
   }

Notice how this versions expects an ExitCode to be sent to each `ShutdownHandler` when calling its `onShutdown` method; in this way the handler can do the merge on the go.