Java thread.getContext().getClassLoader() uniqueness - java

How unique is the thread context's classloader. Is it reset everytime a thread is started?
Can we always be sure that 2 parallel threads will never have the same context classloader?
I see some frameworks like Axis relying on this to get and set run-time setting variables.

How unique is the thread context's classloader.
Not even remotely.
Is it reset everytime a thread is started?
When a thread is created, it doesn’t have context loader that can be reset. It will inherit the parent thread’s context loader. Starting the thread doesn’t change its context loader.
Can we always be sure that 2 parallel threads will never have the same context classloader?
That would be actually very unlikely. As said, threads inherit the parent’s loader by default, so unless someone calls setContextClassLoader explicitly with a different loader, the default application class loader, as returned by ClassLoader.getSystemClassLoader() will be the used by all threads. Even in environments with different class loaders, it’s unlikely to have as much class loaders as threads.
I see some frameworks like Axis relying on this to get and set run-time setting variables.
It’s the main use of the feature, frameworks using the current thread’s context class loader by convention, but of course, for loading classes and resources, not to assume uniqueness of these loaders. The JVM never uses this context class loader on its own, as symbolic references found in a class are resolved through the defining class loader of that class. The same applies for Class.forName(String) (without a class loader argument). It requires code actively invoking getContextClassLoader() and using the returned loader for class loading, to make this feature relevant.
Don’t confuse class loaders with ThreadLocal variables.

Related

Should JavaDelegate classes for Camunda BPM be thread safe?

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.

Is it safe to keep a reference to a thread in a singleton?

Let me give you the scenario.
Say that my first Activity that loads up, also creates a thread, which will run indefinitely in the background.
Now, if I move to another Activity, I assume that the thread that I initially created in the main activity will continue to run.
So, now to my main question - in order to manage this background thread from other Activities, is it safe to store a reference to that thread in a singleton object?
Yes and no. Theoretically, you will have no problem, but you must not allow references to escape.
Problems can arise from keeping the reference in the singleton object private, it must not pass the reference to anything else or allow access to it by anything else, or it can lose control.
Secondly, the thread created by your activity must not allow access to its member variables or allow references to them to escape.
A good book on this area is "Java Concurrency in Practice" by Brian Goetz
Actually where you need to be careful is if you have multiple class loaders. A Singleton is only a singleton if you are using the same class loader to load the class in. If you have multiple class loaders in your app running the same classes you will have another instance of the singleton in each.
Most standalone apps only use one classloader and therefore do not have any issues. If you have only one classloader then you will be fine.

Singletons vs. Application Context in Android?

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.

Can the thread context class loader be null?

I'm not entirely sure how I got to this situation but somehow I'm getting a null ClassLoader from Thread.getContextClassLoader. After reading a little (not much info in the docs nor on google) I got the impression that it's valid for the current thread to have a null class loader, and calls to getContextClassLoader should be checked for a null reference.
This is quite surprising since I've seen a couple of open source projects unchecked calls to getContextClassLoader (which got me to checking this in the first place). Specifically, this line in codemodel: JCodeModel.java line 358
(I just verified that log4j doesn't check as well)
So should calls to getContextClassLoader check for a null reference or is something messed up with my threads?
It's quite valid for Thread.getContextClassLoader to return null. Not all software is of particularly good quality.
Whilst null ClassLoader typically refers to the boot class loader that loads the system classes (I think that's right - the terminology is messed up for historical reasons), for thread context class loaders it is usually interpreted as unset, and the system class loader is used instead.
IIRC, the thread context class loader is set to the system class loader for the main thread if using the java command. For applets the applet thread and EDT have it set to the applet class loader.
I would suggest not using thread context class loaders (or most other thread locals), unless the context requires it.
As Tom says, it is perfectly valid for Thread.getContextClassLoader() to return null. I vaguely recall that the default behaviour has changed over time (or it could have been different in various JVM vendor implementations - I can't remember).
Assuming a non-null context ClassLoader may be valid if you've set one further up the stack and don't have foreign code in between, or if the class/library contract requires one.
As a side note, Class.getClassLoader() can return null too.

How can I identify in which Java Applet context running without passing an ID?

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?

Categories