Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

how to make a singleton and how to store state using services?

Avatar

Level 9

in the AEM java code, you have filters, servlets and services.

 

services are defined like this:

 

@Component(service = SomeService.class)

public class SomeServiceImp implements SomeService {

   

Is this a singleton? can it store state (assume not)?  Is it thread safe (assume not)? 

Are there any tutorials out here?  There are pages of information about OSGI architecture, how to manage lifecycles, bundleActivators, repositories etc, but little I can find about how services really work at the java business logic level. 

 

1. How would you build a service which stores state, for a) the whole application, ob b) for a request?

E.g. a http request to a servlet which makes several calls to a services which need an auth token to make calls to a backend API.  CAching of the auth token could be managed in the servlet, but this makes the servlet have to know about underlying implementation, and less secure.  How would several independent calls to a services method access a "cached" admin token, which is valid for that servlet request (well, its also valid across all requests for a period of time, but thats another caching problem).  

 

Maybe OSGI does not offer any support for state and different scopes (global/request/single)?

 

2. Why would we use OSGI services over singleton classes normal objects in AEM cloud?  There is nothing dynamic about AEM cloud in that you have to have Adobe build and deploy your entire code base as a single monolithic application every time (which takes 1-2 hours to build and deploy to each env).  Bundles are under the hood, but not usable on their own in the AEM dev process (with AEM cloud) that I have seen, unless I am missing something?  If you host yourself, you can build and deploy bundles and edit osgi settings dynamically, but not with cloud.   I also assume that there is no distributed architecture here - a servlet running in a cloud env will be calling its services hosted on the same cloud env in the same process. Or does AEM cloud distribute your codes services across different servers?

 

 

 

 

 

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

 

Services (or better) components are singletons in the first place. You can create multiple instances of them if you use service factories.

 

Regarding state: Of course you can store state but you are responsible to manage that state, also including concurrency. Services are no threadsafe by default.

 

To your question:

 

1 How do I store state for a whole application?

You should use a dedicated storage (database, sling repository, ...; it could even be an in-memory store, but of course that use is limited).

 

2 How do I store state for during a request?

Create a server-side session (with all its implications) or manage it via

request.setRequestAttribute("foo", data);
Object data = request.getRequestAttribute("foo")

 

3 Why OSGI?

AEM is build on the OSGI architecture model, and its extension points are exported via OSGI services. I am not aware of a different way to use these APIs. OSGI is not only about dynamically loading and unloading bundles and services, but also has strong contracts about services.

 

 

 

 

 

 

 

View solution in original post

2 Replies

Avatar

Level 9

I found this resource: http://blog.vogella.com/2017/02/13/control-osgi-ds-component-instances/

Its complicated.  

There does not seem to be an obvious way to scope per http request (ie.. per servlet).  There is a scope called PROTOTYPE and one called PROTOTYPE_REQUIRED, but its not clear what the difference between "once instance per requestor" and "one instance per request", as it does not define what a requestor or request is (a service import request, a service method call request, a http request?).  It also looks like you might have to create your own factories, which adds to the complexity and scope for getting it wrong.

There are almost no examples of a service with http request scope, so we assume its either not possible, or difficult.  The alternative is presumably not using OSGI services for this type of service.

Avatar

Correct answer by
Employee Advisor

 

Services (or better) components are singletons in the first place. You can create multiple instances of them if you use service factories.

 

Regarding state: Of course you can store state but you are responsible to manage that state, also including concurrency. Services are no threadsafe by default.

 

To your question:

 

1 How do I store state for a whole application?

You should use a dedicated storage (database, sling repository, ...; it could even be an in-memory store, but of course that use is limited).

 

2 How do I store state for during a request?

Create a server-side session (with all its implications) or manage it via

request.setRequestAttribute("foo", data);
Object data = request.getRequestAttribute("foo")

 

3 Why OSGI?

AEM is build on the OSGI architecture model, and its extension points are exported via OSGI services. I am not aware of a different way to use these APIs. OSGI is not only about dynamically loading and unloading bundles and services, but also has strong contracts about services.