【问题标题】:java ee: class not found despite valid import?!java ee:尽管导入有效,但找不到类?!
【发布时间】:2014-10-09 21:28:51
【问题描述】:

我使用 jersey 创建某种 RESTful API。为了获取有关当前请求的信息,我使用了 HttpServletRequest 对象。我能够编译项目而没有问题或错误,但是当我运行它时,我收到以下错误:

[INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ backend ---
[WARNING] 
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2570)
    at java.lang.Class.getDeclaredMethods(Class.java:1855)
    at org.glassfish.jersey.server.model.IntrospectionModeller$2.run(IntrospectionModeller.java:236)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.glassfish.jersey.server.model.IntrospectionModeller.getAllDeclaredMethods(IntrospectionModeller.java:230)
    at org.glassfish.jersey.server.model.IntrospectionModeller.checkForNonPublicMethodIssues(IntrospectionModeller.java:170)
    at org.glassfish.jersey.server.model.IntrospectionModeller.doCreateResourceBuilder(IntrospectionModeller.java:118)
    at org.glassfish.jersey.server.model.IntrospectionModeller.access$000(IntrospectionModeller.java:80)
    at org.glassfish.jersey.server.model.IntrospectionModeller$1.call(IntrospectionModeller.java:111)
    at org.glassfish.jersey.server.model.IntrospectionModeller$1.call(IntrospectionModeller.java:108)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
    at org.glassfish.jersey.server.model.IntrospectionModeller.createResourceBuilder(IntrospectionModeller.java:108)
    at org.glassfish.jersey.server.model.Resource.from(Resource.java:744)
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:400)
    at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:163)
    at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:323)
    at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289)
    at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:320)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:285)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.<init>(GrizzlyHttpContainer.java:331)
    at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer(GrizzlyHttpServerFactory.java:116)
    at com.getbro.api.Main.startServer(Main.java:32)
    at com.getbro.api.Main.main(Main.java:42)
    ... 6 more
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpServletRequest
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 36 more

我觉得很奇怪,因为我每个 maven 都导入了这个类:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

...所以它应该像预期的那样工作,但它没有!

【问题讨论】:

    标签: java maven jakarta-ee classnotfoundexception jersey-2.0


    【解决方案1】:

    您的依赖项具有provided 范围,这意味着该工件可用于编译,但不能在运行时使用。有关此主题的更多信息,请访问 the Maven documentation 或 this StackOverflow question。

    这是正确的做法,因为 Servlet API 不是您希望在您的 WAR、EAR 或您正在构建的任何包中拥有的东西。相反,这个 servlet-api JAR 将由您的应用程序服务器(Tomcat、Jetty...)提供。

    如果您从 Eclipse 运行 Web 服务项目,您需要告诉他它必须使用哪个服务器运行时。 (如果您使用的是 Eclipse 以外的 IDE,则必须执行类似的操作):

    • 窗口 > 首选项 > 服务器 > 运行时环境。
    • 如果已经为您的服务器定义了运行时环境(例如,如果您使用的是 Tomcat 6.x),请取消此窗口。否则,请使用 添加... 按钮创建它。

    一旦定义了运行时环境:

    • 右键单击您的项目> 构建路径 > 配置构建路径...。
    • 库 选项卡 > 添加库。
    • 选择适当的服务器运行时并完成。

    【讨论】:

      【解决方案2】:

      您在提供的范围内导入它。这样你只需保证别担心,它会在那里,战争不会增加任何东西。使用范围 compile 实际导入依赖项。

      【讨论】:

      • 在 IDE 中进行测试时,将范围更改为 compile 会起作用。但是,当您将完成的项目实际部署到应用程序服务器时,这会导致问题,因为将有 2 个 servlet-api JAR:一个由服务器提供,另一个在您的 WAR 中。例如,Tomcat 将无法为您的应用程序启动上下文。
      • 其实它不会引起任何问题,因为它是一个只包含API的jar。它没有实现类,应用程序将使用容器类。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-04
      • 1970-01-01
      • 2019-02-04
      • 2020-05-14
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      相关资源
      最近更新 更多