2015-06-05 6 views
7

У меня простая проблема. У меня есть программа, работающая в Java JDK7, но она не работает в JDK8 из-за некоторых изменений самоанализа.Java JDK 8 IndexedPropertyDescriptor изменился с JDK 7 с объектом List

Вот тестовая программа для воспроизведения проблемы:

import java.beans.BeanInfo; 
import java.beans.IntrospectionException; 
import java.beans.Introspector; 
import java.beans.PropertyDescriptor; 
import java.util.ArrayList; 
import java.util.List; 

public class Main { 

    public static void main(String[] args) throws IntrospectionException { 
     BeanInfo info = Introspector.getBeanInfo(MyListClass.class); 
     PropertyDescriptor[] descriptors = info.getPropertyDescriptors(); 
     for (int i = 0; i < descriptors.length; i++) { 
      System.out.println(descriptors[i].getClass().getName() + ":" + descriptors[i].getName()); 
     } 

     System.out.println("\n"); 

     BeanInfo info2 = Introspector.getBeanInfo(MyIndexedListClass.class); 
     PropertyDescriptor[] descriptors2 = info2.getPropertyDescriptors(); 
     for (int i = 0; i < descriptors2.length; i++) { 
      System.out.println(descriptors2[i].getClass().getName() + ":" + descriptors2[i].getName()); 
     } 

     System.out.println("\n"); 

     BeanInfo info3 = Introspector.getBeanInfo(MyArrayClass.class); 
     PropertyDescriptor[] descriptors3 = info3.getPropertyDescriptors(); 
     for (int i = 0; i < descriptors3.length; i++) { 
      System.out.println(descriptors3[i].getClass().getName() + ":" + descriptors3[i].getName()); 
     } 

     System.out.println("\n"); 

     BeanInfo info4 = Introspector.getBeanInfo(MyIndexedArrayClass.class); 
     PropertyDescriptor[] descriptors4 = info4.getPropertyDescriptors(); 
     for (int i = 0; i < descriptors4.length; i++) { 
      System.out.println(descriptors4[i].getClass().getName() + ":" + descriptors4[i].getName()); 
     } 

    } 

    public class MyListClass { 
     private List<String> myListClass = new ArrayList<String>(); 

     public List<String> getMyListClass() { 
      return myListClass; 
     } 

     public void setMyListClass(List<String> myListClass) { 
      this.myListClass = myListClass; 
     } 

    } 

    public class MyIndexedListClass { 
     private List<String> myIndexedListClass = new ArrayList<String>(); 

     public String getMyIndexedListClass(int index) { 
      return myIndexedListClass.get(index); 
     } 

     public void setMyIndexedListClass(int index, String element) { 
      this.myIndexedListClass.set(index, element); 
     } 

     public List<String> getMyIndexedListClass() { 
      return myIndexedListClass; 
     } 

     public void setMyIndexedListClass(List<String> myIndexedListClass) { 
      this.myIndexedListClass = myIndexedListClass; 
     } 

    } 

    public class MyArrayClass { 
     private String[] myArrayClass = new String[20]; 

     public String[] getMyArrayClass() { 
      return myArrayClass; 
     } 

     public void setMyArrayClass(String[] myArrayClass) { 
      this.myArrayClass = myArrayClass; 
     } 

    } 

    public class MyIndexedArrayClass { 
     private String[] myIndexedArrayClass = new String[20]; 

     public String getMyIndexedArrayClass(int index) { 
      return myIndexedArrayClass[index]; 
     } 

     public void setMyIndexedArrayClass(int index, String myValue) { 
      this.myIndexedArrayClass[index] = myValue; 
     } 

     public String[] getMyIndexedArrayClass() { 
      return myIndexedArrayClass; 
     } 

     public void setMyIndexedArrayClass(String[] myIndexedArrayClass) { 
      this.myIndexedArrayClass = myIndexedArrayClass; 
     } 

    } 
} 

здесь являются JDK 7 пиловочник:

java.beans.PropertyDescriptor:class 
java.beans.PropertyDescriptor:myListClass 

java.beans.PropertyDescriptor:class 
java.beans.IndexedPropertyDescriptor:myIndexedListClass 

java.beans.PropertyDescriptor:class 
java.beans.PropertyDescriptor:myArrayClass 

java.beans.PropertyDescriptor:class 
java.beans.IndexedPropertyDescriptor:myIndexedArrayClass 

Вот журналы для JDK8:

java.beans.PropertyDescriptor:class 
java.beans.PropertyDescriptor:myListClass 

java.beans.PropertyDescriptor:class 
java.beans.PropertyDescriptor:myIndexedListClass -> Here is the change 

java.beans.PropertyDescriptor:class 
java.beans.PropertyDescriptor:myArrayClass 

java.beans.PropertyDescriptor:class 
java.beans.IndexedPropertyDescriptor:myIndexedArrayClass 

I должны использовать JDK8 очень скоро, но это блокировка, потому что мое приложение больше не работает. У меня есть эта проблема со всеми классами, которые расширяют интерфейс Collection (список, карта, ...)

Код используется библиотекой commons-beanutils-1.8.0 от Apache Commons.

Я ищу решение, обходное решение, чтобы мое приложение работало так же, как и раньше, при использовании JDK7, есть ли какое-либо решение? Я не могу использовать массив вместо списка (потому что массив не изменился)

Вот ссылки на официальную документацию:

JDK7: http://docs.oracle.com/javase/7/docs/api/java/beans/IndexedPropertyDescriptor.html

JDK8: http://docs.oracle.com/javase/8/docs/api/java/beans/IndexedPropertyDescriptor.html


EDIT: Я нашел свое решение, моя проблема была связана со стойками 1.3. Я должен был переименовать мой индексированный геттер/сеттер в моей ActionForm: http://www.coderanch.com/t/55172/Struts/Indexed-Properties

+0

Я не вижу разницы в ваших примерах. в чем именно проблема?: –

+1

В JDK 7 метод getPropertyDescritor of BeanInfo возвращает «IndexedPropertyDescriptor» для класса MyIndexedListClass, а в JDK 8 возвращает «PropertyDescriptor». –

ответ

5

Ну, спецификация ясно говорит о том, что IndexedPropertyDescriptor может иметь методы, основанные дополнительный массив аксессоры, больше ничего. Это не изменилось. Здесь у вас есть конфликтующие методы собственности, определяющие простое заданное свойство List<String> и и проиндексированное свойство String с таким же именем. Методы, основанные на методе , никогда не были связаны с индексированным свойством.

Так что изменилось, какая из конфликтующих свойств превращает его в BeanInfo и которая будет удалена. Такое поведение может зависеть от неуказанного порядка HashMap или подобного. Могут быть и другие факторы. Таким образом, не рассматривайте его как проблему с Java 7 и Java 8, а просто зависимое от реализации поведение, которое также может изменяться между альтернативными реализациями Java 7.

Существует два способа решения этой проблемы. Вы можете разрешить конфликт путем переименования одного из свойств:

public class MyIndexedListClass { 
    private List<String> myIndexedListClass = new ArrayList<String>(); 

    public String getMyIndexedListClass(int index) { 
     return myIndexedListClass.get(index); 
    } 

    public void setMyIndexedListClass(int index, String element) { 
     this.myIndexedListClass.set(index, element); 
    } 

    public List<String> getMyIndexedListClassAsList() { 
     return myIndexedListClass; 
    } 

    public void setMyIndexedListClassAsList(List<String> myIndexedListClass) { 
     this.myIndexedListClass = myIndexedListClass; 
    } 
} 

Затем все версии Java будет вести себя так же, но имеет побочный эффект теперь видим два различных свойства по-разному именованные свойства.


Альтернатива держать методы как, но явно игнорировать методы, основанные List от признания дескриптора свойства.Другими словами, сделайте поведение, которое произошло в одной реализации и, кажется, ваше желаемое, явное.

public class MyIndexedListClass { 
    private List<String> myIndexedListClass = new ArrayList<String>(); 

    public String getMyIndexedListClass(int index) { 
     return myIndexedListClass.get(index); 
    } 
    public void setMyIndexedListClass(int index, String element) { 
     this.myIndexedListClass.set(index, element); 
    } 
    public List<String> getMyIndexedListClass() { 
     return myIndexedListClass; 
    } 
    public void setMyIndexedListClass(List<String> myIndexedListClass) { 
     this.myIndexedListClass = myIndexedListClass; 
    } 
} 
static // in your example all classes are inner classes 
public class MyIndexedListClassBeanInfo extends SimpleBeanInfo { 
    private PropertyDescriptor[] properties; 

    public MyIndexedListClassBeanInfo() throws IntrospectionException { 
    PropertyDescriptor[] p=Introspector.getBeanInfo(MyIndexedListClass.class, 
     Introspector.IGNORE_IMMEDIATE_BEANINFO).getPropertyDescriptors(); 
    ArrayList<PropertyDescriptor> list=new ArrayList<>(p.length+1); 
    for(PropertyDescriptor d: p) 
     if(!d.getName().equals("myIndexedListClass")) list.add(d); 
    list.add(new IndexedPropertyDescriptor("myIndexedListClass", 
     MyIndexedListClass.class, null, null, 
     "getMyIndexedListClass", "setMyIndexedListClass")); 
    properties=list.toArray(new PropertyDescriptor[list.size()]); 
    } 

    @Override 
    public PropertyDescriptor[] getPropertyDescriptors() { 
     return properties; 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^