ServletContext attributes set on one JVM are not visible on another JVM. Why?
Why would they be? Separate JVMs have separate address spaces. To share information between them, it has to be explicitly sent via some shared channel like a socket, a file or a database.
I didn't hear about any JVMs shared memory which you can use programatically. Since Java 1.5, there is CDS, which sadly won't help you in this situation as far as I know...
As Michael annouced, you should you another shared construct depending on what information you want to share. Corresponding this is servlet problem, you propably want to share some data by various web applications. If you can satisfy with slighly slower performance using database or simple file, it will work for you. If you have some robust enterprise solution, let's say with EJB or something like that, you can see other techonologies like JMS topics or distributed caches in cluster enviroment.
Related
I'm developing an application (Java & JavaFX) that writes/reads data (a file). The problem is I don't want to restrict user to run only one instance (of my app) at a time, as I really can't think of reliable way of doing that so it works on both Windows and Linuxes (e.g. server), heard of sockets and files - both are defective IMO. As user is able to run multiple instances, writing/reading data (from a file) seems really messy, because there's no guarantee that file locking will work reliably on Windows and Linuxes (FileLock documentation - click here).
To sum up: I can't restrict multiple instances of my app, but that leads to problem with writing/reading data (from a file).
Is there anything I missed? Maybe there's some other way to solve my problem I can't think of? How do the "big" popular programs handle that?
Suggested: Use a socket solution
You could follow the techniques outlined in an answer to:
JavaFX Single Instance Application
FAQ
Addressing some additional questions:
heard of sockets and files - both are defective IMO.
You state your opinion that using sockets to set up a single instance application won’t work well enough for you. You are in the best position to decide that.
For some apps which want to achieve a single instance, the socket-based or file-based solution outlined in the answer to the linked question or other comments will work well enough.
"What happens if more than one user try to run the application? Won't they conflict on opening the socket?"
Prevent launching multiple instances of a java application
And:
Also, I can't be sure if chosen port (fixed, since all instances should check for one port) is being used by some other applications/processes
You may be able to address some of these concerns by enhancing the socket-based solutions outlined in the linked questions.
Enhanced Socket Solution Outline
If you want, you can write an enhanced algorithm to deal with some of these issues.
When another app instance startup occurs, you try to connect to a current instance on a well-known socket.
Check the response to the connection.
If it doesn’t respond with the correct protocol response (e.g. matching user and app name) then increment the port by 2 and retry.
Test the response again until either:
You get a match for the app/user combo, then send a signal to that app to display itself.
OR
If you get no match, then create a new instance on the tested open port.
I'm not suggesting you do that, just explaining that it is possible.
Alternative: OS native service
There are also other OS-specific mechanisms for handling this such as Windows or Linux services which you can investigate if you want, those approaches are involved and vary by OS, so I won’t discuss them in detail here.
For the OS-specific solutions, you usually would:
Create a native package for your app (e.g. using jpackage)
Install it.
Have the installer config the app as a service
e.g. on linux, create an init.d script with a pid file configured via chkconfig.
The service launches on boot and stops on shutdown.
The app is then accessed via a tray icon or something similar
The means of interaction is often OS version specific.
Alternative: Allow multiple app instances but use a single database instance
You may also consider using a database rather than files for data storage, as a database system can help solve many of the concurrent access issues which can arise with file based solutions. Multiple clients can connect to the database, and the database and your app code can handle locks and collisions on the data access to ensure data integrity is contained. Using such a solution, there is no need to enforce that a single application instance is running for a user (at least from a data integrity perspective).
I'm looking for a way to share large in-memory objects between java applications and have been looking at JMS (ActiveMQ) and JavaSpaces. Will any of theese allow me to reliably send/share objects between two or more java applications? Is ActiveMQ suitable for large messages?
You can use in-memory data grids like Oracle Coherence or JBoss Data Grid. This may be a faster then JMS using.
It really depends what you mean by share. If you mean that different processes (potentially on different machines) need to be able to access a "shared" object, then yes, as the other answer suggests, something like Oracle Coherence would be great.
On the other hand, if you mean share as in to pass from one process to another, then you probably are looking for a messaging solution, e.g. JMS or even simpler e.g. REST.
I intend to create a java program/service that continuously polls rss-feeds using the informa library 'poller' functionality. I want to be able to add,delete,update the rss-url's realtime, while the program is running. I have no prior experience with the informa library but I need it to potentially scale to a lot of rss-feeds.
Does anyone have have experience with the informa library for polling rss-feeds? What other method/libraries would you consider to poll a lot of rss-feeds (10.000+)?
What do you consider to be an accepted solution to control a running (console) java program. I was thinking about using a control port for sending commands. Are there other mechanisms more commonly used to achieve this functionality?
Please let me know if you need more specific information.
Kind regards,
Ivo
What do you consider to be an accepted solution to control a running
(console) java program. I was thinking about using a control port for
sending commands. Are there other mechanisms more commonly used to
achieve this functionality?
You can read the parameter from a .properties file. The only disadvantage with this is that the properties file will have to be read in each time you want to use that property, irrespective of whether the value has changed.
You can make use of JMX. This is a fairly nice concept in which you expose a bean to be manageable using the jconsole command (Java Management Extensions Console). Once done, you can then remotely inject values into a running JVM.
There is a nice example on Sun Oracle website that shows you how to do it.
Yes, a normal way to interact with a remote service would be a control port as you described it.
You can also control it via Database settings and create a thread which will poll for these DBs settings. The DB settings will be set via some web? UI.
If you plan on running one service with polling on one single machine I would rather recommend against it and set your service either on virtual machines or setup multiple instances of the service on one big machine with a big amount of memory. I have been using a com.sun.syndication library for feeds parsing/retrieving.
I don't want to be a captain obvious but I think it's easily achievable with a usual multi-threading application and Concurrent Queueing. If I got you correctly.
Thanks.
Imagine you have a standard java web-app using plain servlets, or SpringMVC, or whatever. You also want (for whatever reason) a way to talk to the server not using HTTP - I'll use direct sockets as it's the easiest example I can think of.
Writing a web-app is easy, you have servlets acting as entrypoints. Writing a java app which monitors ports is also pretty easy. But what about one that does both? Is it allowed without hacking? And if it turns out we agree this is a Bad Idea, what's a better architecture? Note that one of the motivations behind this is performance... we could easily have two separate apps sharing a DB but prefer to avoid using the DB as a communication tool, when information could be cached in memory much more efficiently.
So I assume there is a Java EE container in play, like Tomcat. If you want it to listen on some other port besides or in addition to 80, sure. You would make a new Connector in server.xml, in Tomcat's case, and specify whatever port you like.
If you want this connector to speak a custom protocol, you need to implement and register your own customer Connector. I've not done it, but seems straightforward.
If you're answering substantially the same requests via two protocols, it makes sense to use one server with different endpoints. I imagine it makes it far easier to share all that common logic.
Even if you want to run a separate app, it still probably pays to go this way, since you'll be leveraging the container's management of connections and such.
Between the transitions of the web app I use a Session object to save my objects in.
I've heard there's a program called memcached but there's no compiled version of it on the site,
besides some people think there are real disadvantages of it.
Now I wanna ask you.
What are alternatives, pros and cons of different approaches?
Is memcached painpul for sysadmins to install? Is it difficult to embed it to the existing infrastructure from the perspective of a sysadmin?
What about using a database to hold temporary data between web app transitions?
Is it a normal practice?
What about using a database to hold
temporary data between web app
transitions? Is it a normal practice?
Database have indeed a cache already. A well design application should try to leverage it to reduce the disk IO.
The database cache works at the data level. That's why other caching mechanism can be used to address different levels. At the java level, you can use the 2nd level cache of hibernate, which can cache entities and query result. This can notably reduce the network IO between the app. server and the database.
Then you may want to address horizontal scalability, that is, to add servers to manage the load. In this case, the 2nd level cache need to be distributed across the nodes. This exists (see JBoss cache), but can get slightly complicated to manage.
Distributed cache tend to worker better if they have simpler scheme based on key/value. That's what memcached is, but there are also other similar solutions. The biggest problem with distributed caches is invalidation of outdated entries -- which can itself turn into a performance bottleneck.
Don't think that you can use a distributed cache as-is to make your performance problems vanish. Designing a scalable distributed architecture requires experience and is always a matter of trade-off between what to optimize and not.
To come back to your question: for regular application, there is IMHO no need of a distributed cache. Decent disk IO and network IO lead usually to decent performance.
EDIT
For non-persistent objects, you have several options:
The HttpSession. Objects need to implement Serializable. The exact way the session is managed depends on the container. In a cluster, the session is usually replicated twice, so that if one node crashes you still have one copy. There is then session affinity to route the request to the server that has the session in memory.
Distributed cache. A system like memcached may indeed make sense, but I don't know the details.
Database. You could of course dump any Serializable object in the database in a BLOB. Can be an option if the web servers are not as reliable as the database server.
Again, for regular application, I would try to go as far as possible with the HttpSession.
How about Ehcache? It's an easy to use pure Java solution ready to plug in to Hibernate. As far as I remember it's supported by containers.
It's quite painless in my experience.
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-cache
This page should have everything that you need (hopefully !)