The main question is about static fields and singleton instances (for configs, etc.) - are instances of one process running in different threads, as usual servlet requests?
If look deeper - do different #ProcessApplication run in one JVM and will see the same singletons? I don't think so. I know exactly that their classes don't see each other and can have equal names (because of different classLoaders?)
Haven't found any meaningful info on these important themes about Camunda, will appreciate your answers.
I had this same question for one of our scenario while back, and read their Javadoc as mentioned here for a servlet container. Extracting Javadoc,
Invocation Semantics
When the {#link #execute(java.util.concurrent.Callable)} method is
invoked, the servlet process application modifies the context
classloader of the current Thread to the classloader that loaded the
application-provided subclass of this class. This allows,
the process engine to resolve {#link JavaDelegate} implementations using the classloader of the process application
This pretty much explain everything you want to know, since the behavior is very similar to how a web container operates. If you want to know how other container implementations behaves, you can check the respective Javadocs of classes in this package.
To answer your question:
Yes. Thread-safety is required for the shared-resources accessed by JavaDelegate in the same process application. According to the documentation (see below) they create a new instance of delegate each time a task is going to be executed.
Note!
Each time a delegation class referencing activity is executed, a
separate instance of this class will be created. This means that each
time an activity is executed there will be used another instance of
the class to call execute(DelegateExecution).
Therefore, at any time there can be many delegate instances actively running due to the multiple invocation of Process Definitions. So, if they are accessing a shared resource, then they need to be synchronized (thread-safe), because, that shared resources (static or singleton) is local to the process application and loaded by respective application classloader according to above Invocation Semantics Javadoc.
Hope this helps.
One of my Android apps uses a custom Application class to perform some global initialization. This done in the onCreate() method:
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
someCustomInit();
}
}
This works fine, but now I have discovers a crash log in the Developer Console which indicated that MyApplication.onCreate() did not run / has not completed at the time the crash happened: The code crashed because some initialization that is performed MyApplication.onCreate() was not complete.
How is this possible? I assumed that MyApplication.onCreate() would run before all other code? Isn't that correct?
Is it save to move someCustomInit(); to the constructor of MyApplication instead? No other code should run before the application object has been created, correct?
Or are there any side effects from using the constructor instead of onCreate()?
I assumed that MyApplication.onCreate() would run before all other code? Isn't that correct?
ContentProvider instances are created before onCreate() is called on the Application. In theory, your stack trace should show you what code of yours is being invoked prior to your initialization.
Is it save to move someCustomInit(); to the constructor of MyApplication instead?
That would depend on what is happening in someCustomInit(). Your Application is not initialized yet.
Another possibility is to override attachBaseContext(), such as how ACRA is hooked in. There, you are passed a Context object that you can use, if your initialization requires a Context.
The Application class is a singleton for your app process, but its onCreate() is not the first possible code to execute. Class field initializers, the constructor as well as any static code blocks (often used for loading native libs) will execute first. The static code blocks, in particular, will run when the class is loaded by the runtime.
Normally, this is not a problem and your safest route is to put your specific code in the onCreate() method.
How is this possible?
It is possible since Application class onCreate is called for every process of your app.
For example Service can be started in separate process so your Application can be started twice. I have met this behaviour when used Yandex.Appmetrica library. It is not bad actually, because crashes in library will not affect other parts of application.
Or are there any side effects from using the constructor instead of
onCreate()?
From the documentation:
The Application class, or your subclass of the Application class, is
instantiated before any other class when the process for your
application/package is created.
So constructor will be called twice. Any difference?
You should move your code that supposed to run only once to somewhere else, outside Application class. Probably in some Singleton which will be called from Launcher Activity or smth. Actually if you see sources of Application class you will see that comment:
There is normally no need to subclass Application. In most situations,
static singletons can provide the same functionality in a more modular
way.
I'm currently working with an application that does some heavy computational work. It has been ported from C to Java years ago and it shows a bit. Among others it uses public static variables to share data between classes.
The work is very suited for parallelizing as multiple files are processed and every file can be done completely independ of others. But just starting multiple threads doesn't work because of the static variables. I would like to prevent a rewrite because the classes are quite fast, mature and bug-free.
Is there an easy way for me to start multiple threads/processes from within the java program wherein each thread will have it's own copy of the static variables or will I have to resort to just calling the JVM multiple times by executing commands?
Yes, You can use multiple class loaders, or start multiple processes.
However, I suggest just fixing the code, it would be much simpler. Make all the static fields, non static and have a ThreadLocal variable which hold the instance copy for that thread.
Recalling this post enumerating several problems of using singletons
and having seen several examples of Android applications using singleton pattern, I wonder if it's a good idea to use Singletons instead of single instances shared through global application state (subclassing android.os.Application and obtaining it through context.getApplication()).
What advantages/drawbacks would both mechanisms have?
To be honest, I expect the same answer in this post Singleton pattern with Web application, Not a good idea! but applied to Android. Am I correct? What's different in DalvikVM otherwise?
EDIT: I would like to have opinions on several aspects involved:
Synchronization
Reusability
Testing
I very much disagree with Dianne Hackborn's response. We are bit by bit removing all singletons from our project in favor of lightweight, task scoped objects which can easiliy be re-created when you actually need them.
Singletons are a nightmare for testing and, if lazily initialized, will introduce "state indeterminism" with subtle side effects (which may suddenly surface when moving calls to getInstance() from one scope to another). Visibility has been mentioned as another problem, and since singletons imply "global" (= random) access to shared state, subtle bugs may arise when not properly synchronized in concurrent applications.
I consider it an anti-pattern, it's a bad object-oriented style that essentially amounts to maintaining global state.
To come back to your question:
Although the app context can be considered a singleton itself, it is framework-managed and has a well defined life-cycle, scope, and access path. Hence I believe that if you do need to manage app-global state, it should go here, nowhere else. For anything else, rethink if you really need a singleton object, or if it would also be possible to rewrite your singleton class to instead instantiate small, short-lived objects that perform the task at hand.
I very much recommend singletons. If you have a singleton that needs a context, have:
MySingleton.getInstance(Context c) {
//
// ... needing to create ...
sInstance = new MySingleton(c.getApplicationContext());
}
I prefer singletons over Application because it helps keep an app much more organized and modular -- instead of having one place where all of your global state across the app needs to be maintained, each separate piece can take care of itself. Also the fact that singletons lazily initialize (at request) instead of leading you down the path of doing all initialization up-front in Application.onCreate() is good.
There is nothing intrinsically wrong with using singletons. Just use them correctly, when it makes sense. The Android framework actually has a lot of them, for it to maintain per-process caches of loaded resources and other such things.
Also for simple applications multithreading doesn't become an issue with singletons, because by design all standard callbacks to the app are dispatched on the main thread of the process so you won't have multi-threading happening unless you introduce it explicitly through threads or implicitly by publishing a content provider or service IBinder to other processes.
Just be thoughtful about what you are doing. :)
From: Developer > reference - Application
There is normally no need to subclass Application. In most situation,
static singletons can provide the same functionality in a more modular
way. If your singleton needs a global context (for example to register
broadcast receivers), the function to retrieve it can be given a
Context which internally uses Context.getApplicationContext() when
first constructing the singleton.
Application is not the same as the Singleton.The reasons are:
Application's method(such as onCreate) is called in the ui thread;
singleton's method can be called in any thread;
In the method "onCreate" of Application,you can instantiate Handler;
If the singleton is executed in none-ui thread,you could not
instantiate Handler;
Application has the ability to manage the life cycle of the
activities in the app.It has the method
"registerActivityLifecycleCallbacks".But the singletons has not the
ability.
I had the same problem: Singleton or make a subclass android.os.Application?
First I tried with the Singleton but my app at some point makes a call to the browser
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
and the problem is that, if the handset doesn't have enough memory, most of your classes (even Singletons) are cleaned to get some memory so, when returning from the browser to my app, it crashed everytime.
Solution: put needed data inside a subclass of Application class.
Consider both at the same time:
having singleton objects as static instances inside the classes.
having a common class (Context) that returns the singleton instances for all the singelton objects in your application, which has the advantage that the method names in Context will be meaningful for example: context.getLoggedinUser() instead of User.getInstance().
Furthermore, I suggest that you expand your Context to include not only access to singleton objects but some functionalities that need to be accessed globally, like for example: context.logOffUser(), context.readSavedData(), etc. Probably renaming the Context to Facade would make sense then.
They're actually the same.
There's one difference I can see. With Application class you can initialize your variables in Application.onCreate() and destroy them in Application.onTerminate(). With singleton you have to rely VM initializing and destroying statics.
From the proverbial horse's mouth...
When developing your app, you may find it necessary to share data, context or services globally across your app. For example, if your app has session data, such as the currently logged-in user, you will likely want to expose this information. In Android, the pattern for solving this problem is to have your android.app.Application instance own all global data, and then treat your Application instance as a singleton with static accessors to the various data and services.
When writing an Android app, you're guaranteed to only have one instance of the android.app.Application class, and so it's safe (and recommended by Google Android team) to treat it as a singleton. That is, you can safely add a static getInstance() method to your Application implementation. Like so:
public class AndroidApplication extends Application {
private static AndroidApplication sInstance;
public static AndroidApplication getInstance(){
return sInstance;
}
#Override
public void onCreate() {
super.onCreate();
sInstance = this;
}
}
My 2 cents:
I did notice that some singleton / static fields were reseted when my activity was destroyed. I noticed this on some low end 2.3 devices.
My case was very simple : I just have a private filed "init_done" and a static method "init" that I called from activity.onCreate(). I notice that the method init was re-executing itself on some re-creation of the activity.
While I cannot prove my affirmation, It may be related to WHEN the singleton/class was created/used first. When the activity get destroyed/recycled, it seem that all class that only this activity refer are recycled too.
I moved my instance of singleton to a sub class of Application. I acces them from the application instance. and, since then, did not notice the problem again.
I hope this can help someone.
My activity calls finish() (which doesn't make it finish immediately, but will do eventually) and calls Google Street Viewer. When I debug it on Eclipse, my connection to the app breaks when Street Viewer is called, which I understand as the (whole) application being closed, supposedly to free up memory (as a single activity being finished shouldn't cause this behavior). Nevertheless, I'm able to save state in a Bundle via onSaveInstanceState() and restore it in the onCreate() method of the next activity in the stack. Either by using a static singleton or subclassing Application I face the application closing and losing state (unless I save it in a Bundle). So from my experience they are the same with regards to state preservation. I noticed that the connection is lost in Android 4.1.2 and 4.2.2 but not on 4.0.7 or 3.2.4, which in my understanding suggests that the memory recovery mechanism has changed at some point.
I'm part of a team that develops a pretty big Swing Java Applet. Most of our code are legacy and there are tons of singleton references. We've bunched all of them to a single "Application Context" singleton. What we now need is to create some way to separate the shared context (shared across all applets currently showing) and non-shared context (specific to each applet currently showing).
However, we don't have an ID at each of the locations that call to the singleton, nor do we want to propagate the ID to all locations. What's the easiest way to identify in which applet context we're running? (I've tried messing with classloaders, thread groups, thread ids... so far I could find nothing that will enable me to ID the origin of the call).
Singletons are evil, what do you expect? ;)
Perhaps the most comprehensive approach would be to load the bulk of the applet in a different class loader (use java.net.URLClassLoader.newInstance). Then use a WeakHashMap to associate class loader with an applet. If you could split most of the code into a common class loader (as a parent of each per-applet class loader) and into the normal applet codebase, that would be faster but more work.
Other hacks:
If you have access to any component, you can use Component.getParent repeatedly or SwingUtilities.getRoot.
If you are in a per-applet instance thread, then you can set up a ThreadLocal.
From the EDT, you can read the current event from the queue (java.awt.EventQueue.getCurrentEvent()), and possibly find a component from that. Alternatively push an EventQueue with a overridden dispatchEvent method.
If I understand you correctly, the idea is to get a different "singleton" object for each caller object or "context".
One thing you can do is to create a thread-local global variable where you write the ID of the current context. (This can be done with AOP.) Then in the singleton getter, the context ID is fetched from the thread-local to use as a key to the correct "singleton" instance for the calling context.
Regarding AOP there should be no problem using it in applets since, depending on your point-cuts, the advices are woven at compile time and a JAR is added to the runtime dependencies. Hence, no special evidence of AOP should remain at run time.
#Hugo regarding threadlocal:
I thought about that solution. However, from experiments I found two problems with that approach:
Shared thread (server connections, etc) are problematic. This can be solved though by paying special attention to these thread (they're all under my control and are pretty much isolated from the legacy code).
The EDT thread is shared across all applets. I failed to find a way to force the creation of a new EDT thread for each applet. This means that the threadlocal for the EDT would be shared across the applets. This one I have no idea how to solve. Suggestions?