What are the other ways to specify code for Insight to analyze? - spring-insight

Spring Insight documentation states:
A trace represents a thread of execution. It is usually started by an HTTP request but can also be started by a background job
My application architecture style is one of queues running in the background that I'd like to instrument as well. However, I can't figure out how to get Spring Insight to instrument these calls initiated by queued message. I.e. I'd like to instrument the trace after a message is read off of the queue.
How can I ensure Insight instruments these background jobs?

I ended up creating an aspect that targets all of the Command Handlers. It extends the AbstractOperationCollectionAspect, implements the collectionPoint aspect passing in the Handler as an argument to use when it implements the createOperation method.
I.e.
public aspect CommandHandlerOperationCollectionAspect extends AbstractOperationCollectionAspect
{
public pointcut collectionPoint():
execution(* com.xtrac.common.core.handler.ThreadedHandler.HandlerRunnable.executeActorHandler(com.xtrac.common.core.handler.Handler,java.lang.Object));
protected Operation createOperation(JoinPoint jp)
{
Object[] args = jp.getArgs();
com.xtrac.common.core.handler.Handler handler = (Handler) args[0];
Operation operation = new Operation()
.type(XTRACOperationType.COMMAND_HANDLER)
.label(handler.getClass().getSimpleName())
.sourceCodeLocation(getSourceCodeLocation(jp));
return operation;
}
#Override
public String getPluginName()
{
return HandlerPluginRuntimeDescriptor.PLUGIN_NAME;
}
#Override
public boolean isMetricsGenerator()
{
return true;
}
}
I also implemented an AbstractSingleTypeEndpointAnalyzer to fill out the analyzer:
public class HandlerEndPointAnalyzer extends AbstractSingleTypeEndpointAnalyzer
{
private static final HandlerEndPointAnalyzer INSTANCE=new HandlerEndPointAnalyzer();
private HandlerEndPointAnalyzer() {
super(XTRACOperationType.COMMAND_HANDLER);
}
public static final HandlerEndPointAnalyzer getInstance() {
return INSTANCE;
}
#Override
protected EndPointAnalysis makeEndPoint(Frame handlerFrame, int depth) {
Operation operation = handlerFrame.getOperation();
String resourceLabel = operation.getLabel();
String exampleRequest = EndPointAnalysis.getHttpExampleRequest(handlerFrame);
return new EndPointAnalysis(EndPointName.valueOf(resourceLabel),
resourceLabel,
exampleRequest,
getOperationScore(operation, depth),
operation);
}
being sure to add it as a descriptor:
public class HandlerPluginRuntimeDescriptor extends PluginRuntimeDescriptor {
public static final String PLUGIN_NAME = "handler";
private static final HandlerPluginRuntimeDescriptor INSTANCE=new HandlerPluginRuntimeDescriptor();
private static final List<? extends EndPointAnalyzer> epAnalyzers=
ArrayUtil.asUnmodifiableList(HandlerEndPointAnalyzer.getInstance());
private HandlerPluginRuntimeDescriptor() {
super();
}
public static final HandlerPluginRuntimeDescriptor getInstance() {
return INSTANCE;
}
#Override
public Collection<? extends EndPointAnalyzer> getEndPointAnalyzers() {
return epAnalyzers;
}
#Override
public String getPluginName() {
return PLUGIN_NAME;
}
}
All noted in the spring xml file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:insight="http://www.springframework.org/schema/insight-idk"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/insight-idk http://www.springframework.org/schema/insight-idk/insight-idk-1.0.xsd">
<insight:plugin name="handler" version="${project.version}" publisher="XTRAC Solutions LLC" />
<insight:operation-group group="XTRAC Handlers" operation="command_handler_operation" />
<insight:operation-group group="XTRAC Handlers" operation="event_handler_operation" />
<insight:operation-group group="XTRAC Classic" operation="xtrac_workflow_operation" />
<insight:operation-view operation="command_handler_operation"
template="com/xtrac/insight/command_handler_operation.ftl" />
<insight:operation-view operation="event_handler_operation"
template="com/xtrac/insight/event_handler_operation.ftl" />
<insight:operation-view operation="xtrac_workflow_operation"
template="com/xtrac/insight/xtrac_workflow_operation.ftl" />
<bean id="handlerPluginEndPointAnalyzer"
class="com.xtrac.insight.HandlerEndPointAnalyzer"
factory-method="getInstance"
lazy-init="true"
/>
<bean id="handlerPluginRuntimeDescriptor"
class="com.xtrac.insight.HandlerPluginRuntimeDescriptor"
factory-method="getInstance"
lazy-init="true"
/>
</beans>
along with some ftls.
I also created a MethodOperationCollectionAspect to collect some of the web service calls that occur in these handers. This sets it up for a nice display that tells me a lot about what is going on during the hander operation, and how much time it takes. E.g.
This set up a framework for maintaining a monitor on the health of the application if I set up the base line Thresholds for the named handlers
This is very useful because I can then tell if the application is healthy. Otherwise, the endpoints default to <200 ms for healthy.

Related

MockMvc tests always returns status code 200 for get requests

I I am very new to spring boot and only have been working with it for a couple of days, so I am also very confused about this project (which is not my own). I am supposed to write tests with MockMvc for the rest controller, however each test with MockMvc only returns the status code 200 although it should be a 404.
Here is one of the tests:
#WebMvcTest(ObjectController.class)
#SpringJUnitConfig(TestConfig.class)
public class MvcTest {
#Autowired
MockMvc mockMvc;
#Test
public void shouldReturn404() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/obj/123"))
.andExpect(MockMvcResultMatchers.status().is(HttpStatus.NOT_FOUND.value()));
}
}
This is my rest controller I would like to test.
#RestController
#RequestMapping("obj")
public class ObjectController {
#Autowired
MyClass myClass;
#GetMapping()
public List<MyObject> findAll() {
List<MyObject> objList;
objList = myClass.getObjects();
return objList;
}
#GetMapping("/{id}")
public MyObject findById(#PathVariable String id) {
for (MyObject obj : myClass.getObjects()) {
if (obj.getId().equals(id))
return obj;
}
return null;
}
}
Then there is this class:
public class MyClass {
private List<MyObject> objList = new ArrayList<MyObject>();
public MyObject addObject(MyObject obj) {
objList.add(obj);
return obj;
}
public void setObjects(List<MyObject> objList) {
this.objList = objList;
}
public synchronized List<MyObject> getObjects() {
return objList;
}
}
There is an xml file that belongs to the class looking like this which can be found in the resource folder:
<?xml version='1.0' encoding='ISO-8859-1'?>
<beans xmlns='http://www.springframework.org/schema/beans'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:context='http://www.springframework.org/schema/context'
xsi:schemaLocation='http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd'>
<bean id='MyClass' class='it.is.some.path.MyClass'>
<property name='objList'>
<list>
<ref bean='[R01] Object1' />
</list>
</property>
</bean>
</beans>
The referenced beans can be found in separate files under resources too, in a sub folder called 'objList' and look like this:
<?xml version='1.0' encoding='ISO-8859-1'?>
<beans xmlns='http://www.springframework.org/schema/beans'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:context='http://www.springframework.org/schema/context'
xsi:schemaLocation='http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd'>
<bean id='[R01] Object1' class='this.is.some.path.MyObject'>
<property name='id' value='123' />
</bean>
</beans>
The myclass.xml as well as the folder with all xmls of the objects are imported via #ImportResource in the Application class.
And then there is
public class MyObject {
public String id = RandomStringUtils.randomAlphanumeric(5);
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
am sorry for the lengthy explanation but I have been spending two days now trying to figure out how to get MockMvc running and I feel like I am completely stuck. I would be very, very grateful if anybody could help out.
I assume 200 is the correct response as you have a mapping for /obj/{id} where {id} is a placeholder for any path variable like 123 in /obj/123.
Even though your controller returns null from a code perspective, Spring won't map this automatically to a 404 not found if this is what you would expect.
So you can literally try it with every path variable, you'll always get HTTP 200 because there wasn't any exception and the DisptacherServlet could properly route the HTTP request to a controller mapping. HTTP 200 is the default response code if you don't specify anything.
If you want your controller endpoint to return 404 when your MyObject is null, you have to be more explicit about this, e.g.:
#GetMapping("/{id}")
public ResponseEntity<MyObject> findById(#PathVariable String id) {
for (MyObject obj : myClass.getObjects()) {
if (obj.getId().equals(id))
return ResponseEntity.ok(obj);
}
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}

Cucumber-spring is not finding Step Definitions

I need help!
so the following code works for me (Pure JUnit code)
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration("classpath:/importMasterConfig.xml")
public class FeatureWrittenInJavaUsingSteps {
#Before()
public void setup(){
/*do something*/
}
#After
public void tearDown()
{
/*Do something*/
}
#Autowired
ItemServiceController service;
#Test
public void callingStepFunctionsExample(){
ItemServiceControllerTestsSteps steps = new ItemServiceControllerTestsSteps(service);
steps.I_prepare_a_X_item_for_the_X_dealer("only images and pricing", "furniture");
steps.I_perform_the_X_inventory_service_call("createItem");
steps.I_should_get_the_X_response_code("200");
steps.the_inventory_service_response_result_should_be_a_X_object("Vertical Item");
}
}
However, when I try to run this code using the Cucumber Feature, it can't seem to build correctly. I am assuming I am setting up the project wrong.
Here is my Step code:
#ContextConfiguration("classpath:cucumber.xml")
public class ItemServiceControllerTestsSteps {
//Common variables across steps - currently only local.
private VerticalItem itemToCreate;
private ServiceResponse response;
//Step specific variables.
#Autowired
private ItemServiceController itemService;
public ItemServiceControllerTestsSteps(ItemServiceController service){
itemService = service;
}
#Before()
public void setup(){/*Do something*/}
#After()
public void tearDown(){/*Do Something*/}
#Given("^I prepare a \"(.*)\" item for the \"(.*)\" dealer$")
public VerticalItem I_prepare_a_X_item_for_the_X_dealer(String itemType, String dealerType){ //Step function and factory in one.
/*Do stuff*/}
#When("^I perform the \"(.*)\" inventory service call$")
public void I_perform_the_X_inventory_service_call(String actionType){
/*Do Stuff*/}
#Then("^I should get the \"(.*)\" response code$")
public void I_should_get_the_X_response_code(String codeType){/*Do stuff*/}
#Then("^the inventory service response result should be a \"(.*)\" object$")
public void the_inventory_service_response_result_should_be_a_X_object(String expectedClassType){ /*Do Stuff*/}
}
Here is my cucumber.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cucumber.runtime.java.spring stepDefinitions"/>
<context:annotation-config/>
<import resource="classpath:importMasterConfig.xml"/>
</beans>
Finally here is my Runner Class:
#RunWith(Cucumber.class)
#CucumberOptions(plugin = {"pretty", "rerun:rerun.txt", "html:target/local-html-report/"},
glue = "stepDefinitions.ItemServiceControllerTestsSteps")
public class CucumberRunner {}
If someone can please enlighten me why the JUnit runner works and the cucumber one doesn't I would be a very happy camper!
In the above code, I did a few things wrong but lets cover the big ones.
1) My Glue code String was incorrect, I need to pass in the package name, not the file name (should have been just stepDefinitions)
2) I was using Spring 3 instead of Spring 4 with Cucumber 1.2.2 - The latest Cucumber requires Spring 4.
The other stuff wasn't actually related to Spring and Cucumber.
Step definitions should be instance methods on the step definitions classes, and not class (static) methods.
Step definitions classes are instantiated (on demand) for each scenario, so no state should be leaked between scenarios.

Unable to move from controller to view in Spring MVC

I am using Spring MVC framework for my project.
I am unable to get my code running from controller to view.
Sharing the important chunk of code here.....
Inside AdminController.java controller
System.out.println("controller returning");
return new ModelAndView("dataFrame_","frameData",dataString);
Inside dispatcher-servlet.xml
<bean name="/dataFrame.htm"
class="com.organization.dept.spec.proj.module.controller.DataFrameController" >
</bean>
<bean id="dataFrameViewResolver"
class="com.organization.dept.spec.proj.module.view.DataFrameViewResolver">
<property name="dataFrameView">
<bean class="com.organization.dept.spec.proj.module.view.DataFrameView" />
</property>
<property name="dataFramePrefix" value="dataFrame_"></property>
</bean>
inside DataFrameViewResolver.java
public class DataFrameViewResolver extends AbstractCachingViewResolver {
private String dataFramePrefix;
private View dataFrameView;
#Override
protected View loadView (String viewName, Locale locale) throws Exception {
View view = null;
if(viewName.startsWith(this.dataFramePrefix)){
view = dataFrameView;
}
return view;
}
and
public String getDataFramePrefix() {
return dataFramePrefix;
}
public void setDataFramePrefix(String dataFramePrefix) {
this.dataFramePrefix = dataFramePrefix;
}
public View getDataFrameView() {
return dataFrameView;
}
public void setDataFrameView(View dataFrameView) {
this.dataFrameView = dataFrameView;
}
}
inside DataFrameView.java ...
public class DataFrameView extends AbstractView {
#Override
protected void renderMergedOutputModel(Map map, HttpServletRequest request,HttpServletResponse response) throws Exception {
System.out.println("RenderMergeoutputModel"); //line 99
I was unable to get the above system.out.println i.e. was unable to execute my code till that line 99.
The localhost log files of tomcat revealed some exception java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config
I put the jstl-1.2.jar in lib and this could just get me rid of exception however still was unable get sysout of DataFrameView of line 99.

OSGi Declarative Services - NullPointer Exception

I have a problem with my Declarative Services. I have 2 bundles, one is a server provider and another the user interface that consumes the service.
On server side, the implementation is:
public boolean checkUser(){
return true;
}
And the XML file inside OSGi-INF folder:
<component name="ZBService">
<implementation class="service.ZBService" />
<service>
<provide interface="service.IZBService" />
</service>
</component>
On client side, the implementation is:
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService{
IZBService zb;
public void setZBService(IZBService eventAdmin) {
this.zb = eventAdmin;
}
public void unsetZBService(IZBService eventAdmin){
if(this.zb == eventAdmin){
this.zb = null;}
}
public boolean greetServer(String input, String input2) throws Exception {
return zb.checkUser();
}
}
And XML file:
<component name="ZBService">
<implementation class="main.java.com.gwt.app.server.GreetingServiceImpl" />
<service>
<provide interface="main.java.com.gwt.app.client.GreetingService"/>
</service>
<reference name="zb" interface="service.IZBService" bind="setZBService" unbind="unsetZBService" cardinality="0..n" policy="dynamic" />
</component>
Also, I have included the tag Service-Component on manifest file and I have deployed the equinox ds bundle that is ACTIVE.
The client is a GWT user interface, then I inject the service reference into server side of GWT. Well, when I deploy the application on Equinox it runs, but when I push the button, I launch an event to call ZBService. I have debugged the application and the error is zb attribute is null. It is to say, the dependence is nos injected. However the services are exposed on Equinox. If I write services on Equinox console, the services are deployed. Then, my conclusion is the error is due to the injection does not perform.
I would like to know if someone knows what is the reason??
Thanks a lot in advance!!
Nice day
EDIT:
I did your suggestions but it doesn't run. I change the component names and condinality/policy. The result is the same --> NullPointerException due to the injection isn't done.
Also I have debug the application to see if the methods bind and/or unbind are called, but they aren't.
The complete class is:
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService{
static protected IZBService zb;
public GreetingServiceImpl(){
System.out.println("Constructor GreetingServiceImpl");
}
public IZBService getZb() {
return zb;
}
public void setZb(IZBService zb) {
GreetingServiceImpl.zb = zb;
}
public void unsetZb(IZBService zb) {
GreetingServiceImpl.zb = zb;
}
#Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Cache the current thread
Thread currentThread = Thread.currentThread();
// We are going to swap the class loader
ClassLoader oldContextClassLoader = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(this.getClass().getClassLoader());
super.service(req, resp);
currentThread.setContextClassLoader(oldContextClassLoader);
}
public void activate(ComponentContext context) {
System.out.println("Creating new greeter for " + context.getProperties().get("name")
+ ": " + context.getComponentInstance().toString());
}
public void activate() {
System.out.println("Activando la referencia al servicio");
}
public void deactivate(ComponentContext context) {
System.out.println("Deactivating greeter for " + context.getProperties().get("name")
+ ": " + context.getComponentInstance().toString());
}
public boolean greetServer(String input, String input2) throws Exception {
return zb.checkUser();
}
}
And the XML client is:
<?xml version="1.0" encoding="UTF-8" ?>
<scr:component name="serviceZB" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
<implementation class="main.java.com.gwt.app.server.GreetingServiceImpl" />
<!-- <service>
<provide interface="main.java.com.gwt.app.client.GreetingService"/>
</service> -->
<reference name="zb" interface="service.IZBService"
bind="setZb" unbind="unsetZb" cardinality="1..1"
policy="static" />
</scr:component>
Why isn't the service injected if the service is deployed???
Here is a list of things you can try:
First, remove the "static" of zb, that could be the problem.
If you are using Equinox, add the -Dequinox.ds.print=true flag to the VM arguments and see more information about parsing XMLs and so
Of course, add sysouts to setZB and unsetZB :)
Remember that IZBService implementation needs a constructor without arguments
If you are using Equinox use the "list -c" command to obtain information of each component (it's cool because says exactly why a component is not registered).
Set the "inmediate=true" in XMLs to force to inmediatly activation.
You have both components with the same name, , which is kind of awkward when discussing them.
The reference on the client side has: cardinality="0..n" policy="dynamic". Which means it can be activated with zero to n references. Yet your code does not handle this. It seems to expect exactly one reference. Perhaps you should use cardinality="1..1" policy="static".

How to get values from property-file into Map using Spring framework?

For now I could inject values from property-files:
#Value("${aaa.prop}")
public String someProp;
But I want something more...
For example I have some property file:
aaa.props=p1,p2,p3
aaa.props.p1=qwe
aaa.props.p2=asd
aaa.props.p3=zxc
I know for sure, that it contains property aaa.props, and know nothing about other properties. And I want to get this properties in to map using code like this:
#Value ("${aaa.props}")
public Map<String, String> someProps;
Resulting someProps: {p1=qwe,p2=asd,p3=zxc}
Well I built a generic approach for you: a factory bean that creates a map by filtering another map (properties are a kind of map, after all).
Here's the factory bean:
public class FilteredMapFactoryBean<V> extends
AbstractFactoryBean<Map<String, V>>{
private Map<String, V> input;
/**
* Set the input map.
*/
public void setInput(final Map<String, V> input){
this.input = input;
}
/**
* Set the string by which key prefixes will be filtered.
*/
public void setKeyFilterPrefix(final String keyFilterPrefix){
this.entryFilter = new EntryFilter<String, V>(){
#Override
public boolean accept(final Entry<String, V> entry){
return entry.getKey().startsWith(keyFilterPrefix);
}
};
}
public static interface EntryFilter<EK, EV> {
boolean accept(Map.Entry<EK, EV> entry);
}
/**
* If a prefix is not enough, you can supply a custom filter.
*/
public void setEntryFilter(final EntryFilter<String, V> entryFilter){
this.entryFilter = entryFilter;
}
private EntryFilter<String, V> entryFilter;
/**
* {#inheritDoc}
*/
#Override
public Class<?> getObjectType(){
return Map.class;
}
/**
* {#inheritDoc}
*/
#Override
protected Map<String, V> createInstance() throws Exception{
final Map<String, V> map = new LinkedHashMap<String, V>();
for(final Entry<String, V> entry : this.input.entrySet()){
if(this.entryFilter == null || this.entryFilter.accept(entry)){
map.put(entry.getKey(), entry.getValue());
}
}
return map;
}
}
Here is a spring bean definition file with some sample usage:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- use System.getProperties() as input -->
<bean class="spring.test.FilteredMapFactoryBean" id="javaMap">
<property name="keyFilterPrefix" value="java." />
<property name="input" value="#{T(java.lang.System).getProperties()}" />
</bean>
<!-- use custom properties as input -->
<bean class="spring.test.FilteredMapFactoryBean" id="customMap">
<property name="keyFilterPrefix" value="hello" />
<property name="input">
<props>
<prop key="hello">Is it me you're looking for?</prop>
<prop key="hello.again">Just called to say: hello.</prop>
<prop key="hello.goodby">You say goodbye and I say hello</prop>
<prop key="goodbye.blue.sky">Did-did-did-did-you hear the falling bombs?</prop>
<prop key="goodbye.ruby.tuesday">Who could hang a name on you?</prop>
</props>
</property>
</bean>
</beans>
And here is a test class:
public class Tester{
#SuppressWarnings("unchecked")
public static void main(final String[] args){
final ApplicationContext context =
new ClassPathXmlApplicationContext("classpath:spring/test/mapFactorybean.xml");
final Map<String, String> javaMap =
(Map<String, String>) context.getBean("javaMap");
print("java.", javaMap);
final Map<String, String> customMap =
(Map<String, String>) context.getBean("customMap");
print("hello.", customMap);
}
private static void print(final String prefix, final Map<String, String> map){
System.out.println("Map of items starting with " + prefix);
for(final Entry<String, String> entry : map.entrySet()){
System.out.println("\t" + entry.getKey() + ":" + entry.getValue());
}
System.out.println("");
}
}
The output is as expected:
Map of items starting with java.
java.runtime.name:Java(TM) SE Runtime Environment
java.vm.version:14.2-b01
java.vm.vendor:Sun Microsystems Inc.
java.vendor.url:http://java.sun.com/
java.vm.name:Java HotSpot(TM) Client VM
java.vm.specification.name:Java Virtual Machine Specification
java.runtime.version:1.6.0_16-b01
java.awt.graphicsenv:sun.awt.Win32GraphicsEnvironment
[... etc]
Map of items starting with hello.
hello.goodby:You say goodbye and I say hello
hello:Is it me you're looking for?
hello.again:Just called to say: hello.
I'm afraid you can't, directly. But you can
implement ApplicationContextAware and set the ApplicationContext as a field in your bean.
in a #PostConstruct method call context.getBean("${aaa.props}")
parse the result manually and set it to the desired fields
you can use #Value.
Properties file:
aaa.props={p1:'qwe',p2:'asd',p3:'zxc'}
Java code:
#Value("#{${aaa.props}}")
private Map<String,String> someProps;
You could do something like this:
Maven dependency
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
Add the import.
import javax.annotation.Resource;
...
#Resource (name="propertiesMapName")
public Properties someProps;
In your spring xml application context:
<util:properties id="propertiesMapName" location="classpath:yourFile.properties"/>
You will need this namespace
xmlns:util="http://www.springframework.org/schema/util"
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd
The solution it's well defined on https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config
#ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
}

Resources