javascript
java glassfish_java – Spring,NotReadablePropertyException和Glassfish版本
我正在使用一個使用
Spring MVC的Web應用程序.
它在Glassfish 3.0.1上運行良好,但是當遷移到Glassfish 3.1時,它開始表現得很奇怪.有些頁面只是部分顯示,或者根本沒有顯示任何內容,并且在日志中有很多此類消息:
[#|2012-08-30T11:50:17.582+0200|WARNING|glassfish3.1|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=69;_ThreadName=Thread-1;|StandardWrapperValve[SpringServlet]: PWC1406: Servlet.service() for servlet SpringServlet threw exception
org.springframework.beans.NotReadablePropertyException: Invalid property 'something' of bean class [com.something.Something]: Bean property 'something' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:729)
at org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:576)
at org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:553)
at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:719)
at org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99)
at org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:226)
at org.springframework.web.servlet.support.BindStatus.(BindStatus.java:120)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:178)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:198)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:164)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:127)
at org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:421)
at org.springframework.web.servlet.tags.form.TextareaTag.writeTagContent(TextareaTag.java:95)
at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
錯誤消息不正確,因為有問題的屬性沒有setter-method(通過構造函數獲取其值).但就像我說的那樣,使用Glassfish 3.0.1時這不是問題,只有在使用Glassfish 3.1的新服務器上使用它時才會出現問題.
有誰知道Glassfish版本中是否有可能導致此問題的內容?或者它是新服務器上缺少的某種配置?
一些代碼:
控制器:
@modelattribute
public SomethingContainer retriveSomethingContainer(@PathVariable final long id {
return somethingContainerDao.retrieveSomethingContainer(id);
}
@InitBinder("somethingContainer")
public void initBinderForSomething(final WebDataBinder binder) {
binder.setAllowedFields(new String[] {
"something.title","something.description",});
}
SomethingContainer:
@Embedded
private final Something something = new Something();
public Something getSomething() {
return something;
}
//no setter
public String getDescription() {
return something.getDescription();
}
更新:
重啟Glassfish實際上可以暫時解決問題.我懷疑它可能與自定義綁定器的加載有關,我們遇到了一些內存錯誤的問題,我認為這與它有關,但是已經修復但沒有解決這個問題.
更新2:
在3.0.1服務器上,其中一個jvm參數是-client.在3.1服務器上,它是-server.我們將它更改為-client,這使得錯誤的頻率下降了很多,它每隔一天發生一次-server,花了2周的時間才發生-client.
更新3:
有關服務器的一些信息(如果請求,可以添加更多信息……)
Server1(工作的):
Windows Server 2003
Java jdk 6 build 35
Glassfish 3.0.1 build 22
-xmx 1024m
Server2(有問題的那個):
Windows Server 2008 64-bit
Java jdk 6 build 31
Glassfish 3.1 build 43
-xmx 1088m
-xms 1088m
我們使用的是Spring 3.1.0版.
更新4:
我通過將jsp中的字段重命名為modelattribute中不存在的內容來重新創建錯誤.
但是,更重要的是,我注意到了一些事情:系統無法找到getter的字段通常是modelattribute中引用的字段的超類.繼續我的例子,SomthingContainer真的是這樣的:
public class SuperSomethingContainer {
[...]
private Something something;
public Something getSomething() {
return something;
}
}
public class SomethingContainer extends SuperSomethingContainer {
[...]
}
控制器中的引用保持原樣,因此它引用了相關對象的超類中的字段.
更新5:
發生錯誤后,我嘗試使用調試器連接到生產服務器.我在一個控制器方法的return語句上放了一個斷點,返回帶有錯誤的對象,并試圖查看當時是否可以訪問該字段.我可以,所以問題必須在Spring MVC /生成的jsp-classes中.
(另外,錯誤的字段是“someobject.something [0] .somethingelse [0]”類型,但是當somethingelse-list為空時,沒有錯誤!對我來說,這意味著它某種程度上不能找到列表的get方法(?))
更新6:
似乎問題與從jsps生成Java類有關.我們在部署時沒有使用預編譯jsps,因此在首次使用時會對它們進行編譯.第一次訪問頁面時,會出現問題,并且編譯了jsp.我也注意到,一旦出現問題,之后編譯的jsps都會出錯.我保留了一些問題生成的java文件,在下次重啟時我會將它們與工作文件進行比較.越來越近 :)
更新7:
比較導致錯誤的編譯的jsp java文件與沒有編譯的jsp java文件,并沒有區別.所以有點離開了.
所以,我現在知道離開控制器的Java對象很好(用調試器檢查),并且從jsp生成的java類很好.所以它必須介于兩者之間,現在我需要找出什么……
更新8:
另一輪調試,并將問題縮小了一些.事實證明,spring會對屬于各個類的屬性進行一些緩存.在org.springframework.beans.BeanWrapperImpl中,方法getPropertyValue,有以下內容:
private Object getPropertyValue(PropertyTokenHolder tokens) throws BeansException {
String propertyName = tokens.canonicalName;
String actualName = tokens.actualName;
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
if (pd == null || pd.getReadMethod() == null) {
throw new NotReadablePropertyException(getRootClass(),this.nestedPath + propertyName);
}
問題是cachedIntrospectionResults不包含有問題的屬性,但它包含該類的所有其他屬性.將需要挖掘更多,以試圖找出它丟失的原因,如果它從一開始就丟失,或者它在某個地方丟失了.
另外,我注意到缺少的屬性是那些沒有setter,只有getter的屬性.并且,它似乎是上下文感知,如堆棧跟蹤所示.因此,在訪問一個頁面時找不到屬性并不意味著在訪問另一個頁面時它不可用.
更新9:
另一天,更多的調試.其實找到了一些好東西.前一個代碼塊中的getCachedIntrospectionResults()調用因為調用CachedIntrospectionResults#forClass(theClassInQuestion)而受傷.這返回了一個CachedIntrospectionResults對象,該對象遠遠超出了預期的所有屬性(21個中的11個).進入forClass方法,我發現:
static CachedIntrospectionResults forClass(Class beanClass) throws BeansException {
CachedIntrospectionResults results;
Object value = classCache.get(beanClass);
if (value instanceof Reference) {
Reference ref = (Reference) value;
results = (CachedIntrospectionResults) ref.get();
}
else {
results = (CachedIntrospectionResults) value;
}
if (results == null) {
//build the CachedIntrospectionResults,store it in classCache and return it.
事實證明,返回的CachedIntrospectionResults是由classCache.get(beanClass)找到的.所以存儲在classCache中的內容已損壞/不包含它應該包含的所有內容.我在classCache.get(beanClass)-line上放了一個斷點,并嘗試通過調試器運行它:
classCache.put(beanClass,null);
當允許方法完成并重建CachedIntrospectionResults時,事情又開始起作用了.因此,如果允許重建它,那么存儲在classCache中的內容與將要創建的內容不同步.這是否是由于第一次構建時出現問題,或者如果classCache在我當前不知道的線路上的某個地方被破壞了.
我開始懷疑這與類加載器有關,因為我之前遇到的問題是由于更新Glassfish時類加載器的工作方式發生了變化.
總結
以上是生活随笔為你收集整理的java glassfish_java – Spring,NotReadablePropertyException和Glassfish版本的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DataBinder所有用法-
- 下一篇: 用户画像标签权重计算