0

静的初期化子を持つ Tomcat アプリにクラスがあります。静的イニシャライザ内でAnErrorがスローされています。

問題は、Tomcat によって表示されるエラー メッセージに「原因」が含まれていないことです。つまり、そのエラーのメッセージとスタック トレースが表示されません。

次のように問題を再現できます。

public class BadInitClass
{
  static
  {
    if (System.currentTimeMillis() > 0)
      throw new Error("I need to see this message");
  }

  public void doSomething()
  {
    System.out.println("functionality here");
  }
}

ここで、単体テストからこのクラスを呼び出すと、次のようになります。

@Test
public void testStaticInit() throws Exception
{
  new BadInitClass().doSomething();
}

次に、テストはスタック トレースとメッセージを出力します。

java.lang.Error: I need to see this message
at mypackage.BadInitClass.<clinit>(BadInitClass.java:8)
at mypackage.BadInitClassTest.testStaticInit(UOneUtilitiesTest.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

ただし、同じコードをサーブレットに追加すると、Tomcat はメッセージを出力せず、次のメッセージのみを出力します。

exception

javax.servlet.ServletException: Servlet.init() for servlet MyServlet threw exception
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Thread.java:662)

root cause

java.lang.NoClassDefFoundError: Could not initialize class mypackage.BadInitClass
    mypackage.[calling code here]
    datcon.webmail.utils.DispatchedHttpServlet.init(DispatchedHttpServlet.java:77)
    MyServlet.init(MyServlet.java:57)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Thread.java:662)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.37 logs.

Tomcat 6.0.37 を実行しています。

これは Tomcat のバグですか? 回避策はありますか?

静的イニシャライザは一般的には良い考えではないことはわかっていますが、静的イニシャライザを使用するレガシー コードがいくつかあり、これらの問題のデバッグは、根本的なエラー メッセージやスタック トレースがなければ非常に困難です。

単体テストにNoClassDefFoundError-- 問題は tomcat が使用するカスタム ClassLoader と関係があるのでしょうか?

4

3 に答える 3

1

NoClassDefFoundError内部例外が許可されていないことに気付きました: http://docs.oracle.com/javase/7/docs/api/java/lang/NoClassDefFoundError.html

この場合、Tomcat のクラス ローダーに別の種類の例外をスローするようにパッチを適用しないと、これを修正できないのではないでしょうか?

于 2013-11-15T11:18:12.013 に答える