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

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

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

  • Java

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

    3167 引用 • 8207 回帖 • 1 关注
  • 反射
    18 引用 • 29 回帖
  • Q&A

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

    6505 引用 • 29237 回帖 • 246 关注

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • 860562369 1

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

    1 回复
  • 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 加载器啊,肯定不再出现这个问题,可能直接就从缓存里找到了。

推荐标签 标签

  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 2 关注
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    523 引用 • 4581 回帖 • 692 关注
  • 反馈

    Communication channel for makers and users.

    123 引用 • 906 回帖 • 191 关注
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 454 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖 • 2 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    122 引用 • 73 回帖
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 247 回帖 • 183 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 149 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    5 引用 • 13 回帖 • 1 关注
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    1 引用 • 11 回帖
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 642 关注
  • 自由行
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    20 引用 • 245 回帖 • 229 关注
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖 • 1 关注
  • Netty

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

    49 引用 • 33 回帖 • 21 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    85 引用 • 1201 回帖 • 455 关注
  • GitHub

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

    207 引用 • 2031 回帖
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 36 关注
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    82 引用 • 122 回帖 • 614 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    76 引用 • 37 回帖
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    180 引用 • 447 回帖
  • SSL

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层对网络连接进行加密。

    69 引用 • 190 回帖 • 493 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    90 引用 • 59 回帖 • 3 关注
  • V2Ray
    1 引用 • 15 回帖
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 249 关注
  • Flume

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

    9 引用 • 6 回帖 • 592 关注