I have a static object defined in my logging class, along the lines of:
class myLoggingClass {
static java.util.Properties properties;
...
...
}
According to my reference book, this means that the properties object is shared by all instances of my class.
I find this definition insufficient. I'm writing a class that is being invoked more than once in each application on our project.
Further, our project uses several web services running in the same tomcat container. Each web service may have multiple threads.
The Java Virtual Machine running on the host may also run one or more web service client applications, which run external to tomcat.
So by this definition, I may have tomcat running multiple web services with threads, each having several objects, which may contain an instance of my class.
There may also be one or two web clients running outside of tomcat, but within the same JVM. Would all of these instances of my class share the same properties object? That would make it JVM-wide.
If the static object is not JVM-wide, does anyone know at what level each one would exist? One per tomcat container? One per web service, and one per standalone web service client application?
The reason: When I update my properties, I'm getting a java.lang.ConcurrentUpdateException from java.util.Properties.
I'm using a static boolean variable to "lock" the properties object when my class updates it, but this is not keeping the exception from occurring.
This leads me to believe that the static object used in my class may not be at the same scoping level as the one used in java.util.Properties... But that's just a guess.
Thanks for any help.
Statics aren't "shared by all instances of a class" - they're unrelated to instances; they belong to the type itself. In particular, static variables are perfectly usable without any instances being created.
That gives a clue as to the scope of statics: they're scoped by the Class object representing the containing class, which is in turn scoped by the ClassLoader that loaded it.
Depending on where the library is placed, the static variable may be JVM-wide or web-application wide - or possibly something in between, if Tomcat supports multiple hosting (I can't remember offhand).
Look at the Tomcat documentation for how the libraries are laid out and how they relate to class loaders. For example, here's the Tomcat 6.0 ClassLoader how-to guide, and the equivalent for 5.5.
How does your Boolean "lock" work? You should really use a proper lock (synchronized) to make sure that every use of the properties object (both read and write, including locking for the whole period during which you iterate through it) is appropriately locked.
Instead of changing the "live" Properties object, have you considered treating that as immutable - so when you want to update the properties, you take a copy, change that, and then make the copy the "live" version? You'd still need to prevent two different threads from making changes at the same time (or you'd lose some) but it's likely to make the reading side a lot easier and more efficient.
You may find that the scope of such a static variable is limited to one per ClassLoader that has loaded your class. I'm not sure how Tomcat arranges its ClassLoaders, so it's hard to say what the extent of the scope will be in that environment.
The likely cause of your ConcurrentModificationException is that you are iterating thru the values/entries of the Properties object in one thread while another modifies it at the same time. You cannot do this.
Can you elaborate on the locking mechanism that you mention here:
I'm using a static boolean variable to "lock" the properties object when my class updates it, but this is not keeping the exception from occurring.
?
Because it doesn't sound as if you are using the built-in locking and synchronization methods in Java.
Something like this should prevent threads from reading the Properties object while another thread updates it:
static Object lockObject = new Object();
...
synchronized(lockObject) {
// access the Properties object
}
Note that you will need to do this every time you access the Properties object, either to read it or modify it.
Also I would never recommend static objects to share data among all instances or static lockObjects - global data is evil - but it sounds as if you need this for some reason.
Could it be a classloader problem where the jar that contains your class is duplicated in each WEB-INF/lib of your different applications?
If so, I would try to add this jar to Tomcat libs and not to the application.
Related
So I was searching about storing data in one class, and found this. However, that's not what I'm looking for. What I wanted to know about this was whether it's bad practice, can cause performance issues in an application, or if there's another way to do it, etc... (and I'm not doing this on an Android).
Let's say I have a class that stores a HashMap<Enum, Object> and is initialized when I create the class in main.
public Main() {
// Creates the HashMap, initialized in the constructor 'MemoryContainer'
MemoryContainer m = new MemoryContainer();
m.getTestHash().put(SomeEnum.TEST, "Test"); // Using created HashMap
}
Other than casting the value every time I use it, would this cause major issues? If so, is there an alternative?
There's nothing wrong with storing static values in a class, however this is not a good practice.
To store the constants you should create an interface as every field in an interface is already a constant (public static final).
A better approach will be to store these values in properties files, and load them as needed.
A properties file can be stored externally and a person who isn't aware of your source code would be able to modify this properties file if needed. For example you can store database connection details in properties files and if server support admin determines that database instance is down, he/she can edit the properties file to point the application to a new one.
Finally for most flexibility you shouldn't store the configuration inside application at all. It can be stored in a database like MySql or in a fast data structure storage like Redis. This will allow multiple instances of your application to share the configuration data and it will also allow you to modify configuration on the fly by modifying them in the database.
Sometimes a Git repository is also used to store this kind of data (like in case of microservices). Git repository in addition to being shared among all the instances, also maintains the history of modifications.
I would not look too much at performance issues (of course, I do not know what else your application does or wants to do and how it achieves it).
What you should look at first is Mutability - in your example, nothing would stop me from changing the configuration at Runtime by calling
m.getTestHash().put(SomeEnum.TEST, "NotATestAnymore") - this would immediately change the behaviour for every other use of that specific setting.
I am also not sure why you would not just use a configuration class that would directly provide (typed) getters and, if you know all configuration settings at the launch of the app, one constructor containing all the settings.
Do you plan to read the configuration from an outside source (e.g. file)?
NO,
It won't cause major issues.
Also, it is a good practice to keep those variables (HashMap in your case) in a different class away from your main class (which contains your app logic).
I'm using Properties in my code and I'm curious about multiple access.
I'm in the following case :
public Class MClass{
private static Properties dicoCategories = new Properties(myPropertyFile);
public void changeProperties(){
// changing properties and updating the file
}
}
MyClass is instanciated multiple times and each instance can modify the property file
. I guess I could manage this concurrency using temp files and locks, but I would prefer to use an already existing function. However, I found none. My question is : does the Property class manages concurrency a special way, or is there a multi-users equivalent ?
Although the Properties file is thread-safe, if you modify it using multiple invocations you still need to ensure thread safety. e.g.
properties.set(name, value);
is thread-safe, but
if (properties.get(name) == null) {
properties.set(name, value);
}
is not thread-safe without additional guards, and you should synchronise around such sequences.
It's not clear from your question whether your real issue is with multiple processes accessing this properties file, and if that is the case, then perhaps file locking is appropriate. See this question/answer for more info.
According to the documentation:
This class is thread-safe: multiple threads can share a single Properties object without the need for external synchronization.
According to the Java API, it is thread-safe:
http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html
This would mean that you're OK making changes from different threads concurrently. However I would run a simple concurrency test to be 100% sure. You can also go into the source file and see how Java handles it internally...
As per Java documention
This class is thread-safe: multiple threads can share
a single Properties object without the need for external synchronization
So, answer is that you can use the Properties instance in multi-threaded environment.
What you need to keep in mind is that if the updates to Properties are very frequently done, then, it is possible that your application can become slow due to implicit synchronization within Properties. However, if it is once in a while, then you should be fine.
I am building a webcrawler which is using two classes: a downloader class and an analyzer class. Due to my design of the program I had some methods which I outsourced to a static class named utils (finding the link suffix, determining if I should download it given some variables, etc.). Since at a certain time there is more than one downloader and more than one analyzer I'm wondering whether they can get a wrong answer from some static method in the utils class.
For example, say the analyzer needs to know the link suffix - it's using the utils.getSuffix(link) method. At that same time the OS switches to some downloader thread which also needs to get some link suffix and again uses utils.getSuffix(link). Now the OS switches back to the analyzer thread which does not get the correct response.
Am I right?
In case I'm right should I add synchronized to every method on the utils class? Or should I just use the relevant methods in every thread to prevent that kind of scenario even though I'm duplicating code?
This entirely depends on the implementation of the method. If the method uses only local variables and determines the suffix based on the parameter you give it, all is well. As soon as it needs any resource that is accessible from another thread (local variables and parameters are not) you'll need to worry about synchronization.
It seems to me you're using statics as utilities that don't need anything outside their own parameters; so you should be safe :)
After my research and discussion here I decided I need to set the same name for threads on different JVMs which belong to the same control flow in the distributed system. Threads are created e.g. by RMI. Is it possible to set name when thread is created in that way?
There's no automatic means to transfer this info from client-to-server.
It sounds like you want/need some sort of Context object set up on the client (per-thread?) and passed as a method argument to your RMI servers. That Context object could contain not just the thread-name, but perhaps also other info like the calling process pid etc.
You'd then have to use that Context object to set thread-names etc. accordingly via Thread.setName() once it's been passed across the wire. Going forwards, you could set up context-specific info in your logging framework using this (e.g. using Log4j nested diagnostic contexts)
The use of aspects to automate this further is left as a further exercise for the reader :-)
The Thread class has a static method to setName(String). If you can have your threads, wherever they come from, running that method, you should be good to go. These guys had similar issues with Tomcat related threads.
What is the prefered way to manage and distribute configurations to many different class instances of differing class types (in Java)?
In other words, I have an Application class that stores config options in a Configuration class in a static variable. This allows all the other classes in the application to simply call Application.config to fetch config values.
I'd like to allow there to be multiple instances of Application with associated Configuration's per Application instance. This is were I am lost... Is my only option to cascade a Configuration reference to every other class (via constructors and setters)? Or is there another way?
Seems like a single configuration for an Application instance and all it's supporting instances isn't unreasonable, but the requirement to cascade the single configuration reference just seems like such a burden.
Thanks,
Chenz
It sounds like you just found out that what you thought was global state is not really global.
There are several solutions,
the one you outlined,
use a dependency injection framework like Guice to scope configuration.
use ClassLoader voodoo to create multiple "global" configurations in the same VM.
The best solution is really to thread your configuration through manually or via DI, but since you asked for other options, the third solution is to change your main class to create a UrlClassLoader per-instance of the application that points to your jars. This allows you to have multiple different versions of the Application class and its associated Condiguration class side-by-side in the same VM.
EDIT:
To do the classloader voodoo, you main looks something like this
URLClassLoader application1Loader = new ClassLoader(/* URLs to common Jars and the config files for instance 1*/);
URLClassLoader application2Loader = new ClassLoader(/* URLs to common Jars and the config files for instance 2*/);
// Assuming you have a wrapper for your application that you can run() to get it going
// in its own thread via reflection.
Class<? extends Runnable> app1Class = application1Loader.loadClass("my.pkg.MyApplicaion")
.asSubclass(Runnable.class);
// newInstance() is problematic but I want this code to be brief.
app1Class.newInstance().run();
Class<? extends Runnable> app2Class = application2Loader.loadClass("my.pkg.MyApplicaion")
.asSubclass(Runnable.class);
app2Class.newInstance().run();
UPDATE: The my.pkg.MyApplicaion class must not be in the JVM's classpath.
I generally use Spring and define my config in associated XML files, which I load wherever needed using the spring API's.
A quick and dirty method to pass around app config without rewriting all your API's would be to use the singleton pattern. You could get a reference to the config using AppConfig.getInstance() where ever required.
if your objects know what Application they belong to, no problem: just make configuration be non-static.
If your Application instances are separate threads, no problem: put configuration on ThreadLocal
If there is some kind of namespace associated with each Application, and child objects know about it, no problem: store a static Map somewhere
if none of the above holds, you're kinda screwed...