I've seen the builder pattern recommended in a variety of places, but wasn't sure on thread safety within a Web application using Struts.
I am unclear as to whether the variables of the build static method are shared by, or internal to each thread that invokes the builder code. I have a hunch it's okay, but want to be sure given that the builder code lives inside a Web application and could be invoked by 10s of threads at once.
public static class ExampleBuilder {
public static Thing build(ActionForm form) {
String property1 = form.property1;
String property2 = form.property2;
String propertyX = form.propertyX;
...
return new Thing(property1, ...);
}
}
public class ExampleStrutsAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
Thing example = ExampleBuilder.build(form)
return mapping.findForward("success");
}
}
The above build() method only uses local variables, and doesn't access any state that is shared between threads, so it's thread-safe. Local variables are local to each method invocation, and are thus not shared between threads.
The only thread-safety problem you could have is if the form has the scope session (which is a bad practice). In this case, two threads could use the same ActionForm instances. But this is not really a problem of the build() method. Rather a design problem, or a synchronization problem of the execute() method(s) that use this session-scoped ActionForm.
After the code modifications you did I can say that your code is thread-safe anyway because you do not use any member variables into build() method. You can invoke as build() simultaneously from several threads and each thread will use its own method-level variables.
BTW making this class static does not have any sense here. Static modifier in class context is relevant for inner classes only. Inner static class does not have access to instance of outer class. Top level class does not have outer class at all, so it cannot access its instance anyway.
Related
Recently I came across with a builder pattern that intrigued me.
So, I have an EntityBuilder which builds an Entity, but it doesn't return the entity. Here is the method signature:
public void build();
Instead, inside the build() method, it delivers the new object created, the Entity, to a CacheImplementation instance to store it.
Note: the CacheImpl is injected in the builder's constructor.
public void build(){
//create new entity
cacheImplementation.add(entity);
}
Does this sounds like best practice?
Later edit 0
public interface EntityBuilder {
void setProperty0(PropertyObject propertyObject0);
void setProperty1(PropertyObject propertyObject1);
void setProperty2(PropertyObject propertyObject2);
//...
void build();
}
public class EntityBuilderImpl implements EntityBuilder {
PropertyObject propertyObject0;
PropertyObject propertyObject1;
PropertyObject propertyObject2;
//...
// setters for all properties
#Override
public void build(){
//create new entity
cacheImplementation.add(entity);
}
}
The builder is used in the following way:
public class EntityProcessor{
private EntityBuilderFactory entityBuilderFactory;//initialized in constructor
void process(EntityDetails entityDetails){
EntityBuilder entityBuilder = this.entityBuilderFactory.getNewEntitytBuilder();
//..
// entityBuilder.set all properties from entityDetails
entityBuilder.build();
}
}
Note: the cacheImpl instance just stores the entities in a List<> which is accesses every N seconds.
Does this sounds like best practice?
The traditional builder pattern doesn't store the created object anywhere, it simply returns it.
I can imagine a variation where the builder also has a role of instance control to avoid creating duplicate objects, and managing a store of immutable objects.
The decision to not return an instance could be to make it clear that the method has a side effect. If the method returned the object, it might mislead to thinking that it's a traditional builder without side effects, when that's not the case here.
In any case, all this is just speculation, as we haven't seen the rest of the code where this is used and the way it is implemented and used. We don't have enough context to really judge.
There's nothing wrong with inventing new patterns, but it can be done well or badly.
I've seen similar void build() method in the JCodeModel class. As you can see it throws IOException because of the resources it manages:
public void build(File destDir,
PrintStream status)
throws IOException
You basically ask it to carry out the operation for you and if no error is present - you can continue with the workflow.
In general builder is used in following way:
Some class will use builder to create class. Simple
Now you have additional piece of complexity - caching. You can put caching inside Builder or one level higher inside Processor.
What are the implications of putting cache management inside builder:
Builder does not have single responsibility anymore.
It does not work how you would expect at first glance
You are unable to create object without putting it into cache
These problems will not occur if you put cache management to separate class.
I would say that it is not terrible solution, but it certainly will decrease maintainability of your code.
I need a service (singleton fits) with some internal fields, like a list of pending threads (yes everything is written to be thread safe) the problem is that if I #autowire this bean, fields appear to be empty. Debugging I see that the proxy correctly binds to the instance (fields CGLIB$CALLBACK_X are correctly linked to the populated bean) with populated fields, but the fields it offers are empty.
The following lines of codes give a general idea of what i'm talking about.
#Service
public class myService{
#Autowired
private Monitor monitor;
public List getSomething(){
return monitor.getList();
}
}
#Service
public class myStatefulService{
//This field will be populated for sure by someone before getSomething() is called
private List list;
public synchronized List getSomething(){
return this.list;
}
//Called by other services that self inject this bean
public synchronized void addToList(Object o){
this.list.add(o);
}
}
Debugging the variable monitor during the getList call I get
monitor => instance of correct class
fields:
CGLIB$BOUND => true
CGLIB$CALLBACK_0.advised => proxyFactory (correct)
CGLIB$CALLBACK_1.target (reference to the correct instance of myStatefulService class)
fields:
list => [.........] (correctly populated)
CGLIB$CALLBACK_2 .....
......
......
......
list => [] (the list that would be populated is empty instead)
Are you curious or you have some real issue? Nevertheless here is an explanation.
When using CGLIB to proxy classes Spring will create a subclass called something like myService$EnhancerByCGLIB. This enhanced class will override some if not all of your business methods to apply cross-cutting concerns around your actual code.
Here comes the real surprise. This extra subclass does not call super methods of the base class. Instead it creates second instance of myService and delegates to it. This means you have two objects now: your real object and CGLIB enhanced object pointing to (wrapping) it.
The enhanced class is just a dummy proxy. It still has the same fields as your base class (inherited from it) but they are not used. When you call addToList() on myService$EnhancerByCGLIB object it will first apply some AOP logic, call addToList() of myService (which it wraps) and apply remaining AOP logic on return. The myService$EnhancerByCGLIB.list field is never touched.
Why can't Spring use the same class and delegate via super? I guess for simplicity: first create "raw" bean and then apply AOP proxying during post-processing.
"This field will be populated for sure by someone before getSomething() is called"
By someone? No, the Spring bean factory. If you don't configure it, nothing will be populated.
Not every bean needs to be under Spring's control. It sounds like you want to have a List that clients can add and remove items to in a thread-safe way. If that's true, remove the #Autowired annotation, create a new List, and expose methods to add and remove.
I'd recommend a List from the new concurrent collections.
CGLIB will proxy protected getters.
So you can have:
#Autowired
private Monitor monitor;
protected Monitor getMonitor() { return monitor; }
public List getSomething(){
return getMonitor().getList();
}
getMonitor() will be proxied to call getMonitor() on the other instance which has monitor injected.
Background
The Apache Action class is not thread-safe. However, this was only realized after implementing a base class, upon which all other classes in the system depend. The base class uses a number of instance variables:
private HttpServletRequest request;
private ArrayList inputParams = new ArrayList();
private Connection connection;
private String outputParameter;
private boolean exportEnabled;
Fortunately, all usages of those variables are accomplished through accessor methods, exclusively. For example:
public boolean getExportEnabled() {
return this.exportEnabled;
}
public void setExportEnabled( boolean exportEnabled ) {
this.exportEnabled = exportEnabled;
}
Problem
The base class is running in a multi-threaded Servlet environment.
Solution #1
To resolve this issue, I was thinking about using a HashMap keyed to the session. However, this would require re-writing all of the methods, and dependent code:
private static HashMap sessionVariables = new HashMap();
public boolean getExportEnabled( HttpSession session ) {
return getSessionVariables().get( session.getId() + '.exportEnabled' );
}
public void setExportEnabled( boolean exportEnabled, HttpSession session ) {
getSessionVariables().put( session.getId() + '.exportEnabled', exportEnabled );
}
That is a lot of work, and would likely introduce bugs.
Solution #2
It might be possible to change the base class to an "empty" class. This empty class would have a single method:
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response )
throws Exception {
// Instantiate "this" and forward the request?
}
But it would have to know the appropriate base class to instantiate, or perhaps instantiate a new version of itself to handle the call.
Update #1
I believe the Struts architecture does the following:
Create an instance of the Action subclass.
Re-use that same instance for every request.
Obtain a thread (from a thread pool) when receiving a new connection.
Call execute on the Action subclass from the thread.
Handle multiple new connections using different threads.
The same execute method will be called on the same instance of the object, resulting in unsafe behaviour because the subclass has instance variables.
Update #2
The following solution seems to solve the issue:
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response ) throws Exception {
((MyClass)clone()).executeClone( mapping, form, request, response );
}
public ActionForward executeClone(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response ) throws Exception {
// Former "execute" method code goes here.
// ...
}
The original execute method was renamed to executeClone. The new execute implementation creates a clone of the current class and subsequently calls executeClone. This minimally invasive technique avoids introducing new bugs while making the class thread-safe.
Question
What would be the most reliable way to make the code thread-safe while minimizing the risk of introducing bugs?
Thank you!
Solution #1 is dangerous because it assumes that the session is thread-safe, which is not necessarily the case. Someone could be making two simultaneous requests with the same session.
Solution #2 could be easily implemented by making your base class implement Cloneable. Then it can clone itself, set the clone's instance variables, and then call super.execute(). If you think it's too hard to change the design to make your base class be properly thread-safe, this might be an easy way out.
What would be the most reliable way to make the code thread-safe while minimizing the risk of introducing bugs?
There is no general answer to this. What you need to do to make a class thread-safe depends on what the class does, its API design ... and what level of thread-safety you require. In some cases, it is not even practical to make something thread-safe; e.g. read the javadoc for Collections.synchonizedList and look about how it handles the iterator() method.
I have written a web-service application that has in a main class generated random value per request (for logging).
I cannot set it as a static field because next request will override it.
I also cannot pass it to the every class that I use in the main one (as an argument or with setter).
Is it possible to create some semi-static field - visible for one request but not for every other that go to the web-service ?
You can safely assume that, in the Java EE model, each single request is served by a single thread and that there is no contention by concurrent requests.
Having said that, you can employ a Singleton using a ThreadLocal, let the Servlet populate the value and have the underlying classes access the sigleton without having notion of the threads or the HTTP request context:
public class RandomValueHolder {
private static ThreadLocal<Long> randomValue;
public static Long getRandomValue() {
return randomValue.get();
}
public static void setRandomValue(Long value) {
randomValue = new ThreadLocal<Long>();
randomValue.set(value);
}
}
Why not use HttpRequest and store the value as attribute
Save the data in the request itself with Request.setAttribute() and use the corresponding Request.getAttribute() to retrieve it.
how to create singleton classes for multiple uses
and how to connect to jsp with that singleton class
I'm not sure why yould want to connect to a singleton from you JSP directly. If you want to access utility function I'd go with a JSTL function:
<function>
<name>decodeBase64</name>
<function-class>nl.wikiwijs.web.portal.Base64Util</function-class>
<function-signature>java.lang.String stringDecodeBase64(java.lang.String)</function-signature>
</function>
Where 'function-signature' points to a static method in the 'function-class' class. The above should be in a TLD, after which I can be used like this:
${mynamespace:decodeBase64("my value")}
If the singleton is going to be used to retrieve data or expose business logic I'd move it back into a controller/action/component depending on your architecture.
for connecting to jsp, you would use p3t0r's answer.
for singleton, you would use a lazy private static class singleton which guarentees thread safety*:
public class SingletonClass {
private static class LazySingletonInitializer {
static SingletonClass instance = new SingletonClass();
}
private SingletonClass(){}
public SingletonClass getInstance() {
return LazySingletonInitializer.instance;
}
}
(*) because static members of a class are guarenteed by the jvm to be initialized by only one thread.
If you plan to use the Singleton pattern within a Java EE application, have a look at this article. It will provide some important insights as well as links for further research.
As stated by p3t0r, using services directly from within your JSP is not architecturally sound. Try seperating concerns by using some kind of MVC framework (e.g. Spring Web MVC, which, in conjunction with the Spring DI container, frees you from using your own singleton implementations, too).
Basic singleton design pattern has few special characteristics:
No constructor: make sure that the default constructor is private
Create a static function that calls the private constructor(s) if the object is not instantiated already
Have a static instance variable that is the type of its own class.
One example of a simple singleton class implementation is:
public class SingletonClass {
private static SingletonInstance si;
private SingletonClass() {
}
public static synchronized SingletonClass getSingletonInstace() {
if (si == null)
return new SingletonClass();
return si;
}
}