为 Play 构建 WAR 时 .class 位置出错!框架应用
我正在开发 1.2 Play!框架应用程序,在 Tomcat 6 上将其部署为 WAR 时遇到问题。
我的应用程序的一页显示信息列表。 这些信息是从 .yml
文件中检索的。 因此,我有一个控制器,可以从 .yml
文件生成 Iterable
public static void myFunction() {
Constructor constructor = new Constructor(MyClass.class); // org.yaml.snakeyaml.constructor.Constructor
constructor.addTypeDescription(new TypeDescription(MyClass.class));
Yaml yaml = new Yaml(constructor);
Iterable<Object> listOfInfo = yaml.loadAll(Application.class.getResourceAsStream("/my-file.yml"));
render("Application/my-page.html", listOfInfo);
}
重要的一点是 MyClass
位于在 app/my/company/my-app/
包 (my.company.my-app.MyClass
) 中。
当我使用 play run
运行我的应用程序时,没有问题。
现在,我构建 WAR 包(使用 play war -o some/dir --zip),并将生成的 WAR 安装在 Tomcat (6.0) 上。 服务器启动后,尝试访问相应的页面,我收到以下错误:
@683lh76fn
Internal Server Error (500)
Template execution error (In /app/views/Application/my-page.html around line 9)
Execution error occured in template /app/views/Application/my-page.html. Exception raised was ConstructorException : null; Can't construct a java object f
or tag:yaml.org,2002:my.company.my-app.MyClass; exception=Class not found: my.company.my-app.MyClass.
play.exceptions.TemplateExecutionException: null; Can't construct a java object for tag:yaml.org,2002:my.company.my-app.MyClass; exception
=Class not found: my.company.my-app.MyClass
at play.templates.BaseTemplate.throwException(BaseTemplate.java:84)
at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:252)
at play.templates.Template.render(Template.java:26)
at play.templates.GroovyTemplate.render(GroovyTemplate.java:184)
at play.mvc.results.RenderTemplate.<init>(RenderTemplate.java:24)
at play.mvc.Controller.renderTemplate(Controller.java:659)
at play.mvc.Controller.renderTemplate(Controller.java:639)
at play.mvc.Controller.render(Controller.java:694)
at controllers.Application.myFunction(Application.java:311)
如果我查看爆炸战争,我会看到 my.company.my-app.MyClass
是位于目录WEB-INF/application/precompiled/java/my/company/my-app/
目录中。
如果我将此目录移动到 WEB-INF/classes 中,那么我就不会再收到此错误。
为什么会出现这个错误?我可以选择哪些选项来使其工作(无需手动修改 WAR)?
I'm working on a 1.2 Play! framework application, and I have a problem when deploying it as a WAR on a Tomcat 6.
One page of my application displays a list of information.
These information are retrieved from a .yml
file.
So I have a controller that generate a Iterable<Object>
from this .yml
file, like that:
public static void myFunction() {
Constructor constructor = new Constructor(MyClass.class); // org.yaml.snakeyaml.constructor.Constructor
constructor.addTypeDescription(new TypeDescription(MyClass.class));
Yaml yaml = new Yaml(constructor);
Iterable<Object> listOfInfo = yaml.loadAll(Application.class.getResourceAsStream("/my-file.yml"));
render("Application/my-page.html", listOfInfo);
}
The important point is that MyClass
is located in the app/my/company/my-app/
package (my.company.my-app.MyClass
).
When I run my application using play run
, there is no problem.
Now, I build the WAR package (using play war -o some/dir --zip
), and I install this generated WAR on a Tomcat (6.0).
Once the server is started, and try to access the corresponding page, I get the following error:
@683lh76fn
Internal Server Error (500)
Template execution error (In /app/views/Application/my-page.html around line 9)
Execution error occured in template /app/views/Application/my-page.html. Exception raised was ConstructorException : null; Can't construct a java object f
or tag:yaml.org,2002:my.company.my-app.MyClass; exception=Class not found: my.company.my-app.MyClass.
play.exceptions.TemplateExecutionException: null; Can't construct a java object for tag:yaml.org,2002:my.company.my-app.MyClass; exception
=Class not found: my.company.my-app.MyClass
at play.templates.BaseTemplate.throwException(BaseTemplate.java:84)
at play.templates.GroovyTemplate.internalRender(GroovyTemplate.java:252)
at play.templates.Template.render(Template.java:26)
at play.templates.GroovyTemplate.render(GroovyTemplate.java:184)
at play.mvc.results.RenderTemplate.<init>(RenderTemplate.java:24)
at play.mvc.Controller.renderTemplate(Controller.java:659)
at play.mvc.Controller.renderTemplate(Controller.java:639)
at play.mvc.Controller.render(Controller.java:694)
at controllers.Application.myFunction(Application.java:311)
If I have a look in the exploded war, I see that my.company.my-app.MyClass
is located in the directory WEB-INF/application/precompiled/java/my/company/my-app/
directory.
If I move this directory into WEB-INF/classes
, then I don't get this error anymore.
Why does this error occurs? What are my options to make it work (without modifying manually the WAR)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
默认情况下,Tomcat 仅查看 /WEB-INF/classes 和 /WEB-INF/lib(对于每个 war 文件)中的文件,因为它们包含在类路径中。您可以做很多事情。
视窗)。
就我个人而言,我会修复/修改构建 war 文件的方式,并确保将类复制到 WEB-INF/classes 而不是 WEB-INF/application 文件夹。
By the default, Tomcat only looks at files in /WEB-INF/classes and /WEB-INF/lib (for each war file) as they are included in the classpath. There are a number of things you could do..
Windows).
Personally i would fix/modify how i build the war file and make sure that the classes are copied to WEB-INF/classes instead of WEB-INF/application folder.
我终于找到了这个问题的答案!
Yaml 解析器 (snakeyaml) 创建自己的类加载器以解析
.yml
文件。游戏的结构! Framework使用自己的ClassLoader,编译后的类位于WEB-INF/application/precompiled/java目录下,这不是WAR标准。因此,Yaml 无法检索类,特别是
MyClass.class
。解决此问题的解决方案(除了使用 Ant 修改 WAR 之外)是 发挥吧! Yaml 解析器的类加载器。我不写:
我写:
使用这个,我可以使用 Play 创建的 WAR!直接不再出现 Yaml 错误!
I finally found the answer of this problem!
The Yaml parser (snakeyaml) creates its own ClassLoader in order to parse a
.yml
file. The structure of the Play! framework uses its own ClassLoader, and the compiled classes are located in theWEB-INF/application/precompiled/java
directory, which is not the WAR standard.Due to that, Yaml was not able to retrieve the classes, in particular
MyClass.class
.The solution to solve this issue (except by modifying the WAR using Ant for example), is to give the Play! ClassLoader to the Yaml parser. Instead of writing that:
I write:
using this, I can use the WAR created by Play! directly without getting the Yaml error anymore!