Is jCaptcha thread safe? - java

I'm using JCaptcha in a project and needed a behavior that was not directly available. so I looked into the source code to see if I can extend it to obtain what I want and found that the store implementation I use (MapCaptchaStore) uses a HashMap as the store... with no synchronization.
I know JCaptcha does not work in a clustered environment, it is not my case, but how about multiple clients at the same time? Is the store implementation synchronized externally or should I roll my own and make sure it is properly synchronized?
TIA!

Judging by the reading source for MapCaptchaStore, this class is NOT thread-safe. I'm not 100% willing to stand behind this answer though, because synchronisation may be happening at a higher level (eg all accesses to a single instance of MapCaptchaStore may be synchronised on another object).
You could use another implementation of CaptchaStore. For example, EhcacheCaptchaStore

Basic hashmap implementation of the captcha store is not synchronized, that could lead to some weird behaviour.
Other stores are thread safe, for a simple implementation use FastHashMapCaptchaStore.

I'm assuming it is because it has been designed to be integrated with web applications which will always have multiple clients. It's also a CAPTCHA framework so they must have tested with both human and computer clients.
However, I would still recommend testing whether it behaves correctly in a multithreaded environment.

Related

Sharing a java object across a cluster

My requirement is to share a java object across a cluster.
I get Confused
whether to write an EJB and share the java objects across the cluster
or
to use any third party such as infinispan or memecached or terracotta or
what about JCache?
with the constraint that
I can't change any of my source code with specific to any application
server (such as implementing the weblogic's singleton services).
I can't offer two builds for cluster and non cluster environment.
Performance should not be downgraded.
I am looking for only open source third party if I need to use it.
It need to work in weblogic , Websphere , Jbos and Tomcat too.
Can any one come up with the best option with these constraints in mind.
It can depend on the use case of the objects you want to share in the cluster.
I think it comes down to really the following options in most complex to least complex
Distributed cacheing
http://www.ehcache.org
Distributed cacheing is good if you need to ensure that an object is accessible from a cache on every node. I have used ehache to distribute quite successfully, no need to setup a terracotta server unless you need the scale, can just point instances together via rmi. Also works synchronously and asynchronously depending on requirements. Also cache replication is handy if nodes go down so cache is actually redundant and dont lose anything. Good if you need to make sure that the object has been updated across all the nodes.
Clustered Execution/data distribution
http://www.hazelcast.com/
Hazelcast is also a nice option as provides a way of executing java classes across a cluster. This is more useful if you have an object that represents a unit of work that needs to be performed and you dont care so much where it gets executed.
Also useful for distributed collections, i.e. a distributed map or queue
Roll your own RMI/Jgroups
Can write your own client/server but I think you will start to run into issues that the bigger frameworks solve if the requirements of the objects your dealing with starts to get complex. Realistically Hazelcast is really simple and should really eliminate the need to roll your own.
It's not open source, but Oracle Coherence would easily solve this problem.
If you need an implementation of JCache, the only one that I'm aware of being available today is Oracle Coherence; see: http://docs.oracle.com/middleware/1213/coherence/develop-applications/jcache_part.htm
For the sake of full disclosure, I work at Oracle. The opinions and views expressed in this post are my own, and do not necessarily reflect the opinions or views of my employer.
It is just an idea. you might want to check the exact implementation.
It will downgrade performance but I don't see how it is possible to avoid it.
It not an easy one to implement. might be you should consider load balance instead of clustering.
you might consider RMI and/or dynamic-proxy.
extract interface of your objects.
use RMI to access the real object (from all clusters even the one that actually holds the object)
in order to create RMI for an existing code you might use dynamic-proxy (again..not sure about implementation)
*dynamic proxy can wrap any object and do some pre and post task on each method invocation. in this case it might use the original object for RMI invocation
you will need connectivity between clusters in order to propogate the RMI object.

Singleton through several processes?

How can I write singleton to work through several processes? Is it possible?
For example I have code that works with Remote Service in Android. How can I write singleton for this purpose?
This thread is old, but the current accepted answer is wrong and misleading some people, so here we go.
Services in Android may run on the same process as your app, or a different process altogether.
If this is an Service defined by your own app for its internal use, it is probably running on the same process. Just don't set any of the process attributes on the Manifest. In that case, your service will run its tasks on either the main thread, or some background threads, and will share the same singleton instance with the rest of your app.
If this is a true remote Service running on a separate process, or a separate app, then what you are trying to achieve is much, much more difficult. Each process will have its own instance of the singleton, and they are in no way related to each other. This makes perfect sense, once you realise the different processes may not even be running the same version of the code.
If you really want to have a common object across processes (hint: you almost certainly don't), you'll need to create a shared memory space for its data, and implement some means of synchronisation. I'm sure there are full college lectures on that subject.
Remote Service you Create will always be singleton. You need to have an Interface to communicate between process using Android Interface Definition Language.
Android Interface Definition Language
See this Example
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html
public enum MySingleton {
SOLE;
//all class stuff
}
This one is singleton that is simply written, lazy and thread safe. You can use MySingleton.SOLE directly or put it to other variables, but they all will be only references to one only instance. You can use it in as many processes as you wish, it shall weather them all. (processes in Android are threads really)
It is not my idea, it is from Effective Java, Second Edition
As for global data using (put that requirement into the question, please), you could reach MySingleton.SOLE from everywhere. Static constants are global. Of course, names would be yours.
Of course any thing has its workaround. You can fool this singleton by classloading.
If you really want to have one instance for several different tasks, not threads, then the easy solution will be singleton build as Hybernate or other ORM object. All processes will see the same row in the same table with the same data. But I think it is the overkill for your task.

How to use different versions of a class in the same application?

I'm currently working on a Java application which should have the capability to use different versions of a class at the same time (because of multi tenancy support). I was wondering, is there any good approach to manage this? My basic approach is to have an interface, lets say Car, and implement the different versions as CarV1, CarV2, and so on. Every version gets its own class.
My approach is kind of wiered, I think. But I didn't found any literature regarding to this topic, but I actually don't know what I should search for.
The interface idea is prudent. Combine it with a factory that can produce the required implementation instance depending on some external input, e. g. the tenant-id. If you don't need to support multiple tenants in the same running instance of the application, you could also use something like the ServiceLocator from the JDK which allows to use a file-based configuration approach.
If you are running in an application server, consider just firing up multiple instances, each configured for a different client. The server will then take care of the separation of instances, just fine.
Otherwise, if you really think you need multiple implementations at the same time (at runtime) in a non-Java EE application, this is a tricky problem. Maybe you want to consider a look at OSGi containers, which provide features for having multiple versions of a class. However, an approach like this add significant complexity, if you are not already familiar with it.
In theory you can handle this using multiple class loaders like JBoss for example does.
BUT: I would strongly advise against implementing this yourself. This is a rather complicated matter and easily gotten wrong. If you are talking about a web application, you can instead create one web app instance per tenant. If you are working on a stand-alone app, you should check, if running one instance per tenant might be feasible.

Servlet concurrency/synchronization in Tomcat?

Is there a recommended way to synchronize Tomcat Servlet instances that happen to be competing for the same resource (like a file, or a database like MongoDB that isn't ACID)?
I'm familiar with thread synchronization to ensure two Java threads don't access the same Java object concurrently, but not with objects that have an existence outside the JRE.
edit: I only have 1 Tomcat server running. Whether that means different JVMs or not, I am not sure (I assume it's the same JVM, but potentially different threads).
edit: particular use case (but I'm asking the question in general):
Tomcat server acts as a file store, putting the raw files into a directory, and using MongoDB to store metadata. This is a pretty simple concept except for the concurrency issue. If there are two concurrent requests to store the same file, or to manage metadata on the same object at the same time, I need a way to resolve that and I'm not sure how. I suppose the easiest approach would be to serialize / queue requests somehow. Is there a way to implement queueing in Tomcat?
Typically, your various servlets will be running in the same JVM, and if they're not, you should be able to configure your servlet runner so this is the case. So you can arrange for them to see some central, shared resource manager.
Then for the actual gubbinry, if plain old synchronized isn't appropriate, look for example at the Semaphore class (link is to part of a tutorial/example I wrote a while ago in case it's helpful), which allows you to handle "pools" of resources.
If you are running one tomcat server and all your servlets are on one context you can always synchronize on a java object present on that context class loader. If you are running multiple contexts then the "synchronization object" can not reside in any particular context but needs to reside at a higher level that is shared by all the contexts. You can use the "common" class loader in tomcat 6.0 documentation here to place your "synchronization object" there which will then be shared among all contexts.
I have 2 cases, If you expect to access common resource for File editing within the same JVM you can use the "synchronized" in a Java function. If different JVMs and other none Java threads accessing the common resource you might try using manual file locking code giving each thread priority number in queue
For database i believe there's no concurrency issue.
Your external resource is going to be represented by Java object (e.g. java.io.File) in some way or another. You can always synchronize on that object if you need to.
Of course, that implies that said object would have to be shared across your servlet instances.
IMO you're asking for trouble. There are reasons why things like databases and shared file systems were invented. Trying to write your own using some Singleton class or semaphores is going to get ugly real quick. Find a storage solution that does this for you and save yourself a lot of headaches.

Singleton in Java App Server.. How bad of an idea is this?

I am currently working on some older java code that was developed without App Servers in mind. It is basically a bunch of "black box code" with an input interface, and an output interface. Everything in the "black box" classes are static Data Structures that contain state, which are put through algorithms at timed intervals (every 10 seconds). The black box is started from a main method.
To keep this easy for myself, I am thinking of making the "black box" a Singleton. Basically, anyone who wants to access the logic inside of the black box will get the same instance. This will allow me to use Message Driven beans as input to the black box, and a JMS Publisher of some sort as the output of the black box.
How bad of an idea is this? Any tips?
One of the main concerns I have though, is there may be Threads in the "black box" code that I am unaware of.
Is there such thing as "application scoped objects" in EJB?
Note: I am using Glassfish
If you use a simple singelton, you will be facing problems once you enter a clustered environment.
In such scenario, you have multiple classloaders on multiple JVMs, and your sinlgeton pattern will break as you will have several instances of that class.
The only acceptable use for a singleton in an app server (potentially in a clustered environment) is when you the singleton is totally state-less, and is only used as a convenience to access global data/functions.
I suggest checking your application server vendor's solution for this issue. Most, if not all vendors, supply some solution for requirements of your sort.
Specifically for Glassfish, which you say you are using, check out Singleton EJB support for Glassfish. It might be as simple as adding a single annotation.
I would say that creating a singleton is actually the only viable idea. Assuming that code inside this "black box" is known to use static fields, it is absolutely unsafe to create two instances of this facade. Results are unpredictable otherwise.
Far from being a bad idea, it actually sounds to me like potentially quite a good idea.
Just from a program design point of view: if your black box is conceptually an "object" with properties and methods that work on them, then make it into an object, even if there'll only ever be one of them instantiated.
It should work, but there are some issues you may have to deal with.
Threading, as you have mentioned. An MDB is run in the EJB container where you cannot create your own threads, so you have a potential problem there. If you have access to the actual code (which it sounds like you do), you may want to do some refactoring to either eliminate the threads or use an "approved" threading method. The CommonJ TimerManager will probably work in your stated case since it is performing some task on an interval. There are implementations available for most app servers (WAS and Weblogic have it included).
Classloading - This is dependent on you configuration. If the singleton is created and manipulated from MDB's within the same EAR, you will be fine. Separate EAR's will mean different classloaders and multiple instance of you Singleton. Can't comment on whether this would be a problem in your case or not without more information.
I'm missing a point? You mentioned that the 'black box code' contains state. MDBs may be limited to 1 instance per destination but without proper configuration you will end up with a few MDBs. All of them working with your single instance of 'black box code'. For me it seems this is not a good idea, because one bean will override the 'black box code' state a other bean has created a few ticks before.
It seems to me that the artifact that better fits to your requirement is a JBoss MBean. (If you are thinking on JBoss as AS candidate).
Standard MBean Example
MBeans can also be deployed as Singletons, in case of JBoss clustering.
Clustering with JBoss
I hope that this is useful for you.
Rafa.
Fix the code to get rid of the statics as soon as possible. Singletons are not a step in the right direction - they just add extra misdirection.
Don't use Singletons where state may change.
Exposing the global instance of your black-box class doesn't seem like the way to go. Often times, singletons will seem like they will make things easier on you, and in a way they can, but it often comes back to bite you and you end up having to restructure a large chunk of your code.
In the webserver world, an object can be scoped to the request, the session, or the application. Perhaps what you need is a application-scope object.
Search the docs for "application scope object" or "application lifetime object".
Why not create a rest interface for the blank box thingy and let clients make http calls ?
IMO, it's a good idea to have an EJB container of your Singleton needs. In Java EE 6 placing a #Singleton annotation in your session bean gives you a named singleton.

Categories