<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=fmessner" rel="nofollow">Friedrich Messner</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-9453?redirect=false" rel="nofollow">SPR-9453</a></strong> and commented</p>
<p dir="auto">We're using Spring's BeanWrapper to access a bean via reflection. For one bean's property</p>
<ul dir="auto">
<li>which has a generic type</li>
<li>which is read-only (no setter)</li>
<li>whose getter implements an interface</li>
</ul>
<p dir="auto">we're getting a <code class="notranslate">org.springframework.beans.NotReadablePropertyException</code> since Spring 3.1. I tracked it a little bit and found out that it is related to the <code class="notranslate">ExtendedBeanInfo</code> class introduced with Spring 3.1. The following example demonstrates this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="package org.springframework.beans;

import static org.junit.Assert.assertEquals;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;

import org.junit.Test;

public class BeanInfoTest {

    public interface Interface&lt;T&gt; {
        T getProp();
    }

    public final class Bean implements Interface&lt;Class&lt;?&gt;&gt; {
        private Class&lt;?&gt; prop;
        public Class&lt;?&gt; getProp() { return prop; }
    }

    @Test
    public void testWithPlainBeanInfo() throws IntrospectionException {
        BeanInfo info = Introspector.getBeanInfo(Bean.class);
        assertEquals(2, info.getPropertyDescriptors().length);
    }

    @Test
    public void testWithExtendedBeanInfo() throws IntrospectionException {
        ExtendedBeanInfo extendedInfo = new ExtendedBeanInfo(
                Introspector.getBeanInfo(Bean.class));
        assertEquals(2, extendedInfo.getPropertyDescriptors().length);
    }
}"><pre class="notranslate"><code class="notranslate">package org.springframework.beans;

import static org.junit.Assert.assertEquals;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;

import org.junit.Test;

public class BeanInfoTest {

    public interface Interface&lt;T&gt; {
        T getProp();
    }

    public final class Bean implements Interface&lt;Class&lt;?&gt;&gt; {
        private Class&lt;?&gt; prop;
        public Class&lt;?&gt; getProp() { return prop; }
    }

    @Test
    public void testWithPlainBeanInfo() throws IntrospectionException {
        BeanInfo info = Introspector.getBeanInfo(Bean.class);
        assertEquals(2, info.getPropertyDescriptors().length);
    }

    @Test
    public void testWithExtendedBeanInfo() throws IntrospectionException {
        ExtendedBeanInfo extendedInfo = new ExtendedBeanInfo(
                Introspector.getBeanInfo(Bean.class));
        assertEquals(2, extendedInfo.getPropertyDescriptors().length);
    }
}
</code></pre></div>
<p dir="auto">While the first test passes, the second fails on IBM JVM 1.6.</p>
<p dir="auto">If we do any of</p>
<ul dir="auto">
<li>add a setter</li>
<li>remove the interface</li>
<li>change the type to non-generic (e.g. String)</li>
<li>run it under Sun JVM 1.6</li>
</ul>
<p dir="auto">it works.</p>
<p dir="auto">It seems that ExtendedBeanInfo has a problem with the covariant return types coming from the bridge method for the generic property.</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.1.1</p>
<p dir="auto"><strong>Attachments:</strong></p>
<ul dir="auto">
<li><a href="https://jira.spring.io/secure/attachment/20018/introspect.tgz" rel="nofollow">introspect.tgz</a> (<em>1.74 kB</em>)</li>
</ul>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398152560" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/14336" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/14336/hovercard" href="https://github.com/spring-projects/spring-framework/issues/14336">#14336</a> ExtendedBeanInfo exception - java.beans.IntrospectionException (<em><strong>"is duplicated by"</strong></em>)</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398155112" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/14663" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/14663/hovercard" href="https://github.com/spring-projects/spring-framework/issues/14663">#14663</a> Overhaul non-void JavaBean write method support</li>
</ul>
<p dir="auto"><strong>Referenced from:</strong> commits <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/spring-projects/spring-framework/commit/b50bb5071ac353e77e9d38c72f888de3add923b2/hovercard" href="https://github.com/spring-projects/spring-framework/commit/b50bb5071ac353e77e9d38c72f888de3add923b2"><tt>b50bb50</tt></a>, <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/spring-projects/spring-framework/commit/0ee12563b038797a137ac67b13e5dd6d3d918a7f/hovercard" href="https://github.com/spring-projects/spring-framework/commit/0ee12563b038797a137ac67b13e5dd6d3d918a7f"><tt>0ee1256</tt></a>, <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/spring-projects/spring-framework/commit/30d0bd309cfb707813537751db431a3f56212d2b/hovercard" href="https://github.com/spring-projects/spring-framework/commit/30d0bd309cfb707813537751db431a3f56212d2b"><tt>30d0bd3</tt></a>, <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/spring-projects/spring-framework/commit/4a8be690998f43a9253305e09f96ad83058ef540/hovercard" href="https://github.com/spring-projects/spring-framework/commit/4a8be690998f43a9253305e09f96ad83058ef540"><tt>4a8be69</tt></a></p>
<p dir="auto">1 votes, 5 watchers</p>
<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=casey.butterworth" rel="nofollow">Casey Butterworth</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-5192?redirect=false" rel="nofollow">SPR-5192</a></strong> and commented</p>
<p dir="auto">I have recently started some work on an <code class="notranslate">@LookupMethod</code> annotation to be used in the following situation:</p>
<ul dir="auto">
<li>A prototype scoped bean needs to be used within a singleton</li>
<li>The singleton was created using component scanning</li>
</ul>
<p dir="auto">Currently the most obvious solution would be to forgo component scanning for the singleton and define the lookup-method in the ApplicationContext XML or using spring-java-config, e.g:</p>
<div class="highlight highlight-text-xml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;!-- this could also be created using component scanning --&gt;
&lt;bean id=&quot;myPrototype&quot; class=&quot;sample.MyPrototype&quot; scope=&quot;prototype&quot;/&gt;

&lt;bean id=&quot;mySingleton&quot; class=&quot;sample.MySingleton&quot;&gt;
  &lt;lookup-method name=&quot;createMyPrototype&quot; bean=&quot;myPrototype&quot;/&gt;
&lt;/bean&gt;"><pre class="notranslate"><span class="pl-c"><span class="pl-c">&lt;!--</span> this could also be created using component scanning <span class="pl-c">--&gt;</span></span>
&lt;<span class="pl-ent">bean</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>myPrototype<span class="pl-pds">"</span></span> <span class="pl-e">class</span>=<span class="pl-s"><span class="pl-pds">"</span>sample.MyPrototype<span class="pl-pds">"</span></span> <span class="pl-e">scope</span>=<span class="pl-s"><span class="pl-pds">"</span>prototype<span class="pl-pds">"</span></span>/&gt;

&lt;<span class="pl-ent">bean</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>mySingleton<span class="pl-pds">"</span></span> <span class="pl-e">class</span>=<span class="pl-s"><span class="pl-pds">"</span>sample.MySingleton<span class="pl-pds">"</span></span>&gt;
  &lt;<span class="pl-ent">lookup-method</span> <span class="pl-e">name</span>=<span class="pl-s"><span class="pl-pds">"</span>createMyPrototype<span class="pl-pds">"</span></span> <span class="pl-e">bean</span>=<span class="pl-s"><span class="pl-pds">"</span>myPrototype<span class="pl-pds">"</span></span>/&gt;
&lt;/<span class="pl-ent">bean</span>&gt;</pre></div>
<p dir="auto">However, since I've been using component scanning with 2.5, it doesn't feel right defining the wiring outside of the components, and it would be ideal if we could do something like the following:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@Component
public abstract class MySingleton {
   @LookupMethod(beanRef = &quot;myPrototype&quot;)
   protected abstract MyPrototype createMyPrototype();
}

@Component
public class MyPrototype {}"><pre class="notranslate"><code class="notranslate">@Component
public abstract class MySingleton {
   @LookupMethod(beanRef = "myPrototype")
   protected abstract MyPrototype createMyPrototype();
}

@Component
public class MyPrototype {}
</code></pre></div>
<p dir="auto">It would be even better if <code class="notranslate">@LookupMethod</code> could work in conjunction with autowiring (by type), but that can be a subsequent feature request.</p>
<p dir="auto">I've started to implement a solution and will attach shortly.</p>
<hr>
<p dir="auto"><strong>Attachments:</strong></p>
<ul dir="auto">
<li><a href="https://jira.spring.io/secure/attachment/14732/LookupMethod.java" rel="nofollow">LookupMethod.java</a> (<em>348 bytes</em>)</li>
<li><a href="https://jira.spring.io/secure/attachment/14730/LookupMethod.java" rel="nofollow">LookupMethod.java</a> (<em>394 bytes</em>)</li>
<li><a href="https://jira.spring.io/secure/attachment/15723/lookup-method.zip" rel="nofollow">lookup-method.zip</a> (<em>10.43 kB</em>)</li>
<li><a href="https://jira.spring.io/secure/attachment/14731/LookupMethodAnnotationBeanPostProcessor.java" rel="nofollow">LookupMethodAnnotationBeanPostProcessor.java</a> (<em>2.14 kB</em>)</li>
</ul>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398106594" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/12089" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/12089/hovercard" href="https://github.com/spring-projects/spring-framework/issues/12089">#12089</a> Passing lookup-method arguments to created bean constructor</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398163913" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/15860" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/15860/hovercard" href="https://github.com/spring-projects/spring-framework/issues/15860">#15860</a> BeanFactory lacks method for getting bean by type with specified constructor arguments</li>
</ul>
<p dir="auto"><strong>Referenced from:</strong> commits <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/spring-projects/spring-framework/commit/eb0ab8431bc967aff0f186a4b0bc4562e073fd01/hovercard" href="https://github.com/spring-projects/spring-framework/commit/eb0ab8431bc967aff0f186a4b0bc4562e073fd01"><tt>eb0ab84</tt></a></p>
<p dir="auto">37 votes, 33 watchers</p>