I'm fairly new to GWT and have never worked with Java Servlets before. I know how to make RPCs but I was wondering if there are any concurrency issues with declaring member variables in my RPC's ServiceImpl/RemoteServiceServlet class. I.e. From multiple "simultaneous" RPCs overwriting the same variable, similar to what happens with threads when a variable isn't declared volatile.
I also need to use an extra thread in my server side code, so I was wondering if there's any problems (outside of the usual thread safety problems) with declaring some of the servlet's members as static so the other thread can access the variables without a reference to the servlet instance. Is it possible for more than one instance of the same RemoteServiceServlet class to be running at the same time?
E.g.
public class MyServiceImpl extends RemoteServiceServlet implements MyService {
// Which of these variable declarations are a bad idea in a servlet?
private String someVariable;
private static String anotherVariable;
volatile private static String multiThreadedVariable;
public void init() { ... }
...
}
Thanks.
A Servlet is a singleton, therefore there is only one instance of the MyServiceImpl class. By introducing these state variables you will run into thread-safety issues not because there might be more than one MyServiceImpl instance, but because there is only one instance that will service ALL of your requests. Unless you synchronize access to these variables, you will have thread-safety issues, so I recommend removing them completely (most likely you don't even need them).
Related
I'm using vertx in my project nad I guess that I had a terrible idea when I create a Java class like this
public class MyClass {
static Vertx vertx = Vertx.vertx();
public void run() {
vertx.getOrCreateContext().runOnContext(event -> {
// run something
});
}
}
Everything I run in this run() function will be run asynchronous but I'm not sure that it's recommended.
Well, if you have a vert.x application, you can get the Vertx object in a class by extending the AbstractVerticle and getting the vert.x object from it using the getVertx() method.
Also, Vertx.vertx() always creates a new instance. It's better to use something like Vertx.currentContext().getOwner()
Remember that static objects are created before non-static objects and non-static methods being run. This means that if there are some configs/checks that needs to be done at bootstrap (for example metrics), they could be missed, unless maybe also done in a static context.
I would advice against doing this. The reason is, that it would heaviliy reduce your ability to write tests for all the classes that rely on that static Vertx instance.
Use dependency injection instead (or use Verticles as described in the other answer).
Hi I am running into a deadlock in a JavaFX Application and I am not sure why this is happening...
When initializing my application I start a Thread to load a certain view that is creating an object that is extending my DatabaseManager. At the same time another Thread is doing the same on another view and another object that is extending the DatabaseManager.
The first thread that enters the following constructor enters the synchronized block but NEVER reaches the "System.out.println("****3");" line.
After this happened my later started thread enters the constructor and is of course blocked since the resource has never been released again.
by thread 1.
Any ideas, why this is resulting in a deadlock? I am using javafx.concurrent.Task with java.lang.Thread
public abstract class DatabaseManager {
protected static final AtomicReference<EntityManager> entityManager = new AtomicReference<>();
protected DatabaseManager() {
if (entityManager.get() == null) {
System.out.println("****1");
synchronized (entityManager) {
if (entityManager.get() == null) {
System.out.println("****2");
entityManager.set(Persistence.createEntityManagerFactory(
DatabaseConstants.hsqlPersistenceUnitName,
DatabaseConstants.getProperties()).createEntityManager());
System.out.println("****3");
}
}
}
}
...
AtomicReferences (and their primitive wrapper friends) manage their own atomicity. So, while I can't really see why this is deadlocking, using a synchronized block to use an AtomicReference defeats the entire purpose of the AtomicReference in the first place.
You can just do:
protected DatabaseManager() {
entityManager.compareAndSet(null,
Persistence.createEntityManagerFactory(
DatabaseConstants.hsqlPersistenceUnitName,
DatabaseConstants.getProperties()).createEntityManager());
}
which will have exactly the same effect as what you are trying to do (without the logging, obviously).
The recommended way to lazily initialize a static field is to use the "Lazy initialization holder class idiom":
public abstract class DatabaseManager {
protected static EntityManager getEntityManager() {
return EntityManagerHolder.entityManager ;
}
private static class EntityManagerHolder {
static final EntityManager entityManager =
Persistence.createEntityManagerFactory(
DatabaseConstants.hsqlPersistenceUnitName,
DatabaseConstants.getProperties()).createEntityManager() ;
}
}
}
This ensures lazy initialization, because the inner class DatabaseManager.EntityManagerHolder is not loaded until it is referenced for the first time, which doesn't happen until getEntityManager() is called for the first time. It is guaranteed atomic, because class initializers are guaranteed atomic. And furthermore, since the atomicity is enforced only when the inner class is initialized, the cost of synchronization is not incurred on subsequent calls to getEntityManager(). (By contrast, the solution with the AtomicReference performs a (presumably internally-synchronized) call to AtomicReference.compareAndSet(...) each time you create a new DatabaseManager.)
See Josh Bloch's Effective Java, item 71, for a fuller discussion.
I found the solution for my deadlock eventhough I do not know why this results in a deadlock...
I have just another thread that is trying to access another database. The application interacts with 2 databases. All performings on my HSQL database came from my DatabaseManager and while one thread was trying to initialize the EntityManager in my DatabaseManager the third Thread was simply calling
Persistence.createEntityManagerFactory(DBConstants.ORACLE_PERSISTENCE_UNIT).createEntityManager();
After removing that line and also using the DatabaseManager to establish the connection to the second database the deadlock was gone.
But I have no idea why. The only possible solution in my eyes is that eclipselink itself deadlocked there...
I've the following question:
ContainerRequestFilter is a singleton, but reading this:
Jaxrs-2_0 Oracle Spec
in chapter 9.2, they say:
Context is specific to a particular request but instances of certain JAX-RS components (providers and resource classes with a lifecycle other than per-request) may need to support multiple concurrent requests. When injecting an instance of one of the types listed in Section 9.2, the instance supplied MUST be capable of selecting the correct context for a particular request. Use of a thread-local proxy is a common way to achieve this.
In the chapter 9.2, the HttpServletRequest is not mentioned.
So the question is: is it safe in terms of concurrency to inject the HttpServletRequest inside a custom ContainRequestFilter?
I mean this:
#Provider
#PreMatching
public class AuthenticationFilter implements ContainerRequestFilter {
#Context private HttpServletRequest request;
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// This is safe because every thread call the method with its requestContext
String path = requestContext.getUriInfo().getPath(true);
// Is this safe? The property request is injected by using #Context annotation (see above)
String toReturn = (String)request.getAttribute(name);
[...]
}
I did some empirical tests on my IDE in debug mode, sending with two different browsers two different and concurrent requests and it seems to work well; I noticed that the filter's instance is ever the same (it's a singleton), but the injected HttpServletRequest is different in the two cases.
I readed even this thread: How to access wicket session from Jersey-2 request filter? and it seems that my tests are confirmed.
But I still have doubts.
Confirm?
Yes it's safe. To understand the problem, you should understand how scopes work. In any framework that deals with scopes (and injection), the feature is implemented similarly. If an object is in a singleton scope and another object in a lesser scope needs to be injected, usually a proxy of the object will be injected instead. When a call is made on the object, it's actually a call on the proxy.
Though the spec may not mention the HttpServletRequest specifically, most JAX-RS implementation have support for this. With Jersey in particular, if this was not possible (meaning the object is not proxiable), then you would get an error message on startup with something like "not within a request scope". The reason is that the ContainerRequestFilter is created on app startup, and all the injections are handled at that time also. If the HttpServletRequest was not proxiable, it would fail to inject because on startup, there is no request scope context.
To confirm that it is not the actual HttpServletRequest and is a proxy, you can log the request.getClass(), and you will see that it is indeed a proxy.
If you are unfamiliar with this pattern, you can see this answer for an idea of how it works.
See Also:
Injecting Request Scoped Objects into Singleton Scoped Object with HK2 and Jersey
ConfigProperty.idPropertyMap is filled on the server side. (verified via log output)
Accessing it on the client side shows it's empty. :-( (verified via log output)
Is this some default behaviour? (I don't think so)
Is the problem maybe related to the inner class ConfigProperty.IdPropertyMap, java.util.HashMap usage, serialization or some field access modifier issue?
Thanks for your help
// the transfer object
public class ConfigProperty implements IsSerializable, Comparable {
...
static public class IdPropertyMap extends HashMap
implements IsSerializable
{
...
}
protected static IdPropertyMap idPropertyMap = new IdPropertyMap();
...
}
// the server service
public class ManagerServiceImpl extends RemoteServiceServlet implements
ManagerService
{
...
public IdPropertyMap getConfigProps(String timeToken)
throws ConfiguratorException
{
...
}
}
added from below after some good answers (thanks!):
answer bottom line: static field sync is not implemented/supported currently. someone/me would have to file a feature request
just my perspective (an fallen-in-love newby to GWT :-)):
I understand pretty good (not perfect! ;-)) the possible implications of "global" variable syncing (a dependency graph or usage of annotations could be useful).
But from a new (otherwise experienced Java EE/web) user it looks like this:
you create some myapp.shared.dto.MyClass class (dto = data transfer objects)
you add some static fields in it that just represent collections of those objects (and maybe some other DTOs)
you can also do this on the client side and all the other static methods work as well
only thing not working is synchronization (which is not sooo bad in the first place)
BUT: some provided annotation, let's say #Transfer static Collection<MyClass> myObjList; would be handy, since I seem to know the impact and benefits that this would bring.
In my case it's rather simple since the client is more static, but would like to have this data without explicitely implementing it if the GWT framework could do it.
static variables are purely class variable It has nothing to do with individual instances. serialization applies only to object.
So ,your are getting always empty a ConfigProperty.idPropertyMap
The idea of RPC is not that you can act as though the client and the server are exactly the same JVM, but that they can share the objects that you pass over the wire. To send a static field over the wire, from the server to the client, the object stored in that field must be returned from the RPC method.
Static properties are not serialized and sent over the wire, because they do not belong to a single object, but to the class itself.
public class MyData implements Serializable {
protected String name;//sent over the wire, each MyData has its own name
protected String key;
protected static String masterKey;//All objects on the server or client
// share this, it cannot be sent over RPC. Instead, another RPC method
// could access it
}
Note, however, that it will only be that one instance which will be shared - if something else on the server changes that field, all clients which have asked for a copy will need to be updated
I am using the following code in my asp.net app. According to this code, for all users of the app, there will be only a single instance of DBProviderFactory. Will this create a problem in a multi-user environment? So all users would use the the same DbProviderFactory object to create connections. I am not sure if this will create some type of hidden problems in a multi-user environment.
The reason, why I am using a static instance for DbProviderFactory, is so that the GetFactory method is not called everytime a connection needs to be instantiated. This, I think, would make it quicker to get a connection object. Any flaw in my reasoning?
public class DatabaseAccess
{
private static readonly DbProviderFactory _dbProviderFactory =
DbProviderFactories.GetFactory(System.Configuration.ConfigurationManager.ConnectionStrings["DB"].ProviderName);
public static DbConnection GetDbConnection()
{
DbConnection con = _dbProviderFactory.CreateConnection();
con.ConnectionString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["DB"].ConnectionString;
return con;
}
}
It looks fine, but probably will not create interesting efficiencies.
Object creation in .NET is quick. So creating the factory doesn't take a lot of time. Acquiring the connection from a remote database does, but with connection pooling, this normally isn't an issue.
The factory probably doesn't appear to implement any state of it's own & looks like it's probably immutable. So access from different threads is probably okay.
Static objects aren't garbage collected. I doubt the factory will grow in size, so this shouldn't be a problem.
So you avoid a bunch of cheap object creation, a bunch of cheap background garbage collections, and have a minor risk of a derived class actually having state and not being thread safe depending on the exact implementation returned by GetFactory