精华内容
下载资源
问答
  • 本资源可以解决SLF4J: Failed to load class "org.slf问题
  • Unable to load class 'org.gradle.api.internal.plugins.DefaultConvention'. 原因 IDE与Gradle不兼容。 解决办法 https://services.gradle.org/distributions,检查是否有对应的版本。 修改gradle-wrapper....
    • 错误
    Unable to load class 'org.gradle.api.internal.plugins.DefaultConvention'.
    • 原因

     IDE与Gradle不兼容。

    • 解决办法

    https://services.gradle.org/distributions,检查是否有对应的版本。

    修改gradle-wrapper.properties,把链接复制过去:

    错误:https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

    正确:https://downloads.gradle-dn.com/distributions/gradle-5.6.4-all.zip

    • 详细错误
    java.lang.NoClassDefFoundError: org/gradle/api/internal/plugins/DefaultConvention
    	at org.jetbrains.plugins.gradle.tooling.builder.ProjectExtensionsDataBuilderImpl.buildAll(ProjectExtensionsDataBuilderImpl.groovy:50)
    	at org.jetbrains.plugins.gradle.tooling.internal.ExtraModelBuilder.buildAll(ExtraModelBuilder.java:67)
    	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildOperationWrappingToolingModelBuilder$1$1.create(DefaultToolingModelBuilderRegistry.java:104)
    	at org.gradle.api.internal.project.DefaultProjectStateRegistry.withLenientState(DefaultProjectStateRegistry.java:134)
    	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildOperationWrappingToolingModelBuilder$1.call(DefaultToolingModelBuilderRegistry.java:100)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
    	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
    	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildOperationWrappingToolingModelBuilder.buildAll(DefaultToolingModelBuilderRegistry.java:97)
    	at org.gradle.tooling.internal.provider.runner.DefaultBuildController.getModel(DefaultBuildController.java:82)
    	at org.gradle.tooling.internal.provider.runner.DefaultBuildController.getModel(DefaultBuildController.java:63)
    	at org.gradle.tooling.internal.consumer.connection.BuildControllerAdapter.getModel(BuildControllerAdapter.java:58)
    	at org.gradle.tooling.internal.consumer.connection.AbstractBuildController.findModel(AbstractBuildController.java:39)
    	at org.jetbrains.plugins.gradle.model.ProjectImportAction.addExtraProject(ProjectImportAction.java:123)
    	at org.jetbrains.plugins.gradle.model.ProjectImportAction.execute(ProjectImportAction.java:76)
    	at org.jetbrains.plugins.gradle.model.ProjectImportAction.execute(ProjectImportAction.java:40)
    	at org.gradle.tooling.internal.consumer.connection.InternalBuildActionAdapter.execute(InternalBuildActionAdapter.java:53)
    	at org.gradle.tooling.internal.provider.runner.ClientProvidedBuildActionRunner$ResultBuildingListener.buildResult(ClientProvidedBuildActionRunner.java:116)
    	at org.gradle.tooling.internal.provider.runner.ClientProvidedBuildActionRunner$ResultBuildingListener.buildFinished(ClientProvidedBuildActionRunner.java:106)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    	at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:382)
    	at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:364)
    	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
    	at org.gradle.internal.event.DefaultListenerManager$EventBroadcast$ListenerDispatch.dispatch(DefaultListenerManager.java:352)
    	at org.gradle.internal.event.DefaultListenerManager$EventBroadcast$ListenerDispatch.dispatch(DefaultListenerManager.java:339)
    	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
    	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:231)
    	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:150)
    	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
    	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:325)
    	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:235)
    	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:141)
    	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
    	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    	at com.sun.proxy.$Proxy16.buildFinished(Unknown Source)
    	at org.gradle.initialization.DefaultGradleLauncher.finishBuild(DefaultGradleLauncher.java:174)
    	at org.gradle.initialization.DefaultGradleLauncher.finishBuild(DefaultGradleLauncher.java:117)
    	at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:86)
    	at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:78)
    	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:189)
    	at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
    	at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:78)
    	at org.gradle.internal.invocation.GradleBuildController.configure(GradleBuildController.java:67)
    	at org.gradle.tooling.internal.provider.runner.ClientProvidedBuildActionRunner.run(ClientProvidedBuildActionRunner.java:57)
    	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    	at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:63)
    	at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
    	at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:39)
    	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:51)
    	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:45)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
    	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
    	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:50)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
    	at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:80)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:47)
    	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:31)
    	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:42)
    	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:28)
    	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:78)
    	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:52)
    	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:60)
    	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:38)
    	at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:68)
    	at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:38)
    	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:37)
    	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:26)
    	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
    	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
    	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:60)
    	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
    	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
    	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
    	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:48)
    	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:32)
    	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:68)
    	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:27)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
    	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
    	at org.gradle.util.Swapper.swap(Swapper.java:38)
    	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
    	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
    	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
    	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
    	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    	at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.ClassNotFoundException: org.gradle.api.internal.plugins.DefaultConvention
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    	... 121 more
    
    
    展开全文
  • loadClass()和forName()的区别

    千次阅读 多人点赞 2019-06-28 21:53:03
    显式加载:使用 loadClass()、forName() 等方法显式的加载需要的类,对于显式加载这种类加载方式来讲,当我们获取到了 Class 对象后,需要调用 Class 对象的 newInstance() 方法来生成对象的实例。 两种类加载方式...

    类加载的方式

    主要有两种:

    • 隐式加载:使用 new + 构造方法时,隐式的调用类加载器,加载对应的类到 JVM 中,是最常见的类加载方式。
    • 显式加载:使用 loadClass()、forName() 等方法显式的加载需要的类,对于显式加载这种类加载方式来讲,当我们获取到了 Class 对象后,需要调用 Class 对象的 newInstance() 方法来生成对象的实例。

    两种类加载方式的区别:

    • 隐式加载能够直接获取对象的实例,而显式加载需要调用 Class 对象的 newInstance() 方法来生成对象的实例。
    • 隐式加载能够使用有参的构造函数,而使用 Class 对象的 newInstance() 不支持传入参数,如果想使用有参的构造函数,必须通过反射的方式,来获取到该类的有参构造方法。

    关于 Java 虚拟机类加载机制更多的内容请参考我另一篇文章:虚拟机类加载机制总结
     

    loadClass() 和 forName() 的区别

    首先,不管是使用 loadClass() 还是 forName(),对于任意一个类,我们都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这也是实现反射的重要方法。

    那么这两个方法的区别在哪呢?我们通过源码来分析。

    1. loadClass()

    public Class<?> loadClass(String name) throws ClassNotFoundException {
            return loadClass(name, false);
    }
    
    protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                // First, check if the class has already been loaded
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    long t0 = System.nanoTime();
                    try {
                        if (parent != null) {
                            c = parent.loadClass(name, false);
                        } else {
                            c = findBootstrapClassOrNull(name);
                        }
                    } catch (ClassNotFoundException e) {
                        // ClassNotFoundException thrown if class not found
                        // from the non-null parent class loader
                    }
    
                    if (c == null) {
                        // If still not found, then invoke findClass in order
                        // to find the class.
                        long t1 = System.nanoTime();
                        c = findClass(name);
    
                        // this is the defining class loader; record the stats
                        sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                        sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                        sun.misc.PerfCounter.getFindClasses().increment();
                    }
                }
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
    }
    
    protected final void resolveClass(Class<?> c) {
            resolveClass0(c);
    }
    
    private native void resolveClass0(Class<?> c);
    

    我们主要来看一下 resolve 这个布尔变量,resolve 即解析,我们可以看到,在重载的 loadClass() 方法中,如果 resolve 为 true 的话,会执行 resolveClass() 这个方法。我们再来看一下 resolveClass() 这个方法中的这一句注释。
    在这里插入图片描述
    我圈红框的这里,Links the specified class :链接指定的类。

    我们再回过头来看看,return loadClass(name, false);,默认的 loadClass() 方法会传入 false,也就是说,使用默认的 loadClass() 方法获得的 Class 对象是还没有执行链接的。那如果你了解 Java 虚拟机的类加载机制的话,这个时候你便应该知道,使用 loadClass() 方法获得的 Class 对象只完成了类加载过程中的第一步:加载,后续的操作均未进行。

    2. forName()

    @CallerSensitive
    public static Class<?> forName(String className)
                    throws ClassNotFoundException {
            Class<?> caller = Reflection.getCallerClass();
            return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }
    
    @CallerSensitive
    public static Class<?> forName(String name, boolean initialize,
                                       ClassLoader loader)
            throws ClassNotFoundException
        {
            Class<?> caller = null;
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                // Reflective call to get caller class is only needed if a security manager
                // is present.  Avoid the overhead of making this call otherwise.
                caller = Reflection.getCallerClass();
                if (sun.misc.VM.isSystemDomainLoader(loader)) {
                    ClassLoader ccl = ClassLoader.getClassLoader(caller);
                    if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
                        sm.checkPermission(
                            SecurityConstants.GET_CLASSLOADER_PERMISSION);
                    }
                }
            }
            return forName0(name, initialize, loader, caller);
    }
    

    我们也是来重点关注一个布尔变量,那就是 initialize 变量。initialize 即初始化。

    return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    

    我们可以看到,默认传入的 initialize 为 true.说明使用 Class.forName() 方法获得 Class 对象是已经执行完初始化的了(注意这里指的是类加载过程中的最后一步:初始化,而非是实例化对象操作的初始化

    所以,看到这里相信大家也明白了,这两个方法的区别:

    • 使用 loadClass() 方法获得的 Class 对象只完成了类加载过程中的第一步:加载,后续的操作均未进行。
    • 使用 Class.forName() 方法获得 Class 对象是已经执行完初始化的了

     

    两者的使用场景

    对于 Class.forName() 方法,相信大家并不陌生,因为在 Web 开发中,经常会用到使用这个方法来加载 MySQL 的驱动,Class.forName("com.mysql.jdbc.Driver");

    我们看一下驱动的源码会发现在类 Driver 中有这样一个静态代码块,静态代码块会在类加载过程中的初始化阶段执行。

    所以我们现在应该知道了什么时候使用 Class.forName() 方法:在需要对类进行初始化的时候。

     static {  
              try {
                    //往DriverManager中注册自身驱动
                    java.sql.DriverManager.registerDriver(new Driver());  
               } catch (SQLException E) {  
                    throw new RuntimeException("Can't register driver!");  
               }
    }
    

    那么为什么还要有 loadClass() 呢?

    举个小例子,在 Spring IOC 中,在资源加载器获取要读入的字节的时候,即读取一些 Bean 的配置的时候,如果是以 classpath 的方式来加载,就需要使用 ClassLoader 的 loadClass() 方法来加载。之所以这样做,是和 Spring IOC 的 Lazy Loading 有关,即延迟加载。Spring IOC 为了加快初始化的速度,大量的使用了延迟加载技术,而使用 ClassLoader 的 loadClass() 方法不需要执行类加载过程中的链接和初始化的步骤,这样做能有效的加快加载速度,把类的初始化工作留到实际使用到这个类的时候才去执行。

    展开全文
  • ClassLoader中的loadClass和findClass方法

    千次阅读 2018-07-25 19:44:39
    Java中ClassLoader的具体实现 ...jdk中classloader中loadclass方法的实现如下所示: protected Class&lt;?&gt; loadClass(String name, boolean resolve) throws ClassNotFoundExcep...

    Java中ClassLoader的具体实现

    Java虚拟机的类加载器本身可以满足加载的要求,但是也允许开发者自定义类加载器。

    jdk中classloader中loadclass方法的实现如下所示:

    protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                // First, check if the class has already been loaded
                //查找.class是否被加载过
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    long t0 = System.nanoTime();
                    try {
                    //查看父加载器有没有加载过
                        if (parent != null) {
                            c = parent.loadClass(name, false);
                        } else {
                        //还没找到的话查找根加载器,这里就是双亲委派模型的实现
                            c = findBootstrapClassOrNull(name);
                        }
                    } catch (ClassNotFoundException e) {
                        // ClassNotFoundException thrown if class not found
                        // from the non-null parent class loader
                    }
    
                    if (c == null) {
                        // If still not found, then invoke findClass in order
                        // to find the class.
                        //找到根加载器依然为空,只能子加载器自己加载了
                        long t1 = System.nanoTime();
                        c = findClass(name);
    
                        // this is the defining class loader; record the stats
                        sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                        sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                        sun.misc.PerfCounter.getFindClasses().increment();
                    }
                }
                // 解析class文件,就是将符号引用替换为直接引用的过程
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
        }

    在这其中,涉及到一个findclass方法,查看源码后结果如下所示:

    protected Class<?> findClass(String name) throws ClassNotFoundException {
            throw new ClassNotFoundException(name);
        }

    这只是一个空方法,返回内容为class,方法其中没有任何内容,只抛出了个异常,说明这个方法需要开发者自己去实现。

    自定义类加载器

    首先根据源码可以知道,如果自定义的方法不想违背双亲委派模型,则只需要重写findclass方法即可,如果想违背双亲委派模型,则还需要重写loadclass方法。

    展开全文
  • loadClass方法一直存在,没有实现双亲委派模型,不过可以让我们自己去实现。 双亲委派模型的目的 对于JVM而言,能够加载的类都是将.java文件通过编译后的字节码加载入内存中的。而编译后的文件,也就是通过javac...

    findClass方法是JDK1.2后提出的,目的是为了保证加载的类符合双亲委派模型。而loadClass方法一直存在,没有实现双亲委派模型,不过可以让我们自己去实现。

    双亲委派模型的目的

    对于JVM而言,能够加载的类都是将.java文件通过编译后的字节码加载入内存中的。而编译后的文件,也就是通过javac命令编译成的.class文件,终究是以流的形式变成byte[]的数组,再通过ClassLoader的defineClass方法使其最终加载入内存,并可以在代码中获取到对应的Class类。

    在这个过程中,对于defineClass而言,这个byte数组是如何获取到的毫不关心。比如,可以通过从文件中读取,可以从网络下载,可以是将加密后的数据解密后的结果,甚至可以根据实际使用场景new出一个byte数组,自己往数组中写入数据都是可以的。

    但是,传入defineClass的字节byte数组,一定要符合class文件的结构和规则。正是因为虚拟机这样的灵活的加载方式,才实现了诸多灵活多变的技术。比如,早年的Applet以及当下Android的热更新;又或者像Javassist针对JVM生成class的框架或者dexmaker针对Dalvik生成dex的框架,可以在程序运行时生成想要的类,随之加载入内存等等。

    这样做就带来了一个问题,在不做特殊处理的情况下,任何类都是可以通过自定义的ClassLoader加载的,如果这个类之前已经被父ClassLoader加载过,内存中就会有多个具有相同全限定名的类被加载到内存中。

    内存中存在多个相同全限定名的类也并非不好,只是根据实际应用场景,比如像Object的类,我们是不希望内存中存在多个的,如果父ClassLoader已经加载过,我们拿来用就好。而且重复加载Object,也会在类判定上带来问题,因为判断两个类是否一致,不仅要看全限定名是否相同,还要看是否具有相同的ClassLoader。

    但是对于某些场景,比如自定义的ClassLoader,我们允许一些类可以被不同ClassLoader加载,这时即使不遵循双亲委派模型也是可以的。

    综上,双亲委派模型并不是一定要遵循的标准,它只是用来解决当我们不希望内存中存在多个具有相同全限定名加载类的情况。同时,将自定义ClassLoader可以加载的类仅限定在特定的类上,其他的类仍然按照原有的加载方式。

    关于findClass

    下面的代码是ClassLoader的loadClass方法。如果我们重写的是findClass,只有当父ClassLoader都没有加载某个类时,才会去调用c=findClass(name)。也就是说,findClass方法实际上是ClassLoader留给我们去重写的,如果希望遵循双亲委派模型的话。

         protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
                synchronized (getClassLoadingLock(name)) {
                      // First, check if the class has already been loaded
                      Class c = findLoadedClass(name);
                      if (c == null) {
                            long t0 = System.nanoTime();
                            try {
                                  if (parent != null) {
                                         c = parent.loadClass(name, false);
                                  } else {
                                         c = findBootstrapClassOrNull(name);
                                  }
                            } catch (ClassNotFoundException e) {
                                  // ClassNotFoundException thrown if class not found
                                  // from the non-null parent class loader
                            }
    
                            if (c == null) {
                                  // If still not found, then invoke findClass in order
                                  // to find the class.
                                  long t1 = System.nanoTime();
                                  c = findClass(name);
    
                                  // this is the defining class loader; record the stats
                                  sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); 
                                  sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                                  sun.misc.PerfCounter.getFindClasses().increment();
                             }
                      }
                      if (resolve) {
                             resolveClass(c);
                      }
                      return c;
                }
          }
    
    

    关于loadClass

    假如我们铁了心了就是想要不遵循双亲委派模型,可以直接去重写loadClass。但是这样做也有需要解决的问题,比如一个类Hello,该类依赖java.lang.Object和java.lang.String方法。

    	public class Hello {
    		public static String getMessage() {
    			return "hello";
    		}
    	}
    

    如果在自定义ClassLoader时按照如下写法加载Hello时,自定义ClassLoader无法加载Object和String,则会报出NoClassDefFoundError。对于这种情况,手动地将调用super.loadClass,以便让父ClassLoader去加载Object和String的类。

    	public Class<?> loadClass(String name) throws ClassNotFoundException {
    		System.out.println("load:" + name);
    		byte[] bytes = paraseClassByName(name);
    		if (bytes == null) {
    			System.out.println("load failed:" + name);
    			return null;
    		}
    		return defineClass(name, bytes, 0, bytes.length);
    	}
    

    关于ClassLoader的Demo,里面对findClass和defineClass的编写了demo,用于理解双亲委派模型。

    展开全文
  • 1.关于类加载的loadClass()方法的讲解 loadClass()方法是ClassLoader类中的一个方法 loadClass()方法源码: protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { ...
  • loadClass,findClass,defineClass

    千次阅读 2018-04-22 10:28:35
    loadclass:判断是否已加载,使用双亲委派模型,请求父加载器,都为空,使用findclass findclass:根据名称或位置加载.class字节码,然后使用defineClass defineclass:解析定义.class字节流,返回class对象 load...
  • Unable to load class 'javax.xml.bind.JAXBException'. This is an unexpected error. Please file a bug containing the idea.log file. 谷歌查看,好像与JDK版本有关,要用JDK8才行,下载JDK8后,发现项目无法...
  • } } 解决方法二: 以下代码添加到:build.gradle —> dependencies { … } (添加依赖那块地方) 参考链接:Unable to load class ‘javax.xml.bind.JAXBException‘. 添加后可能出现的问题:(报 kapt有问题,改...
  • loadClass() findLoadedClass(String) 调用这个方法,查看这个Class是否已经别加载 如果没有被加载,继续往下走,查看父类加载器,递归调用loadClass() 如果父类加载器是null,说明是启动类加载器,查找对应的...
  • 解决问题 WARN util.NativeCodeLoader: Unable to ...Error: Failed to load class com.leo.sparkrdd.SparkRDDCalculateApp 解决思路 spark这个类,可能是打包的问题。 解决方法 执行命令的: spark-submit –class
  • Class.forName和ClassLoader.loadClass

    千次阅读 2019-04-27 16:13:13
    在上一节中讲到突破双亲委派模型的CurrentClassLoader和ContextClassLoader,接下来重点讲Class.forName和ClassLoader.loadClass ,众所周知它们都可以用来加载目标类,它们之间有一个小小的区别,那就是Class.for...
  • 这句的运行机制是这样的,如果loadClass()方法找不到需要被加载的类(这个代码示例是用huang.de.wei.Hello这个类当做被加载的类),则再到findClass()方法里面找。 如果  Class<?> clazz = ccl.findClass...
  • 装载:通过类的全限定名获取二进制字节流(二进制的class文件),将二进制字节流转换成方法区中的运行时数据结构,在内存中生成Java.lang.class对象。这个时候该类型没有被分配内存和没有设置默认值,也没有初始化。...
  • 要想搞清楚这两个方法的区别,我们需要了解一下Class的加载过程。Class的加载过程分为三步: loading(装载) linking(链接) initializing(初始化) 大家可以通过这篇文章:Java魔法堂:类加载机制入了个门来了解...
  • public class User { private String username; static { System.out.println("this is static block"); } public String getUsername() { return username; } public void setUsername(...
  • Unable to load class ‘javax.xml.bind.annotation.XmlSchema’. This is an unexpected error. Please file a bug containing the idea.log file. 在新版本的Android Studio上打开老项目出现这个问题。 修改了JDK...
  • LoadClass和forName的区别

    千次阅读 2019-04-08 16:38:22
    装载:通过累的全限定名获取二进制字节流,将二进制字节流转换成方法区中的运行时数据结构,在内存中生成Java.lang.class对象; 链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的; 校验:检查...
  • 为什么要把ClassLoader.loadClass(String name)和Class.forName(String name)进行比较呢,因为他们都能在运行时对任意一个类,都能够知道该类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。在...
  • Unable to load class

    千次阅读 2018-09-19 16:51:09
    Unable to load class: oracle.jdbc.driver.OracleDriver from ClassLoader:java.net.URLClassLoader   项目中原来是ojdbc14.jar,后来我将它换成了ojdbc6,之后报错无法加载oracle.jdbc.driver.OracleDriver...
  • springboot启动报错,java.lang.ClassNotFoundException: javax.servlet.Filter 方法一: 将pom文件中tomcat的依赖 将provided注释掉或者更改为compile 方法二: 将这4个更改为compile。
  • AndroidStudio报错:Unable to load class 'javax.xml.bind.JAXBException'. This is an unexpected error 原因:升级androidstudio4.2.1后,默认jdk的问题 解决方案修改为自己安装的jdk即可。
  • findClass()用于写类加载逻辑、loadClass()方法的逻辑里如果父类加载器加载失败则会调用自己的findClass()方法完成加载,保证了双亲委派规则。 1、如果不想打破双亲委派模型,那么只需要重写findClass方法...
  • 首先声明一下,我用的 Intellij IDEA 2018.3 版本的,springboot的版本是 2.0.5.RELEASE 版本。 当我喜滋滋的编写完测试...SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: D...
  • java源码解读之ClassLoader(loadClass方法)

    千次阅读 2017-03-05 17:53:20
    本篇文章仅仅只是对ClassLoader类的loadClass方法从源码上进行分析,至于跟类加载相关的双亲委托模式等其他知识点,不做介绍与阐述,因为网上大把介绍这些的文章,而且我不认为自己能写得比他们好 接下来又是跟之前...
  • 一些看到的博客总结:Java装载: 加载:类全限定名获取二进制字节流,将其转换为方法区中运行时数据结果,在内存生成java.lang.classclass文件字节码加载至内存,静态数据装换成运行时数据去中方法区的类型数据,...
  • ClassLoader.loadClass()与Class.forName()大家都知道是反射用来构造类的方法,但是他们的用法还是有一定区别的。  在讲区别之前,我觉得很有不要把类的加载过程在此整理一下。  在Java中,类装载器把一个类装入...
  • SLF4J: Failed to load class的问题及解决

    万次阅读 2018-08-12 05:29:37
    SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”. SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. pom做以下配置即可 &lt;!--日志--&gt; &...
  • Unable to load class 'com.google.common.collect.ImmutableSet'. Possible causes for this unexpected error include: Gradle's dependency cache may be corrupt (this sometimes occurs afte
  • C++静态加载问题:...另外有两个全局函数叫:StaticLoadObject()和StaticLoadClass(),应该是LoadObject()和LoadClass()的早期版本,前者需要手动强转,后者使用模版封装过,使用更方便,推荐使用后者 原文链接: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 892,880
精华内容 357,152
关键字:

LoadClass