Announcement Announcement Module
Collapse
No announcement yet.
Binding Generics fails after a few minutes run-time. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Binding Generics fails after a few minutes run-time.

    Hello,

    we have a problem with Spring binding in our MVC set up. This is what we have:

    Spring 2.0.4
    Hibernate 3.2
    Freemarker 2.3.10

    Usually we have no problems with spring binding whatsoever. This is the first time we ran in some problems with the binding.
    Our command object has, besides some other stuff, a list of this:

    public abstract class AbstractAttributAuspraegung<T> implements IBo

    which can be one of these:

    public class DoubleAttributAuspraegung extends AbstractAttributAuspraegung<Double> implements IBo {
    or
    public class TextAttributAuspraegung extends AbstractAttributAuspraegung<String> implements IBo {
    or
    public class BooleanAttributAuspraegung extends AbstractAttributAuspraegung<Boolean> implements IBo {

    They all got a variable called „wert“. And that’s the according binding for it:
    path=“ziel.attributAuspraegungen[3].wert“

    The binding works quite well, but only for about 5 Minutes run time. After that spring somehow forgets what to do with the generic classes and tries to
    If it wouldn’t work at all, I could understand it. But it works for some time and then it stops working and the behavior of spring changes.

    Can anyone enlighten me with this?
    Any help is greatly appreciated.

    cheers bind „object“ instead of the correct type (which is one of string, double or boolean). We get a cast exception and that’s it.

    Santo.

  • #2
    Please post some code, when doing so please use [ code][/code ] tags. Also probably there is something in your logging which gives more of a description please also post that.

    Comment


    • #3
      Hi

      I think I am in similar situation here. Here is my code -

      Code:
      abstract class  A<T> {
          public abstract T getValue();
          public abstract void setValue(T value);
      }
      
      public class B extends A<Integer> {
      
          private Integer value;
      
          public Integer getValue() {
              return value;
          }
      
          public void setValue(Integer value) {
              this.value = value;
          }
      }
      Now when I bind the 'value' and submit my form, I get java.lang.ClassCastException in my log file.

      Code:
      Failed to convert property value of type [java.lang.String] to required type [java.lang.Object] for property 'value'; nested exception is java.lang.ClassCastException: java.lang.String]]
      It seems like for some reason my Integer type property is being seen as Object type, maybe because of the Generics?

      Please let us know what to do.
      Thanks in advance.

      Comment


      • #4
        Some investigation

        Hi!

        I'm a colleague of the original poster. We have made some tests resulting in the following:
        (I use iqbal's example as it is more comprehensive.)

        Before the binding failure, BeanUtils.getPropertyDescriptor(B.class, "value") correctly returns java.lang.Integer.
        After the binding failure, the same call returns java.lang.Object.
        Curiously, this call seemed to prolong the time until failure (in Jetty 6).

        B.class.getMethod("getValue", null).getReturnType() correctly returns java.lang.Integer all the time.
        So does B.class.getDeclaredField("value").getType().

        I have a feeling that this has something to do with Spring caching bean information. But that's just me.

        I'd be grateful for any hints leading to to a solution or workaround that does not include "drop generics".

        Cheers,
        Chris

        Comment


        • #5
          If you have a small, reproducible example then I suggest posting it to Jira if no according issue already exists.

          Regards,
          Andreas

          Comment


          • #6
            Workaround

            Unfortunately, I have not been able to create a small reproducable example.

            I have however found a workaround I can live with:

            Instead of using "A.value" as path in Freemarker, I use just "A".

            In my controller I add
            Code:
            @Override
            protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
            	binder.registerCustomEditor(A.class, new AEditor());
            	super.initBinder(request, binder);
            }
            The registered editor looks like this:
            Code:
            public class AEditor extends PropertyEditorSupport {
            	
            	@Override
            	public String getAsText() {
            		Object obj = this.getValue();
            		if (obj instanceof B) {
            			// handle object of class B
            			// i.e. delegate to a specific editor
            		}
            		// repeat for other subclasses of A
            	}
            	
            	@Override
            	public void setAsText(String text) throws IllegalArgumentException {
            		// analogous to getAsText()
            	}
            	
            }
            Not exactly elegant, I know. But it works for me.

            Cheers,
            Chris

            Comment

            Working...
            X