Liferay服务构建器JNDI查找使用错误的命名上下文

时间:2015-02-02 18:08:27

标签: spring tomcat jndi liferay-6 contextclassloader

我有一个通过JNDI配置的servicebuilder portlet:

<Context antiJARLocking="true" useHttpOnly="true">
  <ResourceLink name="app/url" global="my-app/app/url"
    type="java.lang.String" />
</Context>

在我的ext-spring.xml中,我尝试使用以下方法提取该值:

<jee:jndi-lookup jndi-name="java:comp/env/app/url" />

但是,用于查看此值的InitialContext似乎是InitialContext webapp(liferay本身)的ROOT,因为它包含的唯一内容是{ {1}}数据库连接池。我知道JNDI上下文与java:comp/env/jdbc/LiferayPool确定的关联:

ClassLoader

我知道在运行portlet初始化之前,使用类加载器生活。但是,对于我的生活,我不能弄清楚如何解决这个问题。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

我为您提供了一个有效的解决方案,但它与您在帖子中描述的内容略有不同。

首先,我建议你将JNDI的声明移到Tomcat的 server.xml ,特别是&lt; GlobalNamingResources&gt; 标记。

以下是一个例子:

<GlobalNamingResources>
<!-- Editable user database that can also be used by
     UserDatabaseRealm to authenticate users
-->
<Resource
   name="jdbc/CustomDBPoolShared"
   auth="Container"
   type="javax.sql.DataSource"
   factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
   driverClassName="oracle.jdbc.OracleDriver"
   url="jdbc:oracle:thin:@YOUR_SERVER:1521:YOUR_SERVICE"
   username="USERNAME"
   password="PASSWORD"
   maxActive="20"
   maxIdle="5"
   maxWait="10000"
/>
......
</GlobalNamingResources>

之后你应该在 context.xml 中创建 ResourceLink

<Context>

<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>

<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->

<!-- Uncomment this to enable Comet connection tacking (provides events
     on session expiration as well as webapp lifecycle) -->
<!--
<Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-->
<ResourceLink name="jdbc/CustomDBPool" global="jdbc/CustomDBPoolShared" type="javax.sql.DataSource"/>
....
</Context>

如果你有两个portlet访问同一个数据库,这将帮助你处理并发访问。

最后,ext-spring.xml:

   <!-- Custom Beans -->
<bean id="digitalHibernateSessionFactory" class="com.liferay.portal.spring.hibernate.PortletHibernateConfiguration" lazy-init="true">
    <property name="dataSource">
        <ref bean="customDBDataSource"/>
    </property>
</bean>
<bean id="customDBSessionFactory" class="com.liferay.portal.dao.orm.hibernate.SessionFactoryImpl" lazy-init="true">
    <property name="sessionFactoryImplementor">
        <ref bean="digitalHibernateSessionFactory" />
    </property>
</bean>
<bean id="customDBDataSourceTarget" class="com.liferay.portal.spring.jndi.JndiObjectFactoryBean" lazy-init="true">
    <property name="jndiName">
        <value>jdbc/customDBPool</value>
    </property>
</bean>
<bean id="customDBDataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy" lazy-init="true">
    <property name="targetDataSource">
        <ref bean="customDBDataSourceTarget" />
    </property>
</bean>

注意                                                                                                             JDBC / customDBPool                                                       

请注意 jdbc / customDBPool ,它在 context.xml 中描述,不仅适用于ROOT类加载器。

最后,您应该在LiferayServiceBuilder的service.xml中引用正确的dataSource:

<entity name="MyCustomEntity" table="CUSTOM_ENTITY" local-service="true" remote-service="false" data-source="customDBDataSource" session-factory="customDBSessionFactory" cache-enabled="false">
.....
</entity>