将 IProductComponent 转换为具体产品时,faktor ips ClassCastException

faktor ips ClassCastException when casting IProductComponent to concrete product

我正在使用 Linkki 为 faktor ips 项目创建 UI。我有一个 View class,我在其中添加了以下页面以显示它:

//imports...
public class TestPage extends AbstractPage{

    private static final long serialVersionUID = 1L;
    
    private BindingManager bindingmanager;
    private List<KfzProdukt> produktList;
    
    
    public TestPage() {
        this.bindingmanager = new DefaultBindingManager(ValidationService.NOP_VALIDATION_SERVICE);
        this.produktList= setProduktList();
    }

    @Override
    public void createContent() {
        addSection(new showDetailsPmo(produktList));
    }

    @Override
    protected BindingManager getBindingManager() {
        return bindingmanager;
    }

    public List<KfzProdukt> setProduktList() {
        ClassloaderRuntimeRepository runtimeRepository = ClassloaderRuntimeRepository.create(
                "org/.../faktorips-repository-toc.xml");
        runtimeRepository.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
        return runtimeRepository.getAllProductComponents(KfzProdukt.class);
    }
}

faktorips-repository-toc.xml 看起来像这样:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<FaktorIps-TableOfContents productDataVersion="0.0.1" xmlversion="3.0">
 <ProductComponent implementationClass="org.faktorips.beispiel.model.kfz.KfzProdukt" ipsObjectId="Kfz.NormalVertrag 2022-01" ipsObjectQualifiedName="produkte.NormalVertrag 2022-01" kindId="Kfz.NormalVertrag" versionId="2022-01" xmlResource="org/faktorips/beispiel/model/produkte/NormalVertrag 2022-01.xml"/>
 <ProductComponent implementationClass="org.faktorips.beispiel.model.kfz.KfzHaftpflichtdeckungsTyp" ipsObjectId="Kfz.Haftpflicht 2022-01" ipsObjectQualifiedName="deckungen.Haftpflicht 2022-01" kindId="Kfz.Haftpflicht" versionId="2022-01" xmlResource="org/faktorips/beispiel/model/deckungen/Haftpflicht 2022-01.xml"/>
 <ProductComponent implementationClass="org.faktorips.beispiel.model.kfz.KfzAssistancedeckungsTyp" ipsObjectId="Kfz.Teilkasko 2022-01" ipsObjectQualifiedName="deckungen.Teilkasko 2022-01" kindId="Kfz.Teilkasko" versionId="2022-01" xmlResource="org/faktorips/beispiel/model/deckungen/Teilkasko 2022-01.xml"/>
 <ProductComponent implementationClass="org.faktorips.beispiel.model.kfz.KfzAssistancedeckungsTyp" ipsObjectId="Kfz.Vollkasko 2022-01" ipsObjectQualifiedName="deckungen.Vollkasko 2022-01" kindId="Kfz.Vollkasko" versionId="2022-01" xmlResource="org/faktorips/beispiel/model/deckungen/Vollkasko 2022-01.xml"/>
 <!-- a few  <PolicyCmptType...> entries -->
 <ProductCmptType implementationClass="org.faktorips.beispiel.model.kfz.KfzAssistancedeckungsTyp" ipsObjectId="kfz.KfzAssistancedeckungsTyp" ipsObjectQualifiedName="kfz.KfzAssistancedeckungsTyp"/>
 <ProductCmptType implementationClass="org.faktorips.beispiel.model.kfz.KfzHaftpflichtdeckungsTyp" ipsObjectId="kfz.KfzHaftpflichtdeckungsTyp" ipsObjectQualifiedName="kfz.KfzHaftpflichtdeckungsTyp"/>
 <ProductCmptType implementationClass="org.faktorips.beispiel.model.kfz.KfzProdukt" ipsObjectId="kfz.KfzProdukt" ipsObjectQualifiedName="kfz.KfzProdukt"/>
</FaktorIps-TableOfContents>

当我 运行 应用程序时它没有崩溃,但 List<KfzProdukt> produktList 是空的。 runtimeRepository.getAllProductComponents(KfzProdukt.class)方法中的setProduktList() return是一个空的List,这个我看不懂,因为按照我的理解,应该是return一个只有一个元素的list( faktorips-repository-toc.xml).

中的第一个条目

我试图通过专门检索它来获取所述产品。我在方法 setProduktList() 中添加了两行,如下所示:

public List<KfzProdukt> setProduktList() {
        ClassloaderRuntimeRepository runtimeRepository = ClassloaderRuntimeRepository.create(
                "org/faktorips/beispiel/model/internal/faktorips-repository-toc.xml");
        runtimeRepository.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
        
        IProductComponent productComponent = runtimeRepository.getProductComponent("Kfz.NormalVertrag 2022-01");
        KfzProdukt x = (KfzProdukt) productComponent;
        
        return runtimeRepository.getAllProductComponents(KfzProdukt.class);
    }

然后我在 KfzProdukt x = (KfzProdukt) productComponent; 行收到以下错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.likki.fips.kfzlinkki.view.DetailsView': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.likki.fips.kfzlinkki.view.DetailsView]: Constructor threw exception; nested exception is java.lang.ClassCastException: class org.faktorips.beispiel.model.kfz.KfzProdukt cannot be cast to class org.faktorips.beispiel.model.kfz.KfzProdukt (org.faktorips.beispiel.model.kfz.KfzProdukt is in unnamed module of loader 'app'; org.faktorips.beispiel.model.kfz.KfzProdukt is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @6dbef9d8)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:315) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:296) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:332) ~[spring-beans-5.3.18.jar:5.3.18]
    at com.vaadin.flow.spring.SpringInstantiator.getOrCreate(SpringInstantiator.java:117) ~[vaadin-spring-23.0.3.jar:na]
    at com.vaadin.flow.di.Instantiator.createRouteTarget(Instantiator.java:193) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.lambda$getRouteTarget(AbstractNavigationStateRenderer.java:135) ~[flow-server-23.0.3.jar:23.0.3]
    at java.base/java.util.Optional.orElseGet(Optional.java:369) ~[na:na]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.getRouteTarget(AbstractNavigationStateRenderer.java:134) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.sendBeforeEnterEventAndPopulateChain(AbstractNavigationStateRenderer.java:488) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.createChainIfEmptyAndExecuteBeforeEnterNavigation(AbstractNavigationStateRenderer.java:469) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.handle(AbstractNavigationStateRenderer.java:207) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.component.internal.JavaScriptNavigationStateRenderer.handle(JavaScriptNavigationStateRenderer.java:79) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.component.internal.JavaScriptBootstrapUI.handleNavigation(JavaScriptBootstrapUI.java:317) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.component.internal.JavaScriptBootstrapUI.renderViewForRoute(JavaScriptBootstrapUI.java:280) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.component.internal.JavaScriptBootstrapUI.connectClient(JavaScriptBootstrapUI.java:147) ~[flow-server-23.0.3.jar:23.0.3]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at com.vaadin.flow.server.communication.rpc.PublishedServerEventHandlerRpcHandler.invokeMethod(PublishedServerEventHandlerRpcHandler.java:222) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.communication.rpc.PublishedServerEventHandlerRpcHandler.invokeMethod(PublishedServerEventHandlerRpcHandler.java:199) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.communication.rpc.PublishedServerEventHandlerRpcHandler.invokeMethod(PublishedServerEventHandlerRpcHandler.java:149) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.communication.rpc.PublishedServerEventHandlerRpcHandler.handleNode(PublishedServerEventHandlerRpcHandler.java:132) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:71) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:438) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations(ServerRpcHandler.java:419) ~[flow-server-23.0.3.jar:23.0.3]
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) ~[na:na]
    at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:419) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:320) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:115) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1567) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:299) ~[flow-server-23.0.3.jar:23.0.3]
    at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:109) ~[vaadin-spring-23.0.3.jar:na]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.60.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:711) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:353) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:313) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:51) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.60.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.18.jar:5.3.18]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.60.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.18.jar:5.3.18]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.18.jar:5.3.18]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.likki.fips.kfzlinkki.view.DetailsView]: Constructor threw exception; nested exception is java.lang.ClassCastException: class org.faktorips.beispiel.model.kfz.KfzProdukt cannot be cast to class org.faktorips.beispiel.model.kfz.KfzProdukt (org.faktorips.beispiel.model.kfz.KfzProdukt is in unnamed module of loader 'app'; org.faktorips.beispiel.model.kfz.KfzProdukt is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @6dbef9d8)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:311) ~[spring-beans-5.3.18.jar:5.3.18]
    ... 87 common frames omitted
Caused by: java.lang.ClassCastException: class org.faktorips.beispiel.model.kfz.KfzProdukt cannot be cast to class org.faktorips.beispiel.model.kfz.KfzProdukt (org.faktorips.beispiel.model.kfz.KfzProdukt is in unnamed module of loader 'app'; org.faktorips.beispiel.model.kfz.KfzProdukt is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @6dbef9d8)
    at org.likki.fips.kfzlinkki.page.TestPage.setProdukte(TestPage.java:50) ~[classes/:na]
    at org.likki.fips.kfzlinkki.page.TestPage.<init>(TestPage.java:28) ~[classes/:na]
    at org.likki.fips.kfzlinkki.view.DetailsView.<init>(DetailsView.java:32) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) ~[na:na]
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211) ~[spring-beans-5.3.18.jar:5.3.18]
    ... 89 common frames omitted

我不明白这一点,因为我没有尝试将 KfzProdukt 转换为 KfzProdukt(因为如果它们已经是同一件事,我为什么要这样做)。我想将 IProductComponent 转换为 KfzProdukt

有人可以给我解释一下吗?

我不是 100% 确定这里发生了什么,但 ClassCastException 似乎指向 Spring Devtools 中的 org.springframework.boot.devtools.restart.classloader.RestartClassLoader。显然,它重新加载 class org.faktorips.beispiel.model.kfz.KfzProdukt 已经由 'app' class 加载程序加载。您可以尝试禁用重新加载,如 Whosebug 问题中所述:Class loader error - unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader.

这也可以解释为什么 runtimeRepository.getAllProductComponents(KfzProdukt.class) returns 是一个空列表,因为它使用的 KfzProdukt class 不一样(由不同的 [ 加载) =20=]loader) 比存储库中的那个。