BridgePropertyPlaceholderConfigurer camel bean - java

I use the following bean to manage properties in camel as below :
<bean id="ilePropertiesConfigurer"
class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
<property name="properties" ref="allProperties" />
</bean>
allproperties is a java class. it works very well when starting the application.
But now, I want to update properties without restarting my application. I update allproperties but it still takes the old values.
Can you help me?

This is not supported in Apache Camel with that Spring property placeholder bridge. You need to restart your application.
OSGi Blueprint has a concept of allowing to reload/restart your application when properties are changed, but it does a full bundle restart command.

Related

Spring-Boot: Jmx annotation not working in library

I have a Spring-Boot application that just have a simple rest controller. On this controller, I added the jmx annotations #ManagedResource and #ManagedOperation and it is working fine. It is correctly exposed in Jmx.
This application depends on a "global-commons" library to share many basic functionality to all of our modules.
But if I add the same annotations to a class in this library, it is ignored!
And before you ask, yes the library is imported with the latest change.
There is no error or warning message in the logs.
I am configuring all my beans using an xml file. Both classes are beans defined in the same file.
One is a #RestController. The other one is a simple utility class.
Any idea?
Make sure the classes from the global-commons library as managed by Spring. As long as none of the classes in the library are managed by Spring, the annotions don't have any effect.
I found the problems:
The bean that was not working was defined as an "inner" bean:
<bean id="imMetrics" class="com.imetrik.global.common.metrics.ImGlobalMetrics" init-method="init">
...
<property name="reporterList">
<util:list>
<bean id="jmxReporter" class="com.imetrik.global.common.metrics.reporters.ImJmxReporter">
<property name="registryId" value="metricRegistry1"/>
<property name="durationUnit" value="SECONDS"/>
<property name="rateUnit" value="SECONDS"/>
<property name="domain" value="com.imetrik.global.metric"/>
</bean>
</util:list>
</property>
</bean>
The annotated beans is "jmxReporter".
But if I put it outside as a normal "first level" bean and use a reference instead, it is working.
But it is annoying! Is there a way to make it work even as a inner beans?

How to change the TaskExecutor implementation dynamically depending on the application server

I am using Spring 3.0.x to get a WorkManager from an application server and use it to run scheduled jobs that need database access. The problem is, is that this application could be deployed to different Java application servers - in this case, to Websphere 7.0 and GlassFish 3.1 OSE. (Crazy combo, I know...)
The problem I am having is that before deploying to either, I have to change the bean to reference the appropriate TaskExecutor class used for each server. I have Spring load up an applicationContext.xml with these beans in it.
For Websphere, I have to pull the WorkManager externally and use the following bean:
<bean id="myTaskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
<property name="workManagerName" value="wm/default" />
<property name="resourceRef" value="true"/>
</bean>
and the web.xml has something like this:
<resource-ref>
<description>WorkManager</description>
<res-ref-name>wm/default</res-ref-name>
<res-type>commonj.work.WorkManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
For GlassFish, I can just use the bean:
<bean id="myTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
</bean>
Can I somehow dynamically change which TaskExecutor implementation is used on the fly?
I could easily check for the Websphere resource to determine if I am on Websphere, then fall back to GlassFish. But how to load a class like that with Spring (using Annotations or otherwise) is baffling me.
Any help is appreciated. Thanks!
P.S. I am not worried about being J2EE compliant for GlassFish - it's just that Websphere forces you to be so (hence pulling an external WorkManager)
You can easily use a custom VM argument to determine what environment you are running in, and use that to load the appropriate context file.
One file for each supported environment, all of which define the same bean.
task-exec-was.xml
task-exec-glassfish.xml
Add a required VM argument.
-Dapp.server=was
Then, wherever you actually load the bean you include the appropriate file based on a PropertyPlaceholderConfigurer.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
<import resource="task-exec-${app.server}.xml" />
Edits based on information in the comments.
You can override for the environment you do have control over in this case.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="location" value="classpath:spring/was.properties/>
</bean>
<import resource="task-exec-${app.server}.xml" />
Now you have a file called spring/was.properties that defines a property app.server=was, which is read by default. In Glassfish, you supply the same property as a VM argument, which will now override the property read from the file.

Spring JMX. Set the default value of #ManagedAtrribute through XML

I'm using Spring 3.0.5
I have a #ManagedResource bean, for some of the #ManagedAttribute methods which I want to set a defaultValue. Instead of setting it to a hardcoded value I want to be able to read it from a property value at load time, since the default changes from environment to environment.
A snippet from my programs applicationContext.xml:
<context:mbean-export default-domain="sampleApp"/>
<bean id="managedBean" class="com.example.sampleBean">
<constructor-arg value="Sample Bean"/>
<constructor-arg value="${sample.property}"/>
</bean>
I believe I have to use the XML configuration to be able to do this, but haven't figured out how to do it yet.
You can add the following to your applicationContext.xml, it should expose the properties you are after:
<context:property-placeholder location="classpath:application.properties"/>
So if the application.properties file you are pointing to above contains a property called sample.property then Spring will use that to inject into your ${sample.property} placeholder.
For more details you can see the Spring reference here.

Does Spring 3.0 provides a service definition file?

I'm wondering about Spring 3.0 whether it provides an automatically generated service definition page after I defined services.
With SOAP we have a WSDL file which contains WHAT, HOW and WHERE we can call a service.
Is that possible with Spring 3.0 or not?
Yes it does. Just add "?WSDL" to the URL of your Spring-generated web service and you'll get the definition. Also you can append "?xsd=1" instead and you'll get the schema you need (this is referenced also from the WSDL).
You can use an MBeanExporter to expose all of your services via JMX, which would be viewable through a JMX dashboard on your container (IE Tomcat, Jboss, etc). This is an easy way to account for 'what is deployed'. Your question is not entirely clear what sort of artifact you're looking for though.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="autodetect" value="true"/>
</bean>
Will automatically export all of your defined beans as MBeans. Usually that's not entirely what you want, so alternatively, you'll specify them manually.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean"/>
</map>
</property>
</bean>
I agree with Chochos.
These[?wsdl, ?xsd=N] are universal standard to find the service definition file and any Datacontract defined in the wsdl.
example:
if http://localhost:8080/MyService is your service endpoint then it is service container's responsibility to make the WSDl available at http://localhost:8080/MyService,
by default.
The answer is Yes,
Use tag in your message dispatcher spring context file.
if your message dispatcher bean id is spring-ws then the spring context file for it would be spring-ws-servlet.xml.
In that context file,
import the namespace http://www.springframework.org/schema/web-services/web-services-2.0.xsd
xmlns:sws="http://www.springframework.org/schema/web-services".
then use the tag dynamic-wsdl from this namespace.
Also, you can set attributes for it like portType, binding and id. This will generate the wsdl file for you. You can view it by querying for it in the browser
/.wsdl

Out of container JNDI data source

I would like to configure a DataSource using JNDI in a Java SE app. What is the best way to do this?
So far, I've come across 2 projects:
Apache Naming. The project page has a specific example for configuring a data source, but it looks like the project is super old and no longer active.
JBossNS. It looks like it's easy to configure a local-only JNDI using LocalOnlyContextFactory, but I haven't found any docs on how to actually configure a data source.
If possible, I would like to also configure the data source with a JTA transaction manager (using JOTM?).
Why are you using JNDI for this? It's not that it's a bad solution if you have a provider but there are alternatives such as dependency injection (IoC: via Spring or Guice).
The Spring JDBC data access is described here. The great thing is that you can use Spring to inject a DataSource into your code:
<bean class="com.my.Persister">
<property name="dataSource" ref="dataSource" />
</bean>
The data source can be defined using a JNDI-lookup:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource" />
In a test environment, you could inject the data source directly:
<bean id="dataSource" class="apache.db.PoolingDataSource">
<!-- config goes here -->
</bean>
These references are pretty old but may help to use jnpserver (JBoss Naming Service provider):
Working With JNDI In A J2SE Application
Standalone JNDI server using jnpserver.jar
A very easy to use solution for stand-alone JNDI is simple-jndi. It works like a charm as long as you only need it within a single JVM, since it's a library no network server.
The Simple-JNDI version, referenced by klenkes74, is not under active development any more. Because I encountered some issues with it I forked it, did some bug fixes and implemented some new features. I already used the old version not only for testing but in production too because I prefer a Service Locator pattern over Dependency Injection although the latter one is more trendy nowadays.
You can easily use Simple-JNDI to define a DataSource or a connection pool declaratively and get it bound to a JNDI Context.
Define a jndi.properties file in your classpath:
java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
org.osjava.sj.root=[absolute_or_relative_path_to_a_property_file]
The property file looks like:
type=javax.sql.DataSource
driver=org.gjt.mm.mysql.Driver
url=jdbc:mysql://localhost/testdb
user=testuser
password=testing
Now you can access your DataSource from inside your code this way:
InitialContext ctxt = new InitialContext();
DataSource ds = (DataSource) ctxt.lookup("name_of_your_datasource");
For more information see https://github.com/h-thurow/Simple-JNDI

Categories

Resources