如何为 J2SE 1.4 API 添加对 IBM437 字符集的支持

3

我需要对一个使用J2SE 1.4的旧项目进行更改。现在当我运行该项目时,会出现错误:

javax.servlet.ServletException: 字符集 'IBM437' 支持 JSE 1.1 API,但不支持 J2SE 1.4 API。这需要修复 Java 运行环境!请阅读此错误类的 Javadoc 获取更多信息。 at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:498) at org.apache.jsp.download_orders_action_jsp._jspService(download_orders_action_jsp.java:131) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:92) at javax.servlet.http.HttpServlet.service(HttpServlet.java:720) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:162) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:240) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:187) at javax.servlet.http.HttpServlet.service(HttpServlet.java:720) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:199) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:145) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:596) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:433) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:955) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:139) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:596) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:433) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:955) at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2460) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:133) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:596) at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:119) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:594) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:116) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:594) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:433) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:955) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:127) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:596) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:433) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:955) at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:157) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:873) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689) at java.lang.Thread.run(Thread.java:534)
这是一个zip文件创建器使用的功能。我的问题是如何将其添加到J2SE 1.4中。通过谷歌搜索,我找到了这个页面,但我不知道该怎么做。非常感谢任何形式的帮助。

以下是在jsp中调用并且我认为真正的问题出现在这里的制作zip文件的代码:

String zipFilename = currentDumpDirName + ".zip";
de.schlichtherle.io.File srcDir = new de.schlichtherle.io.File(currentDumpRootDir);
de.schlichtherle.io.File zipFile = new de.schlichtherle.io.File(dumpRootDir, zipFilename);
boolean zippedSuccessfully = srcDir.copyAllTo(zipFile);
zipFile.umount();

从异常的根本原因可以看出

de.schlichtherle.io.archive.spi.AbstractArchiveDriver$InconsistentCharsetSupportError: 字符集 'IBM437' 在JSE 1.1 API中被支持,但在J2SE 1.4 API中不被支持。 这需要修复Java运行环境! 请阅读此错误类的Javadoc以获取更多信息。 at de.schlichtherle.io.archive.spi.AbstractArchiveDriver.(AbstractArchiveDriver.java:92) at de.schlichtherle.io.archive.zip.Zip32Driver.(Zip32Driver.java:136) at de.schlichtherle.io.archive.zip.Zip32Driver.(Zip32Driver.java:71) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:274) at java.lang.Class.newInstance0(Class.java:308) at java.lang.Class.newInstance(Class.java:261) at de.schlichtherle.io.ArchiveDriverRegistry.createArchiveDriver(ArchiveDriverRegistry.java:267) at de.schlichtherle.io.ArchiveDriverRegistry.getArchiveDriver(ArchiveDriverRegistry.java:240) at de.schlichtherle.io.DefaultArchiveDetector.getArchiveDriver(DefaultArchiveDetector.java:324) at de.schlichtherle.io.File.init(File.java:892) at de.schlichtherle.io.File.init(File.java:810) at de.schlichtherle.io.File.(File.java:556) at de.schlichtherle.io.File.(File.java:522) at uk.co.planetbeyond.photoprintingserver.OrdersPackagingService.packageOrders(OrdersPackagingService.java:43) at org.apache.jsp.download_orders_action_jsp._jspService(download_orders_action_jsp.java:118) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:92) at javax.servlet.http.HttpServlet.service(HttpServlet.java:720) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:162) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:240) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:187) at javax.servlet.http.HttpServlet.service(HttpServlet.java:720) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:199) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:145) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:596) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:433) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:955) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:139) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:596) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:433) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:955) at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2460) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:133) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:596) at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:119) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:594) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:116) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:594) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:433) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:955) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:127) at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:596) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:433) at org.apache.catalina.core
1个回答

4
您似乎将IBM437作为字符集的规范名称或别名,根据您链接的同一页,该名称或别名未列为有效名称或别名。相反,列出了IBM-437,这似乎是正确的名称,您应该指定它。我在问题中没有看到使用String字面值IBM437的任何代码,并且根据堆栈跟踪,我怀疑您在JSP中(编译为使用Jasper引擎的Servlet)的pageEncoding属性或contentType属性中指定了它。因此,您应该在JSP中将IBM437替换为IBM-437,并重新编译相同的内容。
此外,您没有指定项目是否必须使用IBM-437字符集。我怀疑IBM-437字符集正在使用,因为一个或多个系统属性(例如file.encoding)被设置为IBM-437。如果您不打算使用IBM-437,则应开始考虑在整个代码中使用规范名称或别名,如UTF-8,以便您的应用程序对于处理的输入数据或输出响应的字符集没有任何错误的假设。

更新的回答

根据新的堆栈跟踪和发布的代码,可以得出以下结论:

  • 您正在使用TrueZIP 6。这很重要,因为要求JRE支持IBM437字符集的根本原因是在ZIP文件中对文件条目进行编码时需要使用IBM437字符集,也被称为CP437
  • 您当前的JRE和操作环境不以任何形式支持IBM437字符集。请注意上一行的强调。显然,TrueZIP 6配备了支持IBM437的功能,尽管JRE可能不支持该字符集。 TrueZIP使用Java NIO中自Java 1.4以来可用的SPI提供程序概念来支持JRE不本地支持的其他字符集;在这种特殊情况下,IBM437字符集通过必须存在于truezip-6.jar文件中的de.schlichtherle.nio.charset.IBM437Charset类来支持。 JAR文件还必须包含以下文件:META-INF/services/java.nio.charset.spi.CharsetProvider,其内容为de.schlichtherle.nio.charset.spi.CharsetProvider(即嵌入在TrueZIP中的字符集提供程序注册了IBM437Charset类)。

根据上述,您应该验证以下内容:

  • Web应用程序的类加载器能否查找TrueZIP中嵌入的字符集提供程序?这很重要,因为底层的JRE(我假设它是Sun JRE 1.4.2_x)不支持IBM437字符集,而TrueZIP依赖于嵌入式字符集提供程序来支持IBM437字符集。由于CharsetProvider是使用当前线程的上下文类加载器查找的(在CharsetProvider Java API文档中指出),无法加载TrueZIP的CharsetProvider将导致抛出InconsistentCharsetSupportError。在大多数Web应用程序中,当前线程的上下文类加载器也恰好是Web应用程序的类加载器(从WEB-INF\libWEB-INF\classes加载类),但这并不一定正确。如果上下文类加载器不是Web应用程序类加载器,则必须将truezip-6.jar文件放置在上下文类加载器的类路径中,而不是WEB-INF\lib。
  • 您可以通过在独立的JRE中运行代码(从命令行)而不是在Web应用程序中运行代码来验证错误是否与加载TrueZIP CharsetProvider实现有关;请记住将truezip-6.jar放置在应用程序的类路径中。
  • 考虑将truezip-6.jar放置在Web应用程序容器使用的JRE的扩展目录(<jre>/lib/ext)中。只有在无法让当前线程的上下文类加载器加载TrueZIP CharsetProvider,并且已经验证问题是与加载CharsetProvider有关时,才应尝试这样做。

谢谢回复,但我不认为问题在jsp中。实际上,正在调用一个函数来制作所有订单的zip文件。我将其代码添加到原始问题中。这就是问题所在,正如根本原因所示,我也将其添加到原始问题中。请看看您是否能提供帮助。 - Khizar
@khizar,我可以推断出您正在使用Truezip 6。您能否发布您下载Truezip的网站位置?我无法将异常堆栈跟踪中的行号与Java.net网站上的源匹配。 - Vineet Reynolds
这不是我的项目,而是来自档案馆的一个项目,所以我不知道它是从哪个网站下载的,但我可以告诉你的是,在该项目中包含了truezip-6.jar。希望对你有所帮助。 - Khizar
非常感谢Vineet提供如此详细的答案。我会测试所有情况并反馈结果。 - Khizar
谢谢,伙计。我很着急,所以直接测试了第三个建议,结果非常好。 - Khizar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接