在通过 java 反射调用的方法中,为什么使用 Class.forName() 加载类会出异常?

本贴最后更新于 2253 天前,其中的信息可能已经时移世改

我利用反射执行 insert 方法,在该方法中执行到 Class.forName("org.jsoup.Jsoup")抛异常。

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3187 引用 • 8213 回帖
  • 反射
    19 引用 • 29 回帖
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    8112 引用 • 37003 回帖 • 160 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • nuaa123 1
    作者

    以下是我在众多博客中找到的稍微靠谱点的博文,大概原因就是 Tomcat 有自己的类加载器,必须要把第三方 jar 包放在 tomcat 的 lib 文件夹下面。亲测问题解决。

    在这篇博文中 java 动态加载指定的类或者 jar 包反射调用其方法,介绍动态加载指定的类,当时我是拿 URLClassLoader 介绍的,当然可以自定义一个 ClassLoader 重写对应的方法, 不过这个有现成的比自己重写更强大为何不用。

           话不多说,很久不写博客了,时间太紧了,起因还是一个网友私信我,说他反射创建某个对象时涉及其他 jar 中的类就会报 ClassNotFound 异常。

           其实,我也遇到过这个问题,在项目中反射创建一个 service 也是这样的,涉及到第三方的 jar 可能就出这问题,当时我可是纠结了好久,花了好几天时间去解决,请教过诸多大神和网友,不过还是不行,问题沉溺了有一阵子。

           网上很少又提到这个问题的。最近又请教几个有经验的网友说是没有 findClass 的原因,或是类名或者 service 的原因,应该是我描述问题没描述清楚吧。而且关键这个 jar 呀你不反射创建项目中用的好好的,就和昨天晚上私信我的那个网友一样,按 JVM 的双亲委托模型不应该啊,不熟悉的可以看看这译文个深入分析 Java ClassLoader 原理,自定义或者 URLClassLoader 的父加载器是 App ClassLoader,而这个 jar 或者类肯定它会找到并加载或者提前就加载到 JVM 里呢,怎么回事呢。

           其实你如果这样想,我们都犯了一个严重的错误,就是我们不是单纯依托与 JVM,程序结束就 OK 了,可能你测试的时候没问题,已到项目就有这问题。问题在于我们往往是运行在个应用服务器下,一般都是 tomcat 吧,而 tomcat 有自己的一套加载机制,有自己一些加载器,我们忽略这个因素才是导致了问题发生的根本原因。

           我们忽略了 tomcat 内部自定义的类加载器只想到了 JVM 的那几个加载器,tomcat 有个叫 webApp 的加载器它是先加载 WEB-INF/classes 后在加载 WEB-INF/lib,但它的父加载器是它的 common 加载器,comon 的父加载器是 system 加载器(和 JVM 的应用程序加载器功能差不多,不过指定了其他 tomcat 目录下的加载,大家可以看看官网上的英文文档),但是源码中这个加载器是 URLClassLoader 的子类,而 URLClassLoader 默认父加载 tomcat 下是它的 system 加载器这么设计和 tomcat 的配置有关,默认为无为 false,会直接委托给 tomcat 的 system 加载器加载 system 委托最顶层的 Bootstrap 加载器(差不多是 JVM 里起始加载器和扩展加载器的合并),但不管怎么样,项目在 tomcat 下自定义的或者 URLClassLoader 加载默认父加载器都不会是 tomcat 的 webApp 加载器而是 system 加载器,或者自定义的加载器或 URLClassLoader 和 tomcat 的 webApp 加载器没有上下关系,所以动态创建类时设计到其他类时肯定会报 CNF 异常。

          解决思路就是先获取当前类的 Class,然后获取当前类的加载器,在自定义的加载器或者 URLClassLoader 加载器创建时指定为它们的父加载器,这样问题就会游刃而解了,可能平常我们测试写个简单的例子没遇到这个问题,因为我们那时的 URLClassLoader 或者自定义的加载器的父加载器都是 JVM 的第三次加载器即应用程序加载,它是专门加载 classpath 下边的或者指定的类或者 jar 的,依照双亲委托模型,肯定会找到引入路径的那个类或者 jar 的。

         或者我们使用 Class.forName()的方式来动态加载指定的类,就不会存在这个问题,因为这种方式一方面是能初始化类的静态东西,再就是重要一点,就是采用的加载当前所在类的加载器来加载你指定的类,这样你在 tomcat 下那就是它的 webApp 加载器啊,肯定不再出现这个问题,可能直接就从缓存里找到了。

  • 其他回帖
  • 860562369 1

    Class.forName(),参数是一个文件路径,要是找不到你传入的路径,可不就得抛出异常

    1 回复

推荐标签 标签

  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    6 引用 • 38 回帖
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1348 回帖
  • HBase

    HBase 是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的 Google 论文 “Bigtable:一个结构化数据的分布式存储系统”。就像 Bigtable 利用了 Google 文件系统所提供的分布式数据存储一样,HBase 在 Hadoop 之上提供了类似于 Bigtable 的能力。

    17 引用 • 6 回帖 • 73 关注
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 629 关注
  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3453 回帖 • 203 关注
  • GraphQL

    GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

    4 引用 • 3 回帖 • 9 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 136 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 51 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 742 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 680 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    944 引用 • 1459 回帖 • 17 关注
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    85 引用 • 165 回帖 • 1 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    943 引用 • 943 回帖
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 175 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 22 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    53 引用 • 40 回帖 • 2 关注
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    153 引用 • 3783 回帖 • 1 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 354 关注
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    209 引用 • 2031 回帖 • 1 关注
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    238 引用 • 224 回帖
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 531 关注
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    176 引用 • 815 回帖
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    98 引用 • 344 回帖
  • 工具

    子曰:“工欲善其事,必先利其器。”

    286 引用 • 729 回帖