The OSGi ConfigurationAdmin specification mentions that implementations of ManagedService and ManagedServiceFactory may signal an invalid incoming configuration by throwing a ConfigurationException. Yet, apart from this statement, the spec is silent on how the various actors should handle the situation, and most importantly, what should be the state of the environment after such an exception.
For example, suppose that a ManagedServiceFactory currently has a service instance (lets say service.pid=example.12345) with a valid set of properties; that service instance is published by the factory into the service registry. Then, the factory is informed of a configuration update for that service instance; however, on verification, the update method determine that incoming properties are invalid. Based on the spec, the factory should therefore throw a ConfigurationException.
But then, if nothing else is done, the environment remains in an unstable state: there is now a published service in the registry based on a configuration that no longer exists; consequently, whenever the ManagedServiceFactory service gets restarted (for example because of a bundle update or a whole framework restart), it will not be possible to reinstantiate that service, its former valid configuration having been lost. This breaks the persistence paradigm of the Configuration Admin subsystem, and pose severe issues regarding the stability of some OSGi environment.
Unfortunately, there is no easy way for the initial configurator bundle to detect that its configuration change caused a ConfigurationException, making it hardly possible in general to restore a stable configuration from that place. It seems to me that it would be more appropriate, in such situation, for the ConfigurationAdmin to (persistently) restore the previously valid configuration, but there is unfortunately no mention of such behaviour in the spec, and I don't see any trace of such mechanism in Felix's implementation.
Given these facts, it seems that the only possibility to maintain the stability of the environment would be for a ManagedServiceFactory implementation to first unregister and destroy existing service instances for which it has received invalid configuration properties, and only after that, throw the mandated ConfigurationException. This would effectively result in the same environment state as what would be if the framework was relaunched at that point. Similarly, a ManagedService implementation should handle an invalid configuration by first entirely restoring its default configuration, and then throw a ConfigurationException.
So, how exactly should errors in ManagedService and ManagedServiceFactories configuration updates be handled? Is my understanding correct? From what I see out there in example/open source implementations of ManagedService and ManagedServiceFactory, this aspect seems to be totally ignored by most developers. Does the spec provides any clarification on the subject?
The general strategy is to log it as an error and pray it will be solved soon. The purpose of the Configuration Exception is to provide detailed information to the devops so it can be corrected quickly.
The strategies you describe are imho so hopelessly complex and open ended that they tend to create more problems then they ever can solve. Someone made a mistake to create wrong configuration, the only solution is to fix that configuration. I find that in general systems that handle these exceptional case to become very fragile. Once something is wrong, you're in an infinite space and software is extremely bad in reasoning about things you don't know about.
So unless you have some very specific use cases I do not think it can, nor should it, have a general solution.
In general there are three strategies to handle this:
Rejecting the invalid configuration but keeping the previous state
Rejecting the invalid configuration and destroy the current state as if there was no configuration before
Rejecting invalid values, apply valid values as much as possible
What to choose, an wheather you descide to throw an exception, print a warning to the log, send an e-mail or bring up a popup heavyly depends on your system and use cases.
For example if you have an UI and the user can change the config you can simply save the old config and if you detect an error you can ask the user to either correct or revert the configuration.
Even better, you can describe the Configuration requirements with the MetaTypeService so you can validate the config before apply it.
If you have a set of config files, you better make a backup before so you can revert :)
Related
Context
We use a javax.ws.rs.ext.ExceptionMapper<Exception> annotated as #javax.ws.rs.ext.Provider to handle all exceptions. Internally this ExceptionMapper is distinguishing between different types of exceptions to determine what information to reveal to the client.
In the case of the javax.validation.ConstraintViolationException, we return additional information about which field was invalid and why.
Problem
We just switched from TomEE 1.7.2 JAX-RS to TomEE 7.0.0-SNAPSHOT webprofile.
With TomEE 1.7.2 JAX-RS we used the openejb.jaxrs.providers.auto=true system property, our ExceptionMapper was automatically found and used.
With TomEE 7.0.0-SNAPSHOT webprofile the property is no longer necessary to benefit from auto discovery.
However the org.apache.cxf.jaxrs.validation.ValidationExceptionMapper is also discovered and now acts as the preferred ExceptionMapper for the javax.validation.ConstraintViolationException. Our own ExceptionMapper does not run, and the client therefore gets no information about what went wrong during validation.
Our own ExceptionMapper<Exception> still handles all other exceptions.
What I already tried
"duplicate" the specialized ExceptionMapper
I placed my own javax.ws.rs.ext.ExceptionMapper<javax.validation.ConstraintViolationException> next to my resources, hoping that it takes precedence over the CXF one.
Still the org.apache.cxf.jaxrs.validation.ValidationExceptionMapper takes precedence.
Update: it turned out that this indeed does the trick. I don't know why my initial test didn't work.
Disable the ValidationExceptionMapper via system.properties
In the changelog of TomEE 7.0.0-SNAPSHOT I noticed
TOMEE-1336 Support classname.activated = true/false for auto discovered providers
Looking at the corresponding changeset I was hopeful that I could just disable the org.apache.cxf.jaxrs.validation.ValidationExceptionMapper by adding
org.apache.cxf.jaxrs.validation.ValidationExceptionMapper.activated=false
to our system.properties.
This remained without effect.
Questions
Is this CXF or TomEE behaviour?
How do we configure which ExceptionMapper takes precedence?
Makes some time now but think it is needed by spec but you can disable it by setting cxf.jaxrs.skip-provider-scanning=true.
It completely disables auto providers including the scanned ones but then you can control the one you want in openejb-jar.xml - surely the best and safer solution IMHO cause otherwise you depend a lot of the libs and container setup you use.
There is no priority afaik cause the exception hierarchy is used.
edit: missed a part: you need to impl ExceptionMapper{ValidationException} otherwise CXF one has higher priority than your own one (Exception is less specific)
edit 2: https://issues.apache.org/jira/browse/TOMEE-1656 for the activated support
A recent question on SO lead me to an older answer about the Java Security Manager. My question about this line in that answer:
The security manager impacts performances though, and it is rarely used on the server side.
Can someone please back this up or refute? I thought there is always a security manager, a custom one or the default and that containers use it all the time.
In server-side code that you yourself write, I can't think for any need for you to use a SecurityManager, since if you are writing the code to perform some operation in your application, it's unlikely that you need to check if your code has the permissions that you have given it.
For instance, a lot of the methods in SecurityManager are related to IO operations - checkDelete(), checkRead(), checkWrite(), etc. The JDK library classes will call these methods when you try to create/write/read/delete a file, so calling them yourself would be pointless.
So it's unlikely that your server-side code would make much use of the SecurityManager. However, the code that your code runs in - if you are deployed in a servlet container for instance - might make use of these methods, because they are interested in determining if your code has some level of permission that they give it.
I wrote an unit-test for an activity which finally puts a message into a queue. As soon as a message is put into that queue, a message driven bean starts processing. But I don't want to test MDBs in a unit test. How can I tell OpenEJB to ignore them?
I set up OpenEJB with several properties:
p.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.LocalInitialContextFactory");
p.setProperty("openejb.deployments.classpath.include", ".*");
p.setProperty("openejb.localcopy", "false");
// Messaging
p.put("MyJmsResourceAdapter",
"new://Resource?type=ActiveMQResourceAdapter");
// Do not start the ActiveMQ broker
p.put("MyJmsResourceAdapter.BrokerXmlConfig", "");
p.put("MyJmsConnectionFactory",
"new://Resource?type=javax.jms.ConnectionFactory");
p.put("MyJmsConnectionFactory.ResourceAdapter", "MyJmsResourceAdapter");
p.put("queue/MyQueue",
"new://Resource?type=javax.jms.Queue");
I know I must set openejb.deployments.classpath.exclude, but I can't figure out the right value:
p.setProperty("openejb.deployments.classpath.exclude", "org.example.mdb.*");
For example my class is named org.example.mdb.MyMDB.
just my 2 cents:
try ".*org/example/mdb.*" or ".*org.example.mdb.*"
from Loading Deployments from the Classpath:
Note by default these settings will
only affect which jars OpenEJB will
scan for annotated components when no
descriptor is found. If you would like
to use these settings to also filter
out jars that do contain descriptors,
set the
openejb.deployments.classpath.filter.descriptors
property to true. The default is false
We don't have that feature, but it could easily be added if you wanted to do a little hacking -- new contributions and contributors are always welcome.
This class will do exactly what you want... and a few things you probably don't want :) It strips out all MDBs and JMS resource references (the good part) and it strips out all entity beans and persistence unit references (the part you probably don't want). We wrote it due to some debugging issues we were having when either ActiveMQ or OpenJPA were loaded. If you cleaned it up we'd happily take it back and support it as a feature.
There is a similar feature which strips out all web services. It is installed in the ConfigurationFactory if a specific system property is set. Should be easy to plug an "MDB & JMS" remover using a similar flag at basically that same place in ConfigurationFactory
In fact since in OpenEJB all annotation and xml meta-data is merged into one object tree (which is also a JAXB tree), you could do pretty powerful transformations of the app prior to it being actually deployed. Say for example swap out specific beans for mock versions.
One of those things I think would make an excellent feature but haven't yet had the time to work on. I.e. making some clean hook for people to mess with the tree just before we send it off for deployment. Anyone reading this is welcome to jump in and take a stab at it (yay open source!).
The idea is to utilize AOP for designing applications/tools to debug/view execution flow of an application at runtime. To begin with, a simple data(state) dump at the start and end of method invocation will do the necessary data collection.
The target is not application developers but high level business analyst or high level support people for whom a execution flow could prove helpful. The runtime application flow can also be useful in reducing the learning curve of an application for new developers especially in configuration loaded systems.
I wanted to know if there already exists such tools/applications which could be used. Or better, if this makes sense, then is there a better way to achieve this.
You could start with Spring Insight (http://www.springsource.org/insight) and add your own plugins to collect data appropriate for business analysts/support staff. If that doesn't meet needs, you can write your own custom aspects. It is not that hard.
You could write your own aspects, as suggested by ramnivas, but to prepare for the requests from the users, you may want to just have the aspects compiled into the application, so that you don't have to take a hit at run-time, and then they could just select which execution flows or method groups they are interested in, and you just call the server and set some variable to give them the information desired.
Writing the aspects is easy, but to limit recompiling, you may want to get an idea what the users will want, for example, if they want to have a log of every call made from the time a webservice is called until it gets to the database, then you can build that in, but it would be easier to know this up-front.
Otherwise the aspect does nothing, if the variable is not set, and perhaps unset the variable when finished.
You could also have where they can pick which type of logging and for which user, which may lead to more useful information.
I have a question on using System Properties in Java. Some classes like Authenticator require that we set the system properties regarding Proxy settings and than verify whether the Proxy was valid or not.
My question is should I remove the Set Properties after I am done using it ?
There are other parts of programs that might be using these Properties, this change will autmatically impact thier functionality.
Is there a way, I can set Properties local to a Function (some wrapper class)?
What are the good practises for setting system properties and using them ?
Things that use System.properties should have properties that have a global meaning to the running JVM, so that if, for example, you set a proxy, it should be the relevant proxy across that process.
So therefore there is no need to set them back. In fact, setting them back might make some APIs confused, as they may assume they get back the relevant value at all times, and didn't just cache it when they read it.
Of course if a given API isn't using them that way, then you might have issues, but that would really be an issue with a given API, more than a good practice issue with System properties.
In general, due to threading and synchronization issues, it is probably a good practice to set System properties only at the beginning of the JVM startup (either on the command line or in the main thread before starting other threads) with the expectation that the values remain unchanged for the remainder of the time running the JVM.
This doesn't answer your question about system properties in general, but regarding your specific problem with proxy settings properties, perhaps you can use a ProxySelector to isolate the Test Proxy you mention in the comments here?
You could create a subclass of ProxySelector that you utilize for the test. Make it such that it only applies the test settings when the test URI is attempted. This would isolate it from other requests.
This sort of global proxy setting inflexibility is what initially drove me to use HttpClient for HTTP needs instead of Sun's API.
Edit:
I'm not sure how I ever missed this method, but it is possible to get a URL connection and supply the proxy settings to that connection alone via java.net.Url.openConnection(Proxy)
.
If there is a chance that some other part of your program (or some other webapp in the container, etc) might be affected by "temporary" settings then it is a good idea to remove them.
Best practice would be to try an find some other way to do what you are trying to do. For example, consider creating your own protocol class that overrides a standard one in the area where it figures out what proxy to use.
If you cannot do that, try to structure your code so that the sequence:
change the properties,
do the operation,
restore the properties,
is done in a mutex that respected by anything that might be affected by the properties you are changing. This may be a hard ask though ...