title: How to resolve Spring @Value annotations in a web servlet?
body: <p>I have a servlet packaged in an ear file, and I cannot get it to resolve @Value annotated properties.</p>
  
  <p>The app is in two parts: a servlet packaged in a war file, which is then included by different applications packaged in an ear file. The application supplies the implementation of a class (ResourceManager) defined by an interface in the servlet, and also the property file containing the value of the property for the @Value annotated field.</p>
  
  <p>The war file contains:</p>
  
  <p>web.xml:</p>
  
  <pre><code>&lt;servlet&gt;
    &lt;servlet-class&gt;... extends MessageDispatcherServlet&lt;/servlet-class&gt;
    &lt;init-param&gt;
      &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
      &lt;param-value&gt;
        classpath:/spring-ws.xml
        classpath:/spring-app.xml
      &lt;/param-value&gt;
    &lt;/init-param&gt;
  &lt;/servlet&gt;
  </code></pre>
  
  <p>spring-ws.xml:</p>
  
  <pre><code>&lt;context:annotation-config/&gt;
  &lt;context:property-placeholder location="classpath:/spring-ws.properties"/&gt;
  </code></pre>
  
  <p>The values in spring-ws.properties are referenced directly from spring-ws.xml, and all work fine.</p>
  
  <p>The servlet class contains:  </p>
  
  <pre><code>public class MyServlet extends MessageDispatcherServlet
  
    @Autowired private ResourceManager resourceManager;  // original annotation - got this to work
    @Value("${app.name:}") private String appName;       // added later - cannot get this to work
  </code></pre>
  
  <p>The app.name is optional, hence the trailing ":".</p>
  
  <p>The ear file adds (packaged in a jar file in the ear lib directory):</p>
  
  <p>spring-app.xml:</p>
  
  <pre><code>  &lt;context:property-placeholder location="classpath:/spring-app.properties"/&gt;
  
    &lt;bean class="ResourceManagerImpl"&gt; 
      ...
    &lt;/bean&gt;
  </code></pre>
  
  <p>spring-app.properties:</p>
  
  <pre><code>app.name=myApp
  </code></pre>
  
  <p>My first problem was with the @Autowired annotation: not sure I ever got to the bottom of that correctly, but I managed to get it to work by adding this code to the servlet:  </p>
  
  <pre><code>@Override
  protected void initFrameworkServlet() throws ServletException {
  
    AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
    bpp.setBeanFactory(getWebApplicationContext().getAutowireCapableBeanFactory());
    bpp.processInjection(this);
  }
  </code></pre>
  
  <p>This may not be the best way to fix this, but it was the first I found and it worked, so I used it and moved on. Then I added a @Value annotated field, and I can't find a way to make this work. The javadocs for <a href="http://docs.spring.io/spring/docs/3.2.4.RELEASE/javadoc-api/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.html" rel="nofollow noreferrer">AutowiredAnnotationBeanPostProcessor</a> say that it should process @Value annotations as well, but it doesn't appear to: the appName property is always blank (presumably from the default).</p>
  
  <p>I do have a workaround, using beans:</p>
  
  <pre><code>@Autowired @Qualifier("appName") private String appName;
  
  &lt;bean id="appName" class="java.lang.String"&gt;
    &lt;constructor-arg value="myApp"/&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>But I'm sure there must be a better way of doing this. I've read this post <a href="https://stackoverflow.com/questions/3652090/difference-between-applicationcontext-xml-and-spring-servlet-xml-in-spring">Difference between applicationContext.xml and spring-servlet.xml in Spring Framework</a>, but I'm not sure it applies: I don't think I even have an application context here, just a servlet context defined in the web.xml for the (single) servlet class.</p>
  
  <p>I've also seen this: <a href="https://stackoverflow.com/questions/5275724/spring-3-0-5-doesnt-evaluate-value-annotation-from-properties">Spring 3.0.5 doesn&#39;t evaluate @Value annotation from properties</a>, which looks like the same problem, but the solution there appeared to be to move the "&lt;context:property-placeholder&gt;" from the application context to the servlet context, whereas as I said before, I don't think I even have an application context here...</p>
  
  <p>Finally, I've had a quick go at simplifying the problem, removing the separate app and packaging everything in a single war, but I don't think that is the problem (although could obviously be wrong...): spring can resolve the class path for the app.xml file so it must be able to resolve the class path for the app.properties file.</p>
  
  <p>Any help much appreciated, but I guess at this point it is a bit of an academic interest, as I have a workable solution (using beans) and the people that pay the bills don't really care how it works as long as it works! I'd just like to know so next time I don't have to copy (what I think is) a flawed workaround.</p>
  
  <p>Using spring-ws-core 2.1.4, which pulls in spring 3.2.4 via maven dependencies.</p>
  
  <p>Thanks</p>
  
  <p><strong>Update - Solved</strong></p>
  
  <p>Turns out the key to fixing this was M Deinum's comment that "You also have a duplicate element...". I had two separate PropertyPlaceholderConfigurers in the same context, so the second was ignored and its properties never used. There was no problem with the context itself (which is a servlet context not a root context), or the annotation processing.</p>
  
  <p>So the fix was simply to remove the property placeholder from the spring-app.xml, and combine both property files in the spring-ws.xml</p>
  
  <pre><code>&lt;context:property-placeholder
      location="classpath:/spring-ws.properties,
                classpath:/spring-app.properties"/&gt;
  </code></pre>
  
  <p>TL;DR's answer here <a href="https://stackoverflow.com/questions/15818047/spring-namespace-vs-contextconfiglocation-init-parameters-in-web-xml">Spring: namespace vs contextConfigLocation init parameters in web.xml</a> is also an awesome explanation of how the different contexts are processed!</p>
  
  <p>Cheers,</p>