2013-07-24 139 views
2

我有一些在本地工作得很好的代碼,但是當我嘗試在遠程服務器上運行它時,它會拋出一個空指針異常。它在嘗試從Velocity獲取模板時會這樣做。它第一次失敗,每次都失敗。Velocity在獲取模板時拋出NPE

有問題的代碼是該位:

URL location = Thread.currentThread().getContextClassLoader().getResource("velocity.properties"); 
    String fullPath = location.getPath(); 
    log.debug("Path: " + fullPath); 
    Velocity.init(fullPath); 
    Template tmplt = Velocity.getTemplate("template.html"); //This line throws the error 

記錄顯示的路徑是正確的,我可以驗證該文件是存在的。

用來初始化速度的屬性文件包含:

resource.loader = file 
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader 
file.resource.loader.path=/var/lib/tomcat6/webapps/geoip/WEB-INF/templates/template.html 
file.resource.loader.cache = true 

input.encoding=UTF-8 
output.encoding=UTF-8 

該錯誤的堆棧跟蹤看起來是這樣的:

SEVERE: Servlet.service() for servlet Jersey REST Service threw exception 
java.lang.NullPointerException 
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533) 
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1514) 
at org.apache.velocity.runtime.RuntimeSingleton.getTemplate(RuntimeSingleton.java:299) 
at org.apache.velocity.app.Velocity.getTemplate(Velocity.java:358) 
at ca.company.ipservice.models.MyClass.toHTML(MyClass.java:48) 

我周圍的一派,搜索的StackOverflow,但我不能找到任何答案。有任何想法嗎?

+0

嘗試下面的鏈接 http://stackoverflow.com/questions/2931516/loading-velocity-template-inside-a-jar-file – sunshine

+1

順便說一句,我有一個類似的錯誤消息曾經在多線程環境中使用速度和調用的init()多次時,數百處決的只有一次出現了,不過,好像雖然RuntimeInstance.init()同步是一個罕見的競爭條件,所以不知道怎麼會發生... – centic

回答

5

屬性file.resource.loader.path應該指向一個目錄。嘗試將其設置爲目錄/var/lib/tomcat6/webapps/geoip/WEB-INF/templates

file.resource.loader.path=/var/lib/tomcat6/webapps/geoip/WEB-INF/templates 

,而不是

file.resource.loader.path=/var/lib/tomcat6/webapps/geoip/WEB-INF/templates/template.html 

而且你似乎有一個Web應用程序。在這種情況下,最好是初始化它

VelocityEngine velocityEngine = new VelocityEngine(); 
velocityEngine.setApplicationAttribute("javax.servlet.ServletContext", context); 

其中contextServletContext之前從velocity tools

resource.loader = webapp 
webapp.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader 
webapp.resource.loader.path = templates 
webapp.resource.loader.cache = false 

使用WebappResourceLoader並設置servlet上下文屬性。目錄templates應位於您的網站根目錄中,因此位於WEB-INF的相同位置。

編輯

如果您將應用程序打包成一個war文件,並將其部署到讓你有文件系統的直接訪問,那麼你可以考慮使用ClasspathResourceLoader不打開包裝的應用服務器。爲此,您必須將模板打包到自己的jar文件中,並將其放入WEb-INF/libgetTemplate(...)的參數必須遵循檢索位於類路徑中的資源的規則(請參閱ClassLoader#getResourceAsStream)。

resource.loader = classpath 
classpath.resource.loader.description = Velocity Classpath Resource Loader 
classpath.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader 
classpath.resource.loader.cache = false 

Here你可以找到關於如何加載模板的詳細信息。

+0

我嘗試了所有的你的建議,他們跑就好了本地。可悲的是,他們仍然不能在服務器上工作。感謝您的優秀建議! – kidl33t

+0

@ kidl33t看到我的編輯,我希望它有幫助。祝你好運! – A4L

+1

感謝您的幫助!除了將此行添加到我的velocity.properties文件之外,使用您的建議可以在所有環境中正常工作!你改變了我過去的初始誤差的第二速度記錄的錯誤,這是通過添加這性能解決:「runtime.log.logsystem.class = org.apache.velocity.runtime.log.NullLogSystem」。非常感謝您的幫助,我非常感謝。它讓我擺脫束縛! – kidl33t

1

我認爲這個代碼[1]應該更健壯。當配置日誌記錄時出現任何錯誤時,速度引擎將以怪異狀態結束,其中initialized = false和initializing = true表示應用程序的整個生命週期。我也不確定爲什麼Logging首先比資源管理器初始化。我正在考慮爲該項目打開一個錯誤。

[1] http://grepcode.com/file/repository.springsource.com/org.apache.velocity/com.springsource.org.apache.velocity/1.6.2/org/apache/velocity/runtime/RuntimeInstance.java#RuntimeInstance.init%28%29