aspose file tools*
The moose likes Struts and the fly likes message-resources reload Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Frameworks » Struts
Bookmark "message-resources reload" Watch "message-resources reload" New topic
Author

message-resources reload

P-A Rosenberg
Greenhorn

Joined: Sep 22, 2005
Posts: 15
Hi
I'm using Struts message-resources and it works fine. I wonder if there is a way to configure the struts framework to reload the properties red from the resource file without restarting the webserver? I wold like to be able to reload the properties upon change, alternatively reload the property file every 30 minutes or so. Is there a way to do this?

I have searched the web on it and seen the question asked. The only solution I have found on this issue is to use other ways to handle properties and avoid message-resources.


I'm using Tomcat 5.5.9 and struts 1.2.7.

Struts-config.xml:
<message-resources
parameter="MyWebAppResources"
null="false" />

Property file:
my.property=ABC

In JSP:
<bean:message key="my.property"/>

Help is appreciated!
Thanx'
//P-A
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Struts loads the message resource file into memory when the Action servlet is initialized. I don't know of a way to make it reload except by going in and modifying the struts code.

It is important to realize, though, that in order to refresh the message resource file, it is NOT necessary to restart the SERVER. It IS necessary to restart the APPLICATION. Restarting the application is much faster than restarting the server.


Merrill
Consultant, Sima Solutions
P-A Rosenberg
Greenhorn

Joined: Sep 22, 2005
Posts: 15
Originally posted by Merrill Higginson:
It is important to realize, though, that in order to refresh the message resource file, it is NOT necessary to restart the SERVER. It IS necessary to restart the APPLICATION. Restarting the application is much faster than restarting the server.


I'm not sure I understand what you mean by restarting the application, not the server. Can this be done when using Tomcat?
Is it reload yo refer to?
It seems like the reload option in Tomcat causes memory leaks and the server will run out of memory after X repeated reload actions. I have been recommended not to use reload in production environment due to this problem.
Can you please explain further what you mean by relaoding the application.


I have found this example and the author claims that he go it to work. I can't get the resource to reload this way but maybee someone can tell me what is wrong with the example?

Thanx'
//P-A
[ November 08, 2005: Message edited by: P-A Rosenberg ]
P-A Rosenberg
Greenhorn

Joined: Sep 22, 2005
Posts: 15
Hi again,
To whom it may concern...
This problem has now been solved.
The solution was to create a MessageResourceFactory that extends MessageResourcesFactory and define it in struts-config.xml.

struts.xml:
<message-resources
parameter="MessageResources"
factory="my.package.MyMessageResourceFactory"
null="false" />

MyMessageResourceFactory:
public class MyMessageResourceFactory extends MessageResourcesFactory
{
public MessageResources createResources(String config)
{
return new MyMessageResources(this, config, this.returnNull);
}
}

MyMessageResources:
public class MyMessageResources extends MessageResources
{

public MyMessageResources(MessageResourcesFactory factory, String config, boolean returnNull)
{
super(factory, config, returnNull);
}

public String getMessage(Locale locale, String key)
{
// get the configuration for the specified locale
Configuration resource = getConfiguration(this.config + "_" + locale.getLanguage() + ".properties");

if(resource == null || !resource.containsKey(key))
{
// look for the key in the root configuration
resource = getConfiguration(this.config + ".properties");
}
return resource != null ? resource.getString(key,null) : null;
}

private Configuration getConfiguration(String name)
{
Configuration configuration = null;
URL url = Thread.currentThread().getContextClassLoader().getResource(name);
if(url != null)
{
PropertiesConfiguration pc = new PropertiesConfiguration();
pc.setURL(url);
FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
strategy.setRefreshDelay(10000); //Milli seconds
pc.setReloadingStrategy(strategy);

try
{
pc.load();
configuration = pc;
}
catch(ConfigurationException e)
{
//Logg it
}
}

return configuration;
}

}

I didn't sove this myself so I might not be able to answer questions on it.. . The example have to be modified to suite the specific project.

//P-A R
ajay halmandge
Greenhorn

Joined: Oct 04, 2005
Posts: 7
To turn on servlet reloading, edit Edit install_dir/conf/context.xml and change

<Context>
to
<Context reloadable="true">



for Tomcat 5.X

for Tomcat less then 5.x put

<Context path="" docBase="ROOT" debug="0"/>
<DefaultContext reloadable="true"/>

in server.xml


There is a possibility to restart only webappl without restarting the sever, it could be a solution.


1. go and change ur tomcat-users.xml and add a user with such a line

<user name="yourname" password="yourpassword" roles="manager" />

2. restart ur tomcat.

3. in ur web browser, type http://localhost:8080/manager/list (or whatever port u r using)

4. log in with the password and name, u shld see the list of the applications running

5. type http://localhost:8080/manager/stop?path=/myapp to stop that specific app

6. type http://localhost:8080/manager/start?path=/myapp to start that app again.

7. the updated compiled beans or classes should load properly
ajay halmandge
Greenhorn

Joined: Oct 04, 2005
Posts: 7
Yes myself found the solution.

Touch the top level descriptor. Updating the file works as well as it changes the timestamp.

Here are the descriptors for the most common archive types:

.JAR
META-INF/ejb-jar.xml

.WAR
WEB-INF/web.xml

.EAR
META-INF/application.xml

.SAR
META-INF/jboss-service.xml
P-A Rosenberg
Greenhorn

Joined: Sep 22, 2005
Posts: 15
Originally posted by ajay halmandge:
To turn on servlet reloading, edit Edit install_dir/conf/context.xml and change

<Context>
to
<Context reloadable="true">


Thanx ajay halmandge for your answer. I'm affraid the reload that you describe is not what I was after. Reload of a single application works fine, but that eats memory and is not recommended in production environment according to Tomcat doc. What I was after was possibility to reload the property file into the applciation memory on regular basis. This is what my proposed solution does. With the solution the application can be configured to read the resource from file if the timestamp on resource in memory is older than a specified time.
Thank you anyway
//P-A
Stefaan Huysentruyt
Greenhorn

Joined: Dec 16, 2005
Posts: 3

Just subclass both PropertyMessageResources and PropertyMessageResourceFactory. Name them something like ReloadablePropertyMessageResources and ReloadablePropertyMessageResourcesFactory and configure them like this:


The sources:

ReloadablePropertyMessageResources.java



ReloadablePropertyMessageResourcesFactory.java


Just put some statement like this in an Action:


and voil�...
[ December 16, 2005: Message edited by: Stefaan Huysentruyt ]

-- "Be liberal in what you accept, and conservative in what you send."
-- Jon Postel (August 6, 1943 - October 16, 1998) Internet Pioneer
-- http://www.postel.org/postel.html
Christina De Sousa
Greenhorn

Joined: Aug 05, 2005
Posts: 3
I did get it to work, here is what I have done:

I have a ApplicationError.properties file under /src/resources that neededs to be reloaded.

set up a filter that gets executed before an action:
i.e.
<filter-mapping>
<filter-name>I18nFilter</filter-name>
<servlet-name>action</servlet-name>
</filter-mapping>

in this filter do the following:

String applicationFilename = "resources.ApplicationError";
MessageResourcesFactory factory = MessageResourcesFactory.createFactory();
PropertyMessageResources pmr = new PropertyMessageResources(factory, applicationFilename);
ServletContext ctx = session.getServletContext();
ctx.setAttribute(Globals.MESSAGES_KEY , pmr);

in the struts-config.xml:
<message-resources parameter="resources.ApplicationError" null="false"/>

in your jsp:
<html:errors/>

Hope this helps.
CDS
Michael B�ckling
Greenhorn

Joined: Mar 26, 2008
Posts: 3
I solved the hot-reloading for Struts message resources (beware, Java 5 code).

Here are the two required classes:

Set the factory:


ReloadablePropertyMessageResources:


ReloadablePropertyMessageResourcesFactory:


[ March 26, 2008: Message edited by: Michael B�ckling ]
[ March 26, 2008: Message edited by: Michael B�ckling ]
Sai Narasimha Reddy
Greenhorn

Joined: Dec 13, 2006
Posts: 23
Good work Mr.B�ckling.

Can we replace the ConcurrentHashMap with FastHashMap that comes with commons-collections package??


Sai Narasimha
Siraj Lakhani
Greenhorn

Joined: Nov 07, 2008
Posts: 1
Hi,

We have the similar requirement where we don't want to restart the application and reload the resource file.

I tried ���P-A Rosenberg��� solution to create MyMessageResourceFactory but he problem with this approach is MyMessageResourceFactory gets called once for a given key. If you want the message related to same key, the MyMessageResourceFactory is not called once again and hence the old value is displayed.

The other solution provided requires reloading manually by either writing in action class or in filter. This would require reloading the resource file for each single request and would result into performance issue.

Is there anyway by which values could be retrieved from cache for particular time period and then reloading the file for latest values after time is expired? Please help
PradeepKumar Dev Venkata
Greenhorn

Joined: Feb 19, 2009
Posts: 6
I have implemented the way Michael B�ckling has suggested.

But i am getting ClassCastException

java.lang.ClassCastException: com.tpgsi.tsi.util.ReloadablePropertyMessageResourcesFactory cannot be cast to org.apache.struts.util.MessageResourcesFactory

here is the code:

import org.apache.struts.util.MessageResources;
import org.apache.struts.util.MessageResourcesFactory;

public class ReloadablePropertyMessageResourcesFactory extends MessageResourcesFactory
{


public ReloadablePropertyMessageResourcesFactory()
{
super();
}

public MessageResources createResources(final String config)
{
return new ReloadablePropertyMessageResources(this, config, this.getReturnNull());
}
}


Can any one please help.

Thanks,
Pradeep
PradeepKumar Dev Venkata
Greenhorn

Joined: Feb 19, 2009
Posts: 6
Experts,

Its been really long time since i posted my problem.

I really need this fixed. Please Help me out. Your hep is appreciated.

Thanks,
Pradeep
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: message-resources reload