I am currently using the Owasp ESAPI to manage authentication in my java web application, and I am injecting the Singleton MyAuthenticator with guice.injectMembers(this). I would like to step away from this approach and use a guice-created Singleton-Scoped object. I liked the thread-safety of the ESAPI singleton, and the safety of singletons in general, using Double-Checked Locking, IODH Idiom, or Bloch's Enum INSTANCE style.
What do I need to do to my Guicified Singleton-Scoped Authenticator to make it thread-safe, as well as the ThreadLocal field I am using to get and set my current User?
I would like to make the entire application work with dependency-injection, but don't want it to break upon web-app concurrent access. Any suggestions or common pitfalls?
The ThreadLocal object I am using looks like the code below:
private final ThreadLocalUser currentUser = new ThreadLocalUser();
private class ThreadLocalUser extends InheritableThreadLocal<User> {
#Override
public User initialValue() {
return User.ANONYMOUS;
}
public User getUser() {
return super.get();
}
public void setUser(User newUser) {
super.set(newUser);
}
}
Unfortunately I don't know enough about Owasp ESAPI to give a specific answer, but you may have some luck looking into Guice's AOP support. You can intercept all method invocations on the class and provide whatever concurrency behavior you like.
http://code.google.com/p/google-guice/wiki/AOP
Beware using the "Double-Check Locking" pattern in Java. This design pattern doesn't reliably work in Java (for instance, see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html) unless you declare the singleton instance as "volatile".
Related
I would like to know how to make sure that some method in a service is accessed only once at a time per session.
I'll illustrate by a small example:
Assume we have a user in a state A (user.state = A). This user sends a HTTP GET request to our java spring controller to get a page, say /hello. Based on his status, he will be sent to either A or B. Before that, we will change his status to B (see code below).
Now, assume again that the call dao.doSomething(); takes a lot of time. If the user sends another GET (by refreshing his browser for instance), he will call the exact same method dao.doSomething(), resulting in 2 calls.
How can you avoid that?
What happens if you sends 2 HTTP GETs at the same time?
How can you have something consistent in your controller/service/model/database?
Note 1: here we don't issue the 2 HTTP GETs from different browser. We just make them at the same time on the same browser (I'm aware of the max concurrent session solution, but this does not solve my problem.).
Note 2: the solution should not block concurrent accesses of the controller for different users.
I've read a bit about transaction on service, but I'm not sure if this is the solution. I've also read a bit on concurrency, but I still don't understand how to use it here.
I would greatly appreciate your help! Thanks!
code example:
#Controller
public class UserController {
#RequestMapping(value='/hello')
public String viewHelloPage() {
// we get the user from a session attribute
if (user.getState() = A) {
user.setStatus(B);
return "pageA";
}
return "pageB";
}
#Service
public class UserService {
Dao dao;
#Override
public void setStatus(User user) {
dao.doSomething();
user.setStatus(B);
}
}
Although I wouldn't recommend it (as it basically blocks all other calls from the same user to). On most HandlerAdapter implementations you can set the property synchronizeOnSession by default this is false allowing for concurrent requests to come from the same client. When you set this property to true requests will be queued for that client.
How to set it depends on your configuration of the HandlerAdapter.
how to make sure that some method in a service is accessed only once
at a time per session.
Try to Lock on session object in your controller before calling service method
If dao.doSomething() is doing work that you only want to happen once, you should use an idempotent method like PUT or DELETE. There's no law forcing you to use the correct method, but worst-case it's a self-documenting way to tell the world about how your API should be used. If that isn't enough for you, most browsers will try to help you out based on the type of request. For instance, the browser will often use caching to avoid multiple GETs.
It seems like what you really want to know is how to enforce idempotency. This is very application-specific. One general approach is to generate and store a pseudo-unique id on the server side for the client to attach to their request. This way, any request with the same id after the first can be safely ignored. Obviously old ids should be evicted intelligently.
As I said, the solution is often application-specific. In your case above, it looks like you're trying to switch between 2 states, and your implementation is a server-side toggle. You can utilize the client to ensure that multiple requests will not be a problem.
#RequestMapping(value="/hello", method=RequestMethod.PUT)
public String test(#RequestParam("state") String state) {
dao.setState(user, state)
switch (state) {
case "A":
return "B";
case "B":
return "A";
default:
return "error";
}
}
If you don't mind to configure and use AOP, then the following might help you
#Aspect
#Component
public class NonConcurrentAspect implements HttpSessionListener{
private Map<HttpSession, Map<Method, Object>> mutexes = new ConcurrentHashMap<HttpSession, Map<Method, Object>>();
#Around(value = "#annotation(org.springframework.web.bind.annotation.RequestMapping)")
public Object handle(ProceedingJoinPoint pjp) throws Throwable {
MethodInvocationProceedingJoinPoint methodPjp = (MethodInvocationProceedingJoinPoint) pjp;
Method method = ((MethodSignature) methodPjp.getSignature()).getMethod();
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
HttpSession session = request.getSession(false);
Object mutex = getMutex(session, method);
synchronized (mutex) {
return pjp.proceed();
}
}
private Object getMutex(HttpSession session, Method method) {
Map<Method, Object> sessionMutexes = mutexes.get(session);
Object mutex = new Object();
Object existingMutex = sessionMutexes.putIfAbsent(method, mutex);
return existingMutex == null ? mutex : existingMutex;
}
#Override
public void sessionCreated(HttpSessionEvent se) {
mutexes.put(se.getSession(), new ConcurrentHashMap<Method, Object>());
}
#Override
public void sessionDestroyed(HttpSessionEvent se) {
mutexes.remove(se.getSession());
}
}
It synchronizes on a per-session per-method mutex. One restriction is that the methods so advised should not call each other (which is hardly a case, unless you violate MVC design pattern severely), otherwise you may face deadlocks.
This would handle all the methods tagged with #RequestMapping, but if you want just few methods be guarded against concurrent execution,
then, as one of the possible solutions, you could introduce your own annotation, e.g.
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#Documented
public #interface NonConcurrent {
}
tag the specific methods with this annotation, and replace #RequestMapping in #Around annotation in the above aspect class with your own.
In highly contended environment you may think of more advanced solution than intrinsic locks.
I would, however, advise against using HandlerAdapter's synchronizeOnSession option, not only because it synchronizes all the invocations on the same mutex, but, which is less obvious, the synchronization on publicly available mutex is potentially dangerous.
I have written some code which I thought was quite well-designed, but then I started writing unit tests for it and stopped being so sure.
It turned out that in order to write some reasonable unit tests, I need to change some of my variables access modifiers from private to default, i.e. expose them (only within a package, but still...).
Here is some rough overview of my code in question. There is supposed to be some sort of address validation framework, that enables address validation by different means, e.g. validate them by some external webservice or by data in DB, or by any other source. So I have a notion of Module, which is just this: a separate way to validate addresses. I have an interface:
interface Module {
public void init(InitParams params);
public ValidationResponse validate(Address address);
}
There is some sort of factory, that based on a request or session state chooses a proper module:
class ModuleFactory {
Module selectModule(HttpRequest request) {
Module module = chooseModule(request);// analyze request and choose a module
module.init(createInitParams(request)); // init module
return module;
}
}
And then, I have written a Module that uses some external webservice for validation, and implemented it like that:
WebServiceModule {
private WebServiceFacade webservice;
public void init(InitParams params) {
webservice = new WebServiceFacade(createParamsForFacade(params));
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
So basically I have this WebServiceFacade which is a wrapper over external web service, and my module calls this facade, processes its response and returns some framework-standard response.
I want to test if WebServiceModule processes reponses from external web service correctly. Obviously, I can't call real web service in unit tests, so I'm mocking it. But then again, in order for the module to use my mocked web service, the field webservice must be accessible from the outside. It breaks my design and I wonder if there is anything I could do about it. Obviously, the facade cannot be passed in init parameters, because ModuleFactory does not and should not know that it is needed.
I have read that dependency injection might be the answer to such problems, but I can't see how? I have not used any DI frameworks before, like Guice, so I don't know if it could be easily used in this situation. But maybe it could?
Or maybe I should just change my design?
Or screw it and make this unfortunate field package private (but leaving a sad comment like // default visibility to allow testing (oh well...) doesn't feel right)?
Bah! While I was writing this, it occurred to me, that I could create a WebServiceProcessor which takes a WebServiceFacade as a constructor argument and then test just the WebServiceProcessor. This would be one of the solutions to my problem. What do you think about it? I have one problem with that, because then my WebServiceModule would be sort of useless, just delegating all its work to another components, I would say: one layer of abstraction too far.
Yes, your design is wrong. You should do dependency injection instead of new ... inside your class (which is also called "hardcoded dependency"). Inability to easily write a test is a perfect indicator of a wrong design (read about "Listen to your tests" paradigm in Growing Object-Oriented Software Guided by Tests).
BTW, using reflection or dependency breaking framework like PowerMock is a very bad practice in this case and should be your last resort.
I agree with what yegor256 said and would like to suggest that the reason why you ended up in this situation is that you have assigned multiple responsibilities to your modules: creation and validation. This goes against the Single responsibility principle and effectively limits your ability to test creation separately from validation.
Consider constraining the responsibility of your "modules" to creation alone. When they only have this responsibility, the naming can be improved as well:
interface ValidatorFactory {
public Validator createValidator(InitParams params);
}
The validation interface becomes separate:
interface Validator {
public ValidationResponse validate(Address address);
}
You can then start by implementing the factory:
class WebServiceValidatorFactory implements ValidatorFactory {
public Validator createValidator(InitParams params) {
return new WebServiceValidator(new ProdWebServiceFacade(createParamsForFacade(params)));
}
}
This factory code becomes hard to unit-test, since it is explicitly referencing prod code, so keep this impl very concise. Put any logic (like createParamsForFacade) on the side, so that you can test it separately.
The web service validator itself only gets the responsibility of validation, and takes in the façade as a dependency, following the Inversion of Control (IoC) principle:
class WebServiceValidator implements Validator {
private final WebServiceFacade facade;
public WebServiceValidator(WebServiceFacade facade) {
this.facade = facade;
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
Since WebServiceValidator is not controlling the creation of its dependencies anymore, testing becomes a breeze:
#Test
public void aTest() {
WebServiceValidator validator = new WebServiceValidator(new MockWebServiceFacade());
...
}
This way you have effectively inverted the control of the creation of the dependencies: Inversion of Control (IoC)!
Oh, and by the way, write your tests first. This way you will naturally gravitate towards a testable solution, which is usually also the best design. I think that this is due to the fact that testing requires modularity, and modularity is coincidentally the hallmark of good design.
I never used the #Singleton new feature of JavaEE 6 and i want to give it a try.
I was thinking in creating s Singleton to just hold a password that will allow the app adiministrator(The person that knows the password),to access some content of the app.
I tried to implement it following this tutorial, but it does not work.
This is what i did:
I created the singleton bean:
#Singleton
#Startup
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class AdminAcountEJB implements IAdminAcountEJB {
private String password;
#PostConstruct
public void init() {
password = "password";
}
#Lock(LockType.READ)
public String getPassword() {
return password;
}
}
I extracted an interface
public interface IAdminAcountEJB {
public abstract String getPassword();
}
Then i try to inject the singleton in a managed bean using #EJB
#Named("managementBB")
#SessionScoped
public class ManagementBB implements Serializable{
#EJB
private IAdminAcountEJB managementEJB;
private String input;
private boolean authorized;
public String seeWhatsUp() {
if(input.equals(managementEJB.getPassword())) {
authorized = true;
return "manage?faces-redirect=true;";
}
return "index?faces-redirect=true;";
}
//Get set methods...
}
The last thing i do is create some markup that is displayed in case the correct password is entered:
<h:form rendered="#{managementBB.authorized == false}">
<h:inputSecret value="#{managementEJB.input}"/>
<h:commandButton value="..." action="#{managementEJB.seeWhatsUp}"/>
</h:form>
<h:form rendered="#{managementBB.authorized}">
CORRECT PASSWORD!!
</h:form>
It all seems ok to me, but when i access the page, the console says:
javax.naming.NameNotFoundException:
ejbinterfaces.IAdminAcountEJB#ejbinterfaces.IAdminAcountEJB not found
I don't understand why it don't work, this is how i inject other EJB's that are not Singletones but with #Singleton it does not work.
-How can i fix it?
-I am also interested in knowing what do you think about using a singletone for this purpose, you think is a good and safe idea?
I guess the problem is, that since you refer to your singleton within an EL expression in the view, it has to be annotated with #Named. If you use your beans only within others, this is not necessary.
Concerning your design, my 2 pennies are these:
Since you are using Java EE 6, you won't need to specify an interface for it. If you want/need it nevertheless, don't call it ISomething (except you work for Apple ;-) but give it a domain related name.
Using a singleton which allows concurrent read access is ok for core data. Only, I wouldn't put the password within the code, but into a database table, preferrably hashed and use the singleton as a provider for that which reads the table at startup.
Singletons in general may always introduce a bottleneck into the application because by definition they don't scale. So for your use case it's ok, since we can assume the access rate is very low. The other problem which might be introduced are race conditions (also not in your case) if we have data that changes, since we only have one instance being called in parallel.
As I already have application.properties, where the database connection settings are defined, I decided it is good to put my application-specific settings in that file too. A step further - as spring reads those properties, I declared my Settings bean as follows
<bean name="settingsBean" class="com.tickets.constants.Settings">
<property name="settings">
<props>
<prop key="backup.dir">${backup.dir}</prop>
<prop key="smtp.host">${smtp.host}</prop>
</props>
<property>
</bean>
Now, it happens sometimes, that I need some of those properties in classes that aren't directly in the spring context. Yes - I can either get the spring context from my web application context, or pass the settings as a method parameter to the utility classes, but here's my alternative approach (this is the Settings class):
private static Properties staticSettings;
#PostConstruct
public void init() {
// making the settings available for static access
staticSettings = settings;
}
Now, this looks a bit wrong. But I can't think of a strong reason for not using it.
So to formulate the question - is there any reason not to use my approach, and is there a better one.
You're right, your solution "feels" wrong - the interaction of statics and instance looks like an anti-pattern, but it's a bit of a slippery one to get a grip on.
My gut feeling would be to push the statics a bit further, and make the class itself more internally-consistent, without sacrificing the Spring integration:
public class Settings {
private static Settings instance;
public static Settings initialise(Properties settings) {
instance = new Settings(settings);
return instance;
}
public static Settings get() {
return instance;
}
private final Properties settings;
private Settings(Properties settings) {
this.settings = settings;
}
public String getProperty(String key) {
return settings.getProperty(key);
}
}
Your Spring config would then use factory-method="initialise" rather than the constructor, and other code can use the static get() method to retrieve the singleton. You avoid duplication of the Properties object, and while the static singleton is a bit of an anti-pattern itself, the code makes rather more sense.
But that's the best I can come up with on a freezing cold Saturday morning :)
This is a good question, and I hope you get several informed and well-reasoned responses (better than the one I expect I'm writing).
The reasons for not using this approach are the same as for adopting the Spring framework in the first place: inversion of control, loose coupling, etc. That said, I feel that if you've considered those points in this context and nevertheless feel that this approach elegantly satisfies your actual needs, go right ahead.
Sometimes I feel that Spring -- indeed many leading frameworks & techniques -- allow themselves to slip into "my way or the highway" API design, where the only way to overcome the limitations of Spring is with more Spring.
It shouldn't be that way. You should be able to adopt a thing like Spring in an existing project without signing up to re-architect every bit of your app.
And in fact there are 365236 ways (yours in one) to share objects between the Spring and non-Spring worlds. There's no technical limitation; but the zealots will give you grief.
My spaghetti monster consumes XML from several different SOAP services, and the URL for each service is hardcoded into the application. I'm in the process of undoing this hardcoding, and storing the URLs in a properties file.
In terms of reading the properties file, I'd like to encompass that logic in a Singleton that can be referenced as needed.
Change this:
accountLookupURL ="http://prodServer:8080/accountLookupService";
To this:
accountLookupURL =urlLister.getURL("accountLookup");
The Singleton would be contained within the urlLister.
I've tended to shy away from the Singleton pattern, only because I've not had to use it, previously. Am I on the right track, here?
Thanks!
IVR Avenger
You haven't said why you need only one of whatever it is which will be getting the URL. If that just involves reading a properties file, I don't think you do need only one. Seems to me that having two threads read the same properties file at the same time isn't a problem at all.
Unless you were thinking of having some object which only reads the properties file once and then caches the contents for future use. But this is a web application, right? So the way to deal with that is to read in the properties when the application starts up, and store them in the application context. There's only one application context, so there's your "only one" object.
As an alternative, did you consider using something like Apache Commons Configuration (or maybe another configuration framework)?
Singletons are appropriate for this scenario, BUT you have to make sure you're doing the singleton right.
So, for example, what Bozhno suggests is not a singleton, it's an ugly concoction of nasty statics that's not mockable, not easily testable, not injectable, and generally comes back to bite you in the ass.
An acceptable singleton is just your average class with one notable exception that it is guaranteed either by itself or by some external factory/framework (e.g Spring IoC) to exist in only one instance. If you go with the first approach, you do something like
private MyUberSingletonClass() {
//..do your constructor stuff, note it's private
}
private static MyUberSingletonClass instance = null;
public static synchronized MyUberSingletonClass instance() {
if (instance == null) {
instance = new MyUberSingletonClass();
}
return instance;
}
public String getUberUsefulStuff(){
return "42";
}
That's acceptable if you don't really feel the need for a factory otherwise, and aren't using any IoC container in your app (good idea to think about using one though). Note the difference from Bozhno's example: this is a good vanilla class where the only static is an instance var and a method to return it. Also note the synchronized keyword required for lazy-initialization.
update: Pascal recommends this very cool post about a better way to lazy-init singletons in the comments below: http://crazybob.org/2007/01/lazy-loading-singletons.html
Based on your suggestions, and the fact that I don't think I have as much access to this application as I'd hoped (a lot of it is abstracted away in compiled code), here's the solution I've cooked up. This is, of course, a stub, and needs to be fleshed out with better exception handling and the like.
public class WebServiceURLs {
private static class WebServiceURLsHolder
{
public static WebServiceURLs webServiceURLs = new WebServiceURLs();
}
private Properties webServiceURLs;
public WebServiceURLs()
{
try
{
Properties newURLProperties = new Properties();
InputStreamReader inputStream = new InputStreamReader(
FileLoader.class.getClassLoader().getResourceAsStream("../../config/URLs.properties") );
newURLProperties.load(inputStream);
webServiceURLs =newURLProperties;
}
catch (Exception e)
{
webServiceURLs =null;
}
}
public String getURLFromKey(String urlKey)
{
if (webServiceURLs==null)
return null;
else
return webServiceURLs.getProperty(urlKey);
}
public static WebServiceURLs getInstance()
{
return WebServiceURLsHolder.webServiceURLs;
}
}
Is this a good effort as my "first" Singleton?
Thanks,
IVR Avenger
To restate the obvious, Singleton is to be used when all client code should talk to a single instance of the class. So, use a Singleton IFF you are certain that you would not want to load multiple properties files at once. Personally, I would want to be able to have that functionality (loading multiple properties files).
Singletons are mutable statics and therefore evil. (Assuming a reasonably useful definition of "singleton".
Any code that uses the static (a transitive relationship), is has assumptions about pretty much everything else (in this case, a web server and the internet). Mutable statics are bad design, and bad design makes many aspects go rotten (dependency, understandability, testing, security, etc).
As an example, the only thing stopping late versions of JUnit 3 being used in a sandbox was loading a configuration file in one static initialiser. If it had used Parameterisation from Above, there would have been no issue.