Integrating Seam with Maven, Netbeans and GlassFish

本文介绍如何将使用Maven、NetBeans和GlassFish创建的应用迁移到Seam框架,包括EJB模块和WAR模块的迁移步骤。

The application that resulted from my previous article on Maven, Netbeans and GlassFish uses Hibernate for JPA and Facelets for JSF. This is an ideal situation to make the move to Seam. In the past few weeks I have spent some time on using Seam in GlassFish applications but I haven’t been very successful. However, the jpa example that is shipped with the Seam 2.0.0 GA distribution shows that working with Seam on Glassfish can be very simple. I just built the GlassFish war suing ant and deployed that war to GlassFish. The application just ran without any problems at all! Today I finally managed to build a Seam application for GlassFish. Moving that application to Maven then was very easy. This article will tell you how to do it.

I will assume that you have followed the instructions for creating a Maven enabled Hibernate/Facelets application in Netbeans. If you haven’t then that’s no problem. This article should provide you with enough hints to enable Seam on any Enterprise Application created with Netbeans.

....

Moving the EJB module to Seam

The number of jars that are needed to enable Seam on the EJB module is very very small: just 1. It is the jboss-seam.jar file. The reason only this jar is needed, is that the jars, that the jboss-seam.jar depends on, already have been installed into the GlassFish lib directory when we moved from Toplink Essentials to Hibernate. These jars are dom4j.jar, el-api.jar, hibernate-validator.jar and javassist.jar. Well, the el-api.jar file classes are actually contained in the GlassFish javaee.jar file. Besides these jars, the jboss-seam.jar file also depends on the jboss-el.jar file. We won’t need this jar for the application that we’ll build in this article, but you may want to include that jar anyway in case you’d want to use EL expressions in your entity classes.

Please note that I have updated the list of jars files needed for Hibernate in my previous article. You should now also copy the hibernate-validator.jar file from the Hibernate EntityManager distribution to the GlassFish lib directory. If you haven’t done so, please do it now!

Before we can make Maven download the seam jars, we need to add another repository to our pom.xml file. Since this repository will also be used by the WAR module, I have included it in the Parent Pom Module pom.xml file. The lines to add are these

        <repository>
<id>jboss.org</id>
<name>jboss.org</name>
<url>http://repository.jboss.com/maven2</url>
</repository>

Next, these lines in the EJB module pom.xml file will make Maven download the needed jars

        <dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-seam</artifactId>
<version>2.0.0.GA</version>
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
<exclusion>
<artifactId>el-api</artifactId>
<groupId>javax.el</groupId>
</exclusion>
<exclusion>
<artifactId>javassist</artifactId>
<groupId>jboss</groupId>
</exclusion>
</exclusions>
</dependency>

At this stage you may want to Clean And Build the project so the jars get downloaded and Netbeans is capable of locating the classes in the jars. Once done we can annotate our DataBean session bean with the @Name annotation. Besides that, we can switch over to Seam managed persistency instead of container managed persistency. This means that we need to replace the @PersistenceContext annotation with the @In annotation.

Besides that we’ll need to adjust the DataBean class to conform the Java Bean design guidelines. These guidelines state that Beans contain (private) member variables with getters and setters. To be able to keep on using the "countEmployees" call in our index.xhtml file, we’ll need to introduce a (private) int countEmployees and rename the countEmployees() method to getCountEmployees(). Please note that renaming the method in the DataBean class means that you’ll have to rename the countEmployees method definition in the DataLocal interface as well!

The final DataBean class looks like this

package nl.amis.maven.enterprise.ejb.session;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;

@Stateless
@Name("dataBean")
public class DataBean implements DataLocal {

@In EntityManager em;

private int countEmployees;

public int getCountEmployees() {
return em.createNamedQuery("Employees.getAll").getResultList().size();
}

}

That nearly completes the modifications that the EJB module needs. We only need to create two more files, one of which is empty, and modify our persistence.xml file. Lets start with the empty file.

Expand the Other Sources -> resources -> META-INF node. Right click the META-INF node and select New -> Other … and choose Properties File from the Other category. Name this file "seam" (without the queotes and without the .properties extension) and click Finish. This file will trigger Seam to initiate and load all classes and resources in the EJB module.

While we’re in this node, let’s create the second file. This file will be an XML file (New -> Other … and choose XML document from the XML Category) and name this file "ejb-jar". This file will contain some Seam specific interceptor definitions. The contents of this file should be

<?xml version="1.0" encoding="UTF-8"?>

<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee"
version = "3.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">

<interceptors>
<interceptor>
<interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor>
</interceptors>

<assembly-descriptor>
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
</assembly-descriptor>

</ejb-jar>

Finally, we need to modify the persistence.xml file to define Seam managed persistency. Double click the persistence.xml file in the META-INF node and make the contents look like this

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="MavenEnterpriseApplicationEjbPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>jdbc/hr</non-jta-data-source>
<properties/>
</persistence-unit>
</persistence>

Please note two important things. first of all, we switched from transaction type JTA to RESOURCE_LOCAL. This means that Seam will be in charge of the transactions etc. This means that we will need to modify our data source definition from jta-data-source to non-jta-data-source. Besides that I slightly modified the persistence-unit name. It was MavenEnterpriseApplication-ejbPU but unfortunately Seam won’t accept the dash ("-") in the name.

That’s it for the EJB module.

Moving the WAR module to Seam

Moving the WAR project to Seam also isn’t very complicated. First we need to include the needed dependencies in our pom.xml file. The WAR module needs two of them: jboss-seam-ui.jar and jboss-el.jar. Again, these two jars depend on several jars that already have been installed in the GlassFish lib dir, so we may exclude them. Add these lines to your pom.xml file

        <dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-seam-ui</artifactId>
<version>2.0.0.GA</version>
<exclusions>
<exclusion>
<artifactId>commons-beanutils</artifactId>
<groupId>commons-beanutils</groupId>
</exclusion>
<exclusion>
<artifactId>dom4j</artifactId>
<groupId>dom4j</groupId>
</exclusion>
<exclusion>
<artifactId>el-api</artifactId>
<groupId>javax.el</groupId>
</exclusion>
<exclusion>
<artifactId>javassist</artifactId>
<groupId>jboss</groupId>
</exclusion>
<exclusion>
<artifactId>jboss-seam</artifactId>
<groupId>org.jboss.seam</groupId>
</exclusion>
<exclusion>
<artifactId>jsf-api</artifactId>
<groupId>javax.faces</groupId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-el</artifactId>
<version>2.0.0.GA</version>
<exclusions>
<exclusion>
<artifactId>el-api</artifactId>
<groupId>javax.el</groupId>
</exclusion>
</exclusions>
</dependency>

Clean and Build the project so the jars get downloaded. Doing so will make Maven resolve all dependencies. This will make Maven see that the EJB module depends on jboss-seam.jar and this library will show up in the list. however, this jar is not needed here. If you like you can exclude it by adding these lines to the EJB modulle dependency in the WAR module pom.xml file

            <exclusions>
<exclusion>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-seam</artifactId>
</exclusion>
</exclusions>

Since Seam will be in charge on injecting (and outjecting) bean references, we won’t need the Managed Bean reference in the faces-config.xml file anymore. So, expand the Web Pages -> WEB-INF node and remove the managed bean code from the faces-config.xml file. For Seam to be able to resolve the bean references correctly, the web.xml file also needs to be modified. Open the file and add these lines at the top of the file

    <listener>
<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>

Finally, Seam needs another configuration file called components.xml. This file will, among onther things, enable Seam to setup the persistence unit and to find the session bean in our EJB module. Simply create another XML Document in the WEB-INF directory and name it "components". This is the components.xml file I stole from the Seam jpa example

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:persistence="http://jboss.com/products/seam/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd
http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.0.xsd
http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd">

<persistence:entity-manager-factory name="MavenFaceletsSeamEjbPU"/>

<persistence:managed-persistence-context name="em"
auto-create="true"
entity-manager-factory="#{MavenFaceletsSeamEjbPU}"/>

<core:init jndi-pattern="java:comp/env/#{ejbName}" />

</components>

Please note that the persistence name should be the same as in the persistence.xml file in your EJB module. Besides that, Seam won’t be able to resolve the JNDI names of session beans on GlassFish. I’m not sure why this is so, but Seam NEEDS the jndi-pattern line. The pattern can be anything you like. For me the "java:comp/env/#{ejbName}" pattern will make the DataBean bean be registered under the JNDI name "java:comp/env/DataBean" as this GlassFish log shows

Component: org.jboss.seam.core.init, scope: APPLICATION, type: JAVA_BEAN, class: org.jboss.seam.core.Init
Installing components…
Component: MavenEnterpriseApplicationEjbPU, scope: APPLICATION, type: JAVA_BEAN, class: org.jboss.seam.persistence.EntityManagerFactory
Component: dataBean, scope: STATELESS, type: STATELESS_SESSION_BEAN, class: nl.amis.maven.enterprise.ejb.session.DataBean, JNDI: java:comp/env/DataBean
Component: em, scope: CONVERSATION, type: JAVA_BEAN, class: org.jboss.seam.persistence.ManagedPersistenceContext

There is one more catch to resolve. Since our session bean is packaged in a jar file, the reference to the bean needs to be made explicit in web.xml. This can be done with a "ejb-local-ref" element like this

    <ejb-local-ref>
<ejb-ref-name>DataBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>nl.amis.maven.enterprise.ejb.session.DataLocal</local>
</ejb-local-ref>

That’s it! The ejb-ref-name element makes sure that the "#{ejbName}" part in the jndi-pattern line in the components.xml file is referring to the right value. Please note that this needs to be done for ALL beans that are packaged in the EJB module jar and that need to be references from your xhtml pages. That was easy right?

O wait, one more thing and then we’re finished. Promise. We need to modify the index.xhtml file to make use of the DataBean bean instead of the NumberBackingBean. So, open the index.xhtml file and modify the EL expression to

#{dataBean.countEmployees}

Once more rebuild the application and now fire the exec:exec goal on the EAR module. Once your application has been deployed, browse to e.g. http://localhost:8280/MavenEnterpriseApplication-war/index.jsf and you should once more see

gf_mvn_nb6-result_in_facelets_page.jpg

Next steps

Since Seam now is in charge of the transaction and Entity Manager management, the Hibernate jars are no longer needed in the GlassFish lib directory. You may remove them and then restart GlassFish. This will mean that you need to deploy those jars with your application. This, of course, can be done by modifying the pom.xml files and add the correct dependencies. To do this, I used the list below in the EJB pom.xml and made no modifications to the WAR pom.xml file. Please note that the list below only replaces the Hibernate dependencies. No modifications are needed for the Seam dependencies. Adding the dependencies to the EJB pom.xml will make Maven include the jars both in the EJB jar and in the WAR thus making sure that both modules have the jars they need. It would help to clean up the redundant jars but I’ll leave that up to you to do Smiley

    <dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.5.ga</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.3.0.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.3.0.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.1.ga</version>
<exclusions>
<exclusion>
<artifactId>jboss-common-core</artifactId>
<groupId>jboss</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>3.0.0.ga</version>
</dependency>
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-attrs</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_3</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
<exclusions>
<exclusion>
<artifactId>avalon-framework</artifactId>
<groupId>avalon-framework</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>logkit</artifactId>
<groupId>logkit</groupId>
</exclusion>
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>concurrent</groupId>
<artifactId>concurrent</artifactId>
<version>1.3.4</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
<exclusions>
<exclusion>
<artifactId>xml-apis</artifactId>
<groupId>xml-apis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>jboss</groupId>
<artifactId>javassist</artifactId>
<version>3.3.ga</version>
</dependency>
<dependency>
<groupId>jboss</groupId>
<artifactId>jboss-archive-browsing</artifactId>
<version>5.0.0alpha-200607201-119</version>
</dependency>
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>ejb-api</artifactId>
<version>3.0</version>
<scope>provided</scope>
</dependency>


### 动态图表示中的对比学习用于金融市场预测 在金融市场的背景下,动态图表示通过捕捉随时间变化的关系来提供更丰富的数据结构。为了有效利用这些信息并进行市场预测,研究者提出了基于对比学习的方法[^1]。 #### 对比学习框架概述 对比学习是一种自监督的学习方法,在该领域内被广泛应用于图像识别等领域之外也取得了成功应用案例。对于动态网络而言,这种方法可以通过最大化同一节点不同时间戳下的相似度以及最小化不同时刻间其他节点之间的关联程度来进行训练模型参数调整优化过程[^2]。 ```python import torch from torch_geometric.nn import GCNConv, global_mean_pool as gap class ContrastiveLearningModel(torch.nn.Module): def __init__(self, input_dim, hidden_channels, out_channels): super(ContrastiveLearningModel, self).__init__() # 定义GCN层和其他必要的组件... def forward(self, x_t0, edge_index_t0, batch_t0, x_t1, edge_index_t1, batch_t1): z_t0 = ... # 计算t时刻特征向量z(t) z_t1 = ... # 同样计算下一个时间段内的特征 return z_t0, z_t1 def loss_function(z_i, z_j): temperature = 0.5 N = ... nominator = ... denominator = ... loss = -torch.log(nominator / denominator).mean() return loss ``` 此代码片段展示了如何构建一个简单的对比学习架构,并定义了一个损失函数用来衡量两个时间节点上相同实体之间表征的一致性和差异性[^3]。 #### 整合时间和静态关系 当涉及到具体实现时,除了考虑时间维度上的演化特性外,还需要关注那些相对稳定不变的因素——即所谓的“静态关系”。这可能包括但不限于公司间的长期合作关系、行业内部的竞争格局等。因此,在设计算法过程中应当充分考虑到这两方面因素的影响: - **时间序列建模**:采用循环神经网络(RNNs),长短记忆单元(LSTMs) 或者 Transformer 结构处理连续的时间步长输入; - **多尺度融合机制**:引入注意力机制或其他形式的信息聚合手段,使得模型能够更好地理解局部与全局模式之间的联系; 综上所述,通过对动态图表征学习的研究可以为金融市场分析提供更多可能性。然而值得注意的是实际操作中还需面对诸如噪声干扰等问题挑战[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值