Understanding the practical uses of InitialContext in java? - java

I have worked most on the legacy projects where i spot this line ctx.lookup("datasource"); many number of times. As per usage I have encountered with Initial context , it is used to get the java object binded with some name in webserver/appserver.
For example, we create datasource thru admin console of weblogic then we can use that object programmaticaly in java program with ctx.lookup("datasource"). If I recall correctly I saw this kind of code during EJB implementation also somewhere where some object that was binded with some name in server itself.
Java docs says When the initial context is constructed, its environment is initialized with properties defined in the environment parameter passed to the constructor. So probably the usage I mentioned earlier, Initial context gets constructed with environment parameters(which probably means objects which admin has created in server like datasource, connection pool if any). This is the just one use I could relate initial context.
Please let me know the if it is correct and right usage of initial context class?
Basically with initial context , we can bind/lookup java object with same name. In case of webserver/appserver probably the objects like datasource,connection pool get binded by the server at the time of start up and we can look up them straightaway?

This looks like a correct use of the context class. In newer EJB implementations you can also use the #EJB and #PersistenceContext annotations. For a deeper understanding read the wikipedia article about Dependency Injection.

Related

How to control dependency injection in OSGi at runtime

I'm trying to understand how to control dependency injection in OSGi (specifically Apache Felix as used in Adobe Experience Manager (AEM)). I have a servlet with an #Reference annotation on a field that references an interface -- in my case, it represents a secure document signing provider. I have an implementation class that implements the interface, and it's automatically injected into the servlet.
In the servlet:
#Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private DocumentSigningProvider signingProvider;
...
URL redirectUrl = signingProvider.Sign(...);
and my implementation class:
#Component(metatype=true)
#Service
#Property(name = "service.ranking", intValue = 1000)
public class DocumentSigningProviderDocuSignImpl implements DocumentSigningProvider {
If I write a second implementation, I can control which one is injected via the service.ranking value -- highest number wins. If no ranking is declared on any of the implementations, the oldest wins.
So far, so good -- except that to change the values I need to recompile and redeploy. I need to control this at runtime, or via a configuration file that's tied to the environment or "runmode". I can't see how to do that.
Since the #Component declares metatype=true, #Property annotations within the class generate a control in the OSGi console's GUI. I can use that GUI to change values at runtime. But the service.ranking is declared in an #Property on the class itself, and it doesn't appear to generate a control in the GUI.
In addition, configuration files named after the class provide default values at runtime, and I can have a different config file for each environment or "runmode". This would work for me too; in one environment I can configure a mock implementation, and use a "real" implementation in another environment. But again, these config files seem to work for #Property declarations inside the class, but not on the class.
I've read a number of threads here about this subject but none touch on exposing service.ranking in the OSGi GUI or in config files.
Is there any way to control which class is injected without modifying, re-compiling and re-deploying source code?
In declarative services you can override any service property at runtime by providing a config for the component and setting the property.
So setting service.ranking=1 or similar should actually work.
One thing to note. By default declarative services binds to the first available service and stays with it. So if you want to make sure a service with a higher ranking is used even if it comes later than the one with the lower ranking then you need this option on the consumer side:
#Reference(policyOption=ReferencePolicyOption.GREEDY)
This makes sure DS switches the service if a better one comes later.
If you want to be more specific what service to use on the consumer side you can also use a filter at runtime.
target.signingProvider=(myproperty=myvalue)
I have collected some more hints here.

Best approach storing and accessing Java application data

I'm in the middle of a massive refactoring project, the code has a 5000 line main class which was injected into everything, stored everything and had all of the common code.
I'm no expert on analysis and design but I've separated out things to the best of my ability and I'm about 80% through refactoring the classes that depend on the main class to use the new classes I've created.
There are some types of data which are initialised when the application starts and accessed by pretty much everything throughout the life of the application. For instance there is a Config class which holds hundreds of parameters.
The approach I've taken is to create several singletons the two most central are GUIData and ClientData. GUIData contains a reference to the mainframe of the application and clientdata maintains references to the config and other similar classes.
This allows me to call ClientData.getInstance().getConfig().getParam("param") from anywhere in the code but I don't feel like this is the best approach.
I considered individual static classes instead of these data singletons which contain instances of the classes but some of the classes do need constructors.
I've been googling on and off for a week trying to find a better way to do this but somehow I always end up on threads talking about database caching
Immutable (configuration) instances provide "thread-safe application-wide data access".
Typesafe's config (as suggested in a comment by Brian Kent) does exactly that.
Note that this does not involve static classes or singletons. Static classes and singletons may serve your purposes now,
but they could prove bothersome in the future. They can be handy ofcourse, but try limiting their use.
Initialization will have to be done after reading and parsing the configuration data. It is typically done at application startup, before other processing threads are started. The initialization will have to validate the configuration data as much as possible in order to fail fast and terminate the program if the configuration data is no good.
Having a lot of configuration data bundled together can create "hidden lines of communication". E.g. you update one value and the application fails because it required updates to other values as well. It's perfectly fine to put all configuration data in one file and load it from there, but your application (with hundreds of configuration options) should divide the configuration data in sets that are used by different parts of your application. This improves isolation, helps unit-testing and makes it possible to change the application in the future without getting too many nasty surprises.
There are two ways to use a set of configuration data:
from within an object call a singleton Settings.getInstance().getConfigForThisModule().
provide each object that uses configuration data with the configuration data via the constructor or via setConfig(ConfigForThisModule config).
The first approach depends on a convention not to call Settings.getInstance().getConfigForACompletelyUnrelatedModule() which could be a weakness. The second approach is more in line with "dependency injection" and could be more future proof.
You could mix both approaches while you are refactoring, just make sure to be consistent (e.g. only use the singleton approach for configuration data that is used in all parts of the application).
To further improve your design for using the configuration data, keep the following (likely) future functional requirement in mind: when the configuration file is updated, configuration data is reloaded and used in the application. Most logging frameworks manage to support this functional requirement without affecting the performance of multi-threaded applications. Among other things, it requires the following of your application:
if the new configuation data is no good, the program is not terminated but an error is logged instead and the old configuration data remains in use. Your initialization procedure will need to handle both "load at fresh start" and "reload" scenarios. The main thing to take away from this is that your initialization procedure needs to be re-usable and should not affect other (running) parts of your application (isolation, again).
long-lived objects may not keep a local copy of configuration data or a reference to an instance of ConfigForThisModule, instead Settings.getInstance()... (or some other method that can return an updated instance) should be called regurarly.
replacing old configuration with new configuration may not result in errors. Technically, replacing the configuration is as simple as updating an AtomicReference with a new configuration instance returned with Settings.getInstance().... But this is also where the isolation of the configuration data sets are tested: there should be no problem using an old set in one module and a new set in another module at the same.
Configuration data can be seen as a sort of "global state". With that in mind, further design points on what to do and what to avoid (partially blatantly copied to this answer) are discussed in the following two questions:
Why is Global State so Evil?
How are globals any different from a database?
Sorry, the question is a bit vague, are you looking to store the config or the cached objects used by other parts of your program ?
Since you have 100s of params, start with splitting up the config into manageable blocks
1) Split up your configuration parameters into logical blocks that have 1:1 correspondence with a simple properties file -its going to take some time
2) These property files must be externalized so that you can change them at any point in time, make sure that you pass in the base location via a env variable to the program
3) Write a utility class (singleton) that wraps Apache commons configuration to hold your config. (read *.properties from the base location and merge the properties into one configuration object) this must be done before any threads are kicked off.
4) Refer to the configuration param in your code using config.getXXXX() methods
Apache commons config also has ability to reload the config when your properties file changes on the filesystem.
Once this is done, use a DI container like Spring or Guice to cache the configured objects.
If it's just String property values you need, you don't even need a class for that - a global facility exists for you already: System.getProperties()
All you need do is first load the property values on start up:
System.setProperty("myKey", "myValue"); // see below how load properties from a file
Then read it anywhere in your code:
String myValue = System.getProperty("myKey");
or
String myValue = System.getProperty("myKey", "my desired default");
If your container doesn't support property loading out of the box, to load properties from an external file that looks like this:
key1=value
key2=some other value
etc...
you can use this code:
Files.lines(Paths.get("path/to/file"))
.filter(line -> !line.startsWith("#") || !line.contains("=")) // ignore comment/blank
.map(line -> line.split("=", 2)) // split into key/value
.forEach(split -> System.setProperty(split[0], split[1])); // load as property
you can use the Java Properties class util, basically its a HashTable
reference : https://docs.oracle.com/javase/7/docs/api/java/util/Properties.html
you create a file fileName.properties and store your data in key value pairs, for example:
username=your name
port=8080
then you load it into Properties Object and get the data like the following:
Properties prop = new Properties();
load the file...
String userName = prop.getProperty("username")
String port = prop.getProperty("port")// you can parse it to int if needed
what i suggest is to create a property file for each type of configuration like:
clientData.properties
appConfig.properties
you can follow this simple tutorial
http://www.mkyong.com/java/java-properties-file-examples/

Configuration design pattern across Java system

The question is old hat - what is a proper design to support a configuration file or system configurations across our system? I've identified the following requirements:
Should be able to reload live and have changes picked up instantly with no redeploying
For software applications that rely on the same, e.g., SQL or memcached credentials, should be possible to introduce the change in an isolated place and deploy in one swoop, even if applications are on separate machines in separate locations
Many processes/machines running the same application supported
And the parts of this design I am struggling with:
Should each major class take its own "Config" class as an input parameter to the constructor? Should there be a factory responsible for instantiating with respect to the right config? Or should each class just read from its own config and reload somewhat automatically?
If class B derives from class A, or composes around it, would it make sense for the Config file to be inherited?
Say class A is constructed by M1 and M2 (M for "main") and M1 is responsible for instantiating a resource. Say the resource relies on MySQL credentials that I expect to be common between M1 and M2, is there a way to avoid the tradeoff of break ownership and put in A's config v. duplicate the resource across M1 and M2's config?
These are the design issues I'm dealing with right now and don't really know the design patterns or frameworks that work here. I'm in Java so any libraries that solve this are very welcome.
You may want to check out Apache Commons Config, which provides a wide range of features. You can specify multiple configuration sources, and arrange these into a hierarchy. One feature of particular interest is the provision for Configuration Events, allowing your components to register their interest in configuration changes.
The goal of changing config on the fly is seductive, but requires some thought around the design. You need to manage those changes carefully (e.g. what happens if you shrink queue sizes - do you throw away existing elements on the queue ?)
Should each major class take its own "Config" class as an input parameter to the constructor?
No, that sounds like an awful design which would unnecessarily overcomplicate a lot of code. I would recommend you to implement a global Configuration class as a singleton. Singleton means that there is only one configuration object, which is a private static variable of your Configuration class and can be acquired with a public static getInstance() method whenever it is needed.
This configuration object should store all configuration parameters as key/value pairs.

Detect if running in servlet container or standalone

I have a simple problem: I want to configure an object differently based on whether the object is instantiated within a servlet container, or whether it is instantiated in a stand alone app.
The object is a database connection, and I care about setting query timeouts.
The first solution that I can come up with is:
if (insideServletContainer(this.getClass().getClassLoader()) {
/// do some servlet specific config
}
else {
/// do some standalone config
}
The question is, of course, can I write a reliable method of telling whether the class was loaded within a servlet container. It feels like a hack at best.
The second option is to assume that the default case is a stand alone instantiation, set defaults based on stand-alone configuration, and override them within the servlet context.
So, to sum up my question is: Do you know of a good/reliable mechanism if the class was loaded from within a servlet container? If not, I will have to take the second route.
Nick
This seems like a really bad idea. Instead, why don't you allow the class to take parameters, then let the container or app configure it appropriately?
Setting aside whether or not this is a good idea, I'd suggest looking up java:comp/env, which is only going to be available in an EE server:
try {
new InitialContext().lookup("java:comp/env");
/// do some servlet specific config
} catch (NamingException ex) {
/// do some standalone config
}
An alternate way to do this sort of thing is to have the configuration injected into this class by some sort of bootstrap loader.
In a standalone version, this would be done by the main() method (or something called from it).
In a webapp version, this would be done by a listener or filter invoked configured within the web.xml.
Dependency injection is useful here as it removes the need for your application to check these sorts of things; instead the application is given what it needs.
I would recommend Dependency Injection like #matt b.
As a second option, if it is only the simple case you described and you don't want to add or learn a DI framework to support this feature. You can accomplish the same thing as your current code by using a properties file to load different value based on the environment. You can simply use a different file for each environment and supply a VM arg to indicate which environment you are running.
db_prop.dev
db_prop.stalone
dp_prop.int
db_prop.prod
Then you can load by resource
"db_prop." + System.getProperty("runtime.env")

JNDI Names -- Is Prefix "jdbc/" needed?

What's up with JNDI names? I'm trying to get a javax.sql.DataSource using the new annotations feature of Java 5. It's not working for me, so I want to ask...
I have a in my web.xml, inside of it is an element. I'm switching between "jdbc/MyDB" and "MyDB". Neither makes my class-based DataSource work (it's always null) but in another example I've created using taglibs, both of these JNDI names work.
No, it is not. It is just the convention so that it's clear to everyone what resource it is.
You can even name it k34ug6i2u3dn234uy5f, but that would lead to future maintenance problems.

Categories