Java reflect vs. Qt Meta-Object

本文探讨了Java和C++中的反射机制,通过具体示例对比了两种语言实现反射的不同方式及其优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java的反射机制被广泛的应用在当今各种流行的开源框架中。只要你打开spring,struts或是hibernate的源代码,就可以发现Java反射的身影。利用反射,我们可以在系统运行时通过字符串来获取各种对象的类型,然后通过类型我们可以实例化对象并调用对象的相关方法。当然这一切对于Java来说都是非常的简单和容易理解,因为Java有虚拟机的存在,这个运行时系统就好比一个对象类型数据库,我们只要提供查询条件,就可以返回给我们所需要的对象类型。如下Java代码展示如何应用Reflect特性:

package org.storevm;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class MyClass {

    private String name;

    public MyClass() {

    }

    public void say() {

        System.out.println(name);

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public static void main(String[] args) throws Exception {

        Class clazz = Class.forName("org.storevm.MyClass");

        Object obj = clazz.newInstance();

        Field field = clazz.getDeclaredField("name");

        field.setAccessible(true);

        field.set(obj, "jacktan");

        Method method = clazz.getMethod("say", new Class[] {});

        method.invoke(obj, new Object[] {});

    }

}

上述代码的功能是:

1.  用字符串“org.storevm.MyClass”获取类型对象;

2.  将类型对象实例化为MyClass对象;

3.  从类型对象中获取name属性并设置为可读写状态;

4.  设置name属性的值为“jacktan”字符串;

5.  从类型对象中获取say方法对象;

6.  调用MyClass对象的say方法;

使用Java的反射,我们可以在不引用MyClass对象实例的情况下完成对MyClass对象的所有功能操作。

C++中并没有很强的内省功能,不过Qt 框架为C++扩展了一套类似Java反射的强大类型内省机制,我们称之为“Meta-Object”。通过这套系统,我们也可以非常容易的实现上述Java中实现的功能。不过相比较,Qt C++的编码要复杂一些,代码的可读性也不是很好,对于Java开发人来说可能看的不太习惯。如下代码展示了Qt C++中实现内省的特性:

头文件:cresultset.h

#ifndef CRESULTSET_H

#define CRESULTSET_H

 

#include<QObject>

#include<QString>

 

class CResultSet:public QObject

{

    Q_OBJECT

    Q_PROPERTY(QString m_name READ getName WRITE setName)

public:

    Q_INVOKABLE explicit CResultSet(QObject *parent = 0);

    Q_INVOKABLE CResultSet(const CResultSet &); //重新实现拷贝构造函数


    Q_INVOKABLE void say();

 

    Q_INVOKABLE QString getName() const {return m_name;}

    Q_INVOKABLE void setName(const QString &name){m_name = name;}

 
    CResultSet& operator=(const CResultSet &); //重载赋值操作符

private:

    QString m_name;

};

#endif// CRESULTSET_H


要实现C++的内省,首先必须公有继承Qt的QObject类,然后使用Q_OBJECT宏来标识需要实现内省。如果不继承QObject类而直接使用Q_OBJECT宏,则编译报错。Q_PROPERTY宏用以标识可被内省的成员变量,括号内看上去非常奇怪写法(看到下面就知道为什么要如此的写法)定义了成员变量的类型,名称以及读写该成员变量的setter和getter函数。Q_INVOKABLE宏用以标识可被内省的成员函数,这里需要注意的是,我们在类的构造函数上也标识了Q_INVOKEABLE宏,之后就能看到这样做的原因。为了实现内省,这些宏的标识是必须的,如果不在成员变量或成员函数上使用这些宏,则在调用indexOfProperty和indexOfMethod等函数时将永远返回-1,即无法使用内省。相比Java的实现,Qt的宏更具操控性,控制粒度更加细致,但是增加了编码量。

另外要提一下继承QObject时需要关注的问题。在QObject类中,赋值操作符和拷贝构造函数被定义为私有的,也就是说,通过继承QObject的类是无法进行赋值操作和对象拷贝的。为了解决这个问题,我们必须重新实现拷贝构造函数并重载赋值操作符。

以下代码为cpp文件的内容:cresultset.cpp

#include "cresultset.h"

#include <QDebug>

 

CResultSet::CResultSet(QObject *parent) :

    QObject(parent)

{

}

 

//拷贝构造函数

CResultSet::CResultSet(const CResultSet &other)
{
    *this=other;

}

 

void CResultSet::say()
{

    qDebug() << this->m_name;

}

 

//赋值操作符重载
CResultSet& CResultSet::operator =(const CResultSet &other)

{
    this->m_name = other.m_name;

    return *this;

}

以下代码为Meta-Object特性的调用:main.cpp

#include <QtGui/QApplication>

#include <QDebug>

#include <QMetaObject>

#include <QMetaProperty>

 

int main(int argc,char *argv[])

{

    QApplicationa(argc, argv);

    QMetaObject metaObject = CResultSet::staticMetaObject;
    
    QObject* rs = metaObject.newInstance();   

    int pidx = (rs->metaObject())->indexOfProperty("m_name");

    qDebug() << pidx;

    QMetaProperty property = (rs->metaObject())->property(pidx);

    property.write(rs, QVariant("jacktan111"));

    QMetaObject::invokeMethod(rs, "say", Qt::DirectConnection);

    return a.exec();
}

首先使用类(此类必须继承自QObject)的静态函数staticMetaObject获取QMetaObject对象,该对象中包含了所有元对象信息,包括类名,成员函数,成员变量,信号和槽等,类似于Java中的Class类。然后通过QMetaObject对象的newInstance函数返回QObject的指针,这步类似Java中的Class.newInstance方法。接下去就是一些操作元对象的操作。比如通过实例对象的QMetaObject对象的indexOfProperty函数可以返回指定成员变量名称的索引值,比如利用该索引值调用QMetaObject::property(int)函数,就能得到QMetaProperty对象,该对象类似Java中的Field类,保存了有关于成员变量的相关元数据。QMetaProperty对象中read和write函数分别用于成员变量的读写。写到这里,相信大家都明白了吧!之前的Q_PROPERTY宏为什么定义成如此奇怪的形状。正是通过READ和WRITE指定的函数名称来实现QMetaProperty对象中的read和write函数。

使用QMetaObject对象的静态函数invokeMethod可以调用指定对象的成员函数,前提是被调用的成员函数必须被Q_INVOKABLE宏所修饰。成员函数的调用有2种方式:同步的和异步的,同步使用Qt:: DirectConnection参数,异步使用Qt:: QueuedConnection参数。上述C++代码的功能与Java版本实现的功能完全一样。即通过内省特性为一个实例化对象的成员变量赋值,并调用指定的成员函数。相比之下,Java的内省更容易理解且使用起来也更自然一些,至少没有那些让人看的很费解的宏定义。

最后说说Qt这个C++开发框架,它的强大自不必多说,时间证明了一切。尤其是其跨平台的能力绝对不亚于号称一次编写,随处运行的Java。只要做过跨平台开发的人都知道,要真正实现跨平台应用程序是何其的困难,光是编译源代码这一关就能彻底摧毁你对跨平台应用程序的美好期望,所以为什么Java会那么不厌其烦的宣扬它的跨平台能力。对于开发人员来说根本无需关心编写的代码将来要运行在什么平台上,但是Java的跨平台是借助了JVM的力量,JVM本身并不是跨平台的。每个平台有其自己特定的JVM实现,只是对开发人员来说这一切是透明的,无需开发人员关注。C++是编译成本地代码执行的,没有JVM这种just in time的运行时系统。所以从这点看Qt实现的跨平台比Java更强大,但是天下无免费晚餐,Qt为了实现跨平台,把所有的负担转嫁给了程序员,为了实现跨平台,程序员需要更加缜密的思维和使用大量令人费解的宏定义。

Java的弱势是其GUI方面,虽然现在基于浏览器的应用程序满天飞,但是GUI程序并没有因此而退出历史舞台,在很多场合GUI程序以其界面的统一性以及高性能被广泛的应用在如嵌入式系统,工业应用等领域。这也是QtGUI为什么能活跃到现在的原因。在某些企业应用中,Java和C++可以完美的组合起来,比如,Java用于编写业务逻辑组件,充分发挥其面向对象建模的优势。而C++ Qt GUI则可利用跨语言的通讯机制与Java服务器组件进行交互,从而实现高性能的用户界面体验。而在另外一些场合,我们则可以利用Qt C++的高性能编写服务器端业务处理,而使用Java编写B/S界面解决统一部署的问题,充分结合2种开发语言的优势。所以最为一个好的设计人员,不能拘泥于一种语言的实现平台,应该海纳百川,充分利用各种平台的优势加以结合,创建趋于完美的应用系统。

Qt在很多方面借鉴了Java的设计理念,比如Qt的GUI组件模型,Qt的内省,Qt的布局管理器,Qt的MVC模型等等,处处可见Java设计的影子。所以如果你是一个Java开发人员,那当你遇到Qt时,肯定会有一种似曾相识的感觉。


C:\Users\12527\apache-tomcat-9.0.100\bin\catalina.bat run [2025-05-13 10:55:19,558] 工件 system:war exploded: 正在等待服务器连接以启动工件部署… Using CATALINA_BASE: "C:\Users\12527\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\65fada1a-4c68-4c21-b3b6-bcc92846abdc" Using CATALINA_HOME: "C:\Users\12527\apache-tomcat-9.0.100" Using CATALINA_TMPDIR: "C:\Users\12527\apache-tomcat-9.0.100\temp" Using JRE_HOME: "C:\Users\12527\.jdks\temurin-22.0.2" Using CLASSPATH: "C:\Users\12527\apache-tomcat-9.0.100\bin\bootstrap.jar;C:\Users\12527\apache-tomcat-9.0.100\bin\tomcat-juli.jar" Using CATALINA_OPTS: "" NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED 13-May-2025 10:55:20.722 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.服务器版本: Apache Tomcat/9.0.100 13-May-2025 10:55:20.724 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器构建: Feb 13 2025 11:29:56 UTC 13-May-2025 10:55:20.724 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器版本号: 9.0.100.0 13-May-2025 10:55:20.724 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 操作系统名称: Windows 11 13-May-2025 10:55:20.724 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS.版本: 10.0 13-May-2025 10:55:20.724 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 架构: amd64 13-May-2025 10:55:20.724 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java 环境变量: C:\Users\12527\.jdks\temurin-22.0.2 13-May-2025 10:55:20.724 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java虚拟机版本: 22.0.2+9 13-May-2025 10:55:20.724 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.供应商: Eclipse Adoptium 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: C:\Users\12527\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\65fada1a-4c68-4c21-b3b6-bcc92846abdc 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: C:\Users\12527\apache-tomcat-9.0.100 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: --add-opens=java.base/java.lang=ALL-UNNAMED 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: --add-opens=java.base/java.io=ALL-UNNAMED 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: --add-opens=java.base/java.util=ALL-UNNAMED 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.util.logging.config.file=C:\Users\12527\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\65fada1a-4c68-4c21-b3b6-bcc92846abdc\conf\logging.properties 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 13-May-2025 10:55:20.725 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote= 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote.port=1099 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote.ssl=false 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote.password.file=C:\Users\12527\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\65fada1a-4c68-4c21-b3b6-bcc92846abdc\jmxremote.password 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote.access.file=C:\Users\12527\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\65fada1a-4c68-4c21-b3b6-bcc92846abdc\jmxremote.access 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.rmi.server.hostname=127.0.0.1 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djdk.tls.ephemeralDHKeySize=2048 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dsun.io.useCanonCaches=false 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dignore.endorsed.dirs= 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcatalina.base=C:\Users\12527\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\65fada1a-4c68-4c21-b3b6-bcc92846abdc 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcatalina.home=C:\Users\12527\apache-tomcat-9.0.100 13-May-2025 10:55:20.726 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.io.tmpdir=C:\Users\12527\apache-tomcat-9.0.100\temp 13-May-2025 10:55:20.729 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent 使用APR版本[1.7.4]加载了基于APR的Apache Tomcat本机库[1.3.1]。 13-May-2025 10:55:20.729 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR功能:IPv6[true]、sendfile[true]、accept filters[false]、random[true]、UDS [true]。 13-May-2025 10:55:20.729 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL配置:useAprConnector[false],useOpenSSL[true] 13-May-2025 10:55:20.733 信息 [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL成功初始化 [OpenSSL 3.0.14 4 Jun 2024] 13-May-2025 10:55:20.846 信息 [main] org.apache.coyote.AbstractProtocol.init 初始化协议处理器 ["http-nio-8080"] 13-May-2025 10:55:20.857 信息 [main] org.apache.catalina.startup.Catalina.load 服务器在[276]毫秒内初始化 13-May-2025 10:55:20.902 信息 [main] org.apache.catalina.core.StandardService.startInternal 正在启动服务[Catalina] 13-May-2025 10:55:20.902 信息 [main] org.apache.catalina.core.StandardEngine.startInternal 正在启动 Servlet 引擎:[Apache Tomcat/9.0.100] 13-May-2025 10:55:20.911 信息 [main] org.apache.coyote.AbstractProtocol.start 开始协议处理句柄["http-nio-8080"] 13-May-2025 10:55:20.949 信息 [main] org.apache.catalina.startup.Catalina.start [90]毫秒后服务器启动 已连接到服务器 [2025-05-13 10:55:21,189] 工件 system:war exploded: 正在部署工件,请稍候… 13-May-2025 10:55:21.499 警告 [RMI TCP Connection(2)-127.0.0.1] org.apache.tomcat.util.descriptor.web.WebXml.setVersion 未知版本字符串 [5.0]。将使用默认版本。 13-May-2025 10:55:21.655 警告 [RMI TCP Connection(2)-127.0.0.1] org.apache.tomcat.util.descriptor.web.WebXml.setVersion 未知版本字符串 [5.0]。将使用默认版本。 13-May-2025 10:55:23.948 严重 [RMI TCP Connection(2)-127.0.0.1] org.apache.tomcat.util.modeler.BaseModelMBean.invoke 调用方法[manageApp]时发生异常 java.lang.IllegalStateException: 启动子级时出错 at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:602) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:571) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:603) at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1751) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:264) at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:803) at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802) at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:453) at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:407) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:264) at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:803) at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802) at java.management/com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:472) at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1472) at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1310) at java.base/java.security.AccessController.doPrivileged(AccessController.java:714) at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1412) at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360) at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200) at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197) at java.base/java.security.AccessController.doPrivileged(AccessController.java:714) at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196) at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:598) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:844) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:721) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:720) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1570) Caused by: org.apache.catalina.LifecycleException: 无法启动组件[StandardEngine[Catalina].StandardHost[localhost].StandardContext[/system_war_exploded]] at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:406) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:179) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:599) ... 36 more Caused by: java.lang.IllegalStateException: 由于StackOverflower错误,无法完成对web应用程序[/system_war_exploded]的批注的扫描。可能的根本原因包括-Xss的设置过低和非法的循环继承依赖项。正在处理的类层次结构是[com.opensymphony.xwork2.interceptor.NoParameters->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object] at org.apache.catalina.startup.ContextConfig.checkHandlesTypes(ContextConfig.java:2307) at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2247) at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:2204) at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:2177) at org.apache.catalina.startup.ContextConfig.scanWebXmlFragment(ContextConfig.java:2085) at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:2065) at org.apache.catalina.startup.ContextConfig.processClasses(ContextConfig.java:1372) at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1273) at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:973) at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:290) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4407) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) ... 37 more 13-May-2025 10:55:23.950 严重 [RMI TCP Connection(2)-127.0.0.1] org.apache.tomcat.util.modeler.BaseModelMBean.invoke 调用方法[createStandardContext]时发生异常 javax.management.RuntimeOperationsException: 调用方法[manageApp]时发生异常 at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:274) at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:803) at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802) at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:453) at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:407) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:264) at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:803) at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802) at java.management/com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:472) at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1472) at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1310) at java.base/java.security.AccessController.doPrivileged(AccessController.java:714) at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1412) at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360) [2025-05-13 10:55:23,969] 工件 system:war exploded: 部署工件时出错。请参阅服务器日志了解详细信息。 at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200) at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197) at java.base/java.security.AccessController.doPrivileged(AccessController.java:714) at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196) at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:598) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:844) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:721) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:720) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1570) Caused by: java.lang.IllegalStateException: 启动子级时出错 at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:602) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:571) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:603) at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1751) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:264) ... 30 more Caused by: org.apache.catalina.LifecycleException: 无法启动组件[StandardEngine[Catalina].StandardHost[localhost].StandardContext[/system_war_exploded]] at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:406) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:179) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:599) ... 36 more Caused by: java.lang.IllegalStateException: 由于StackOverflower错误,无法完成对web应用程序[/system_war_exploded]的批注的扫描。可能的根本原因包括-Xss的设置过低和非法的循环继承依赖项。正在处理的类层次结构是[com.opensymphony.xwork2.interceptor.NoParameters->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object->java.lang.Object] at org.apache.catalina.startup.ContextConfig.checkHandlesTypes(ContextConfig.java:2307) at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2247) at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:2204) at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:2177) at org.apache.catalina.startup.ContextConfig.scanWebXmlFragment(ContextConfig.java:2085) at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:2065) at org.apache.catalina.startup.ContextConfig.processClasses(ContextConfig.java:1372) at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1273) at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:973) at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:290) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4407) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) ... 37 more 13-May-2025 10:55:30.932 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [C:\Users\12527\apache-tomcat-9.0.100\webapps\manager] 13-May-2025 10:55:31.244 信息 [Catalina-utility-1] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 13-May-2025 10:55:31.278 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[C:\Users\12527\apache-tomcat-9.0.100\webapps\manager]的部署已在[346]毫秒内完成
05-14
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值