【问题标题】:How do I use the spring jars in my liferay portlet instead of the spring jars in the ROOT\WEB-INF\lib?如何在我的 liferay portlet 中使用 spring jars 而不是 ROOT\WEB-INF\lib 中的 spring jars?
【发布时间】:2015-09-01 16:29:17
【问题描述】:

我创建了一个 portlet,并尝试在其中使用 spring jpa 进行数据检索。我正在使用 Spring 版本 3.2.14,并且我需要的 spring jar 部署在我的 portlet 的 WEB-INF/lib 文件夹中。

在启动 tomcat 时,我不断收到以下异常:

Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'packagesToScan' of bean class [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Bean property 'packagesToScan' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1052)
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:921)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
    ... 39 more

如果我将调试器附加到 Tomcat,我可以看到它使用的是 ROOT/WEB-INF/lib 中的 spring-beans.jar(版本 3.0.7.RELEASE),它在 'packageToScan' 中存在已知问题我的 bean 定义中的 LocalContainerEntityManagerFactoryBean:

<bean id="reportingEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
        <list>
            <value>org.preptoolkit.exercise.reporting.model</value>
        </list>     
    </property>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true" />
            <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
        </bean>
    </property>
</bean>

我已经尝试将 spring-beans-3.2.14.RELEASE.jar 放入 $tomcat_home/lib/ext 并且 liferay 仍然使用 3.0.7 版本。

Liferay 版本:6.2-ce-ga4

那么如何让 Liferay 使用 spring-beans-3.2.14.RELEASE.jar 而不是我的 portlet 的一个 ROOT?

(我已经在这堵墙上敲了 3 天)

更新

这是完整的堆栈跟踪:

13:26:55,702 ERROR [localhost-startStop-1][ContextLoader:206] Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportingEntityManagerFactory' defined in ServletContext resource [/WEB-INF/classes/persistenceContext.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'packagesToScan' of bean class [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Bean property 'packagesToScan' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1363)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1085)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:516)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:455)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:282)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:204)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
    at com.liferay.portal.spring.context.PortletContextLoaderListener.contextInitialized(PortletContextLoaderListener.java:85)
    at com.liferay.portal.deploy.hot.SpringHotDeployListener.doInvokeDeploy(SpringHotDeployListener.java:85)
    at com.liferay.portal.deploy.hot.SpringHotDeployListener.invokeDeploy(SpringHotDeployListener.java:41)
    at com.liferay.portal.deploy.hot.HotDeployImpl.doFireDeployEvent(HotDeployImpl.java:227)
    at com.liferay.portal.deploy.hot.HotDeployImpl.fireDeployEvent(HotDeployImpl.java:96)
    at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil.java:28)
    at com.liferay.portal.kernel.servlet.PluginContextListener.fireDeployEvent(PluginContextListener.java:164)
    at com.liferay.portal.kernel.servlet.PluginContextListener.doPortalInit(PluginContextListener.java:154)
    at com.liferay.portal.kernel.util.BasePortalLifecycle.portalInit(BasePortalLifecycle.java:44)
    at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:74)
    at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:58)
    at com.liferay.portal.kernel.util.BasePortalLifecycle.registerPortalLifecycle(BasePortalLifecycle.java:54)
    at com.liferay.portal.kernel.servlet.PluginContextListener.contextInitialized(PluginContextListener.java:116)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1113)
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1671)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'packagesToScan' of bean class [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Bean property 'packagesToScan' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1052)
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:921)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
    ... 39 more

【问题讨论】:

  • @Tobias 你是对的。我尝试了我的 portlets WEB-INF/lib 文件夹。
  • 您的 portlet 应用程序是否也可能是一个钩子?在这种情况下,Liferay 的 Spring 也可能会尝试加载您的应用程序。但由于我目前没有使用 Spring 的 portlet 项目,因此无法对其进行测试。我只能说,通常来自 ROOT Web 应用程序的库在任何 Portlet Web 应用程序中都不可见。也许您可以添加完整的堆栈跟踪?
  • 已添加。检查我的 portlet 是否是 liferay hook...
  • 我在项目中有一个liferay-hook.xml。我删除了它并重新部署了该应用程序,但仍然遇到同样的问题。
  • 堆栈跟踪有帮助(见下文)

标签: spring tomcat liferay


【解决方案1】:

有一个SpringHotDeployListener 尝试为每个 portlet 应用程序初始化 Spring(使用 Liferay 的库)。

要为您的 web 应用关闭此功能,您必须删除 portal-ext.properties 中属性 hot.deploy.listeners 中的 com.liferay.portal.deploy.hot.SpringHotDeployListener

如果您使用其他使用 Liferay Spring 环境的 portlet 应用程序,您需要创建一个 Ext Plugin 并在 ext-impl 中扩展 SpringHotDeployListener

public class MySpringHotDeployListener extends SpringHotDeployListener {
    protected void doInvokeDeploy(HotDeployEvent hotDeployEvent) throws Exception {
        if (!hotDeployEvent.getServletContext().getServletContextName().equals("MyContextName")) {
            super.doInvokeDeploy(hotDeployEvent);
        }
    }

    // Same for doInvokeUndeploy
}

然后在portal-ext.properties 中使用MySpringHotDeployListener 而不是SpringHotDeployListener

【讨论】:

  • 托拜厄斯你是个天才!! SpringHotDeployListener 肯定会阻止我在 portlet 的 WEB-INF 目录中拥有的 spring jars/implementation。
  • 知道如何使用我的 WEB-INF/lib 中的 spring jar 来初始化我的 portlet?我能够初始化和使用我的 Spring 存储库和服务,但现在我的 portlet 没有呈现...
  • 可能是 Liferay 需要 Spring 集成以某种方式与 portlet 通信 - 所以也许您需要更改您的 MySpringHotDeployListener 以仅包含您的 portlet 应用程序的 PortletContextLoaderListener 实现的一部分。 .
猜你喜欢
  • 2018-01-26
  • 2021-06-30
  • 2018-02-24
  • 2018-09-22
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
相关资源
最近更新 更多