In Java, how to reload dynamically resources bundles in a web application? - java

We are using fmt:setBundle to load a resource bundle from a database (we extended the ResourceBundle class to do that).
When we modify a value in database, we have to reload the web server to display the new value on the web app.
Is there any simple way to use the new value without restarting the web server ?
(We do not want to always look up the value from database but we would like to invalidate the cache, for example by calling a special 'admin' URL)
EDIT : We are using JDK 1.4, so I would prefer a solution on that version. :)

If you're using JDK 1.6 you can use the callback methods getTimeToLive() and needsReload() in ResourceBundle.Control to control if the bundle cache needs to be loaded with new values from the database.

As others have pointed out in the comments, you might want to look into Spring - particularly the ReloadableResourceBundleMessageSource.

First you can create a class which extends from ReloadableResourceBundleMessageSource to expose its inner class protected method called getProperties. This method return a concurrent map from PropertiesHolder object. Second you should configure a bean of that extended class in you web configuration class. Now you able to use messageSource in your service or business layer. Here is the reference link Configure reloadable message source bundle

Related

Replace default resourceBundle and resourceControl implementations in JSP web application

in an existing Web Application (JSP, Struts), localizations are managed through JSTL tags fmt:setbundle, fmt:message and .properties files.
I'd like to get rid of the .properties files and use an alternative datasource for localizations.
For my goal I've created custom ResourceBundle and ResourceControl implementations (details on where data is picked, xml, database, are out of scope), but I'm wondering how to register and use them in place of the default/factory file-based implementation, so I'm not forced to modify markup code (fmt:message...) among web application files.
I saw examples that point to replace fmtResourceKey session value but it's limited to only one bundle and it looks like an "hack".
Any good ideas?
Thanks for your help!
Ok, it seems I sorted out with subclassing/customizing java.util.ResourceBundle, which also carries implementantion of custom ResourceBundleControl and ResourceBundleControlProvider (injected through Service Provider Interface - SPI).
Similar solution is depicted in this page from Oracle:
https://docs.oracle.com/javase/tutorial/i18n/serviceproviders/resourcebundlecontrolprovider.html
but was lacking an important hint: "put your JAR inside VM" since ResourceBundle.GetBundle method internally uses Serviceloader.LoadInstalled which searches for custom provider installed inside Java VM, as stated in LoadInstalled documentation:
This method is intended for use when only installed providers are
desired. The resulting servicewill only find and load providers that
have been installed into the current Java virtual machine; providers
on the application's class path will be ignored.
Thanks!

hazelcast : changing configuration programatically doesnt work

I am unable to configure/change the Map(declared as part of hazelcast config in spring) properties after hazelcast instance start up. I am using hazelcast integrated with spring as hibernate second level cache. I am trying to configure the properties of map (like TTL) in an init method (PostConstruct annotated) which is called during spring bean initialization.
There is not enough Documentation , if there is please guide me to it.
Mean while i went through this post and found this Hazelcast MapStoreConfig ignored
But how does the management center changes the config, will it recreate a new instance again ?
Is hazelcast Instance light weight unlike session factory ? i assume not,
please share your thoughts
This is not yet supported. JCache is the only on-the-fly configuration data structure at the moment.
However you'll most probably be able to destroy a proxy (DistributedObject like IMap, IQueue, ...), reconfigure it and recreate it. Anyhow at the time of recreation you must make sure that every node sees the same configuration, for example by storing the configuration itself inside an IMap or something like that. You'll have to do some wrapping on your own.
PS: This is not officially supported and an implementation detail that might change at later versions!
PPS: This feature is on the roadmap for quite some time but didn't made it into a release version yet, it however is still expected to have full support at some time in the future.

Why LocalEntityManagerFactoryBean class is called "Local"?

Spring has a class called LocalEntityManagerFactoryBean. Why is this class called "Local"? In what meaning is it local? Is there some RemoteEntityManagerFactoryBean class in Spring as well?
I dont have an authoritative source, however I'm pretty sure that it is "Local" in that it is local to the spring application context used by the application.
Spring doesn't provide a Remote EMF, however other components such as application servers will. For instance JBoss AS (an open source J2EE app server) can manage JPA EMF's and will make it available to your application at runtime, eg over JNDI, refer to the JBoss docs

Runtime loading of Controllers for Spring MVC and dynamically mapping requests/URLs

We are starting a new project using Spring MVC, and we would like to move away from annotation-driven request/url mapping. We wish to implement the following use case:
Use Case A
User enters a URL.
The request mapping handler retrieves a list of mappings (e.g. from the DB), and based on this dynamic list of mappings, it calls the relevant controller.
This is because we want to be able to do the following as well:
Use Case B
We want to load a new Controller (perhaps a new reports module) into the web app without having to redeploy or do a server restart.
We will map this new Controller to a URL and persist it somewhere (most likely the DB).
We would like the Controller to be registered in the Spring app context (managed by Spring).
We would then like to use this new Controller in the request mapping.
We've taken an initial look at the different ways we can implement this, but we are unsure of the best architecture/method to go about this route. A couple of questions:
For Use Case A, how do we implement this within the Spring MVC framework (or if it's possible)?
For Use Case B, is there a good framework or way to be able to do dynamically loading and registering of this for web applications? We've taken a cursory look at OSGI but it seems to be advisable for use in non-web applications.
For Use case A :
Instead of DB you can keep the url mappings in a property file and then use property place holder to initialize beans using xml configuration on context up. This way remaining inside the spring framework, you can avoid annotations.
For Use Case B :
Tomcat supports dynamic reloading of classes but that to of only non structural changes in class file. But this has memory leaks as well as it doesnt cleans up old instance of class loader rather it creates a new instance.
Its quite achievable using spring-mvc-router API.
Please check below link
url-action mapping & routing in Spring MVC 3.0
Here the URL can be configured to controller.method using .conf file, but this can be achievable using java configuration, and i haven't tried so far.
Also if xml configuration chosen, then check out the property 'autoReloadEnabled', but its not adviceable for production use.
Hope this helps!!!

Create a new mixin in sling

I am having trouble create a new custom type to the jackrabbit in apache sling using the below code. This worked fine straight on Jackrabbit but not on Apache Sling. Am I doing this correctly for sling? Thanks
The following code gives me a "javax.jcr.InvalidItemStateException: Conflict". I am using a standalone sling and am the only user so there is definitely no conflict.
Repository repository = JcrUtils.getRepository("http://localhost:8080/server");
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
NamespaceRegistry registry = session.getWorkspace().getNamespaceRegistry();
registry.registerNamespace("my", "http://my.com/v1.0");
CndImporter.registerNodeTypes(new FileReader("C:\\test.cnd"), session);
If you're using Sling, you can avoid all this by putting your CND file in an OSGi bundle (where your java code should reside anyway), with a header that tells Sling where to find it.
Your node types will then be registered automatically when your bundle is activated. For an example of this see the event.cnd file which is declared in a Sling-Nodetypes bundle header that's set in that module's pom.xml (or in any other way if you're not using Maven).
Note also that you shouldn't need JcrUtils.getRepository in Sling anyway, the right way to get a repository is via the SlingRepository OSGi service, which takes care of repository login and configuration in a consistent way for all your Sling components. You can get the repository via a #Reference to a SlingRepository in java code, or get a JCR Session from the Resource that Sling provides to request handlers like servlets and scripts. The Slingbucks sample uses both mechanisms.
The JavaDocs for InvalidItemStateException offer this clue:
Exception thrown by the write methods of Node and Property and by save
and refresh if an attempted change would conflict with a change to the
persistent workspace made through another Session. Also thrown by
methods of Node and Property if that object represents an item that
has been removed from the workspace.
Are you sure that you don't have any old sessions still running, perhaps is a daemon process that hasn't been shut down properly?

Categories