Posts tagged ‘jboss’

Maven, Hibernate, Spring, CXF e MySql rodando no Jboss 7

Este post demonstra como usar de maneira prática o Hibernate com Spring publicando um Web Services utilizando com o Apache CXF, no Jboss 7 AS.

O primeiro passo é configurar o Maven, que irá auxiliar na automação do projeto. Acredito que é a parte mais complicada deste tutorial, já que encontrar todas as bibliotecas e dependências necessárias não é uma tarefa fácil. O pom.xml (arquivo de configuração do Maven) abaixo funciona perfeitamente para a configuração feita no nosso application-context.xml que você irá ver a seguir, você poderá fazer download da versão completa deste projeto no fim deste post.

...

	<dependencies>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate</artifactId>
			<version>3.2.1.ga</version>
			<exclusions>
				<exclusion>
					<groupId>asm</groupId>
					<artifactId>asm</artifactId>
				</exclusion>
				<exclusion>
					<groupId>asm</groupId>
					<artifactId>asm-attrs</artifactId>
				</exclusion>
				<exclusion>
					<groupId>cglib</groupId>
					<artifactId>cglib</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.8</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib-nodep</artifactId>
			<version>2.1_3</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-annotations</artifactId>
			<version>3.2.0.ga</version>
		</dependency>
		<dependency>
			<groupId>javax.persistence</groupId>
			<artifactId>persistence-api</artifactId>
			<version>1.0</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-simple</artifactId>
			<version>1.5.2</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>${servlet.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.unitils</groupId>
			<artifactId>unitils</artifactId>
			<version>1.0</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxws</artifactId>
			<version>${cxf.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http</artifactId>
			<version>${cxf.version}</version>
		</dependency>
	</dependencies>
...

Vamos começar a fazer nosso serviço que irá retornar informações sobre Clubes de Futebol. Vamos mapear o Bean referente a tabela TB_CLUBES.

package com.lucianosilva.lab.entity;

@Entity
@Table(name = "TB_CLUBES")
public class Clube implements BaseEntity<Long> {
	private static final long serialVersionUID = 5541457395540986982L;

	@Id
	@Column(name = "ID_CLUBE", nullable = false)
	private Long idClube;

	@Column(name = "NOME", nullable = true)
	private String nome;

	@Column(name = "NOME_POP", nullable = true)
	private String nomePopular;

	@Column(name = "FUNDACAO", nullable = true)
	private Date dataFundacao;

	/* (non-Javadoc)
	 * @see com.lucianosilva.lab.core.BaseEntity#getId()
	 */
	@Override
	public Long getId() {
		//
		return this.idClube;
	}

	/* (non-Javadoc)
	 * @see com.lucianosilva.lab.core.BaseEntity#setId(java.lang.Object)
	 */
	@Override
	public void setId(Long id) {
		//
		this.idClube = id;
	}

//... getters and setters
}

Agora podemos construir o acesso aos dados, que faz uso de Generic DAO ocultado neste post, não se preocupe é uma prática comum, no fim do post estão os arquivos para download.

Essa classe básicamente define o que vamos ter no serviço, duas operações de retorno filtrando pelo ID e Nome.

package com.lucianosilva.lab.dao;

public class ClubesDao extends HibernateGenericRepository<Clube, Long> {

	/* (non-Javadoc)
	 * @see com.lucianosilva.lab.repository.HibernateGenericRepository#findById(java.io.Serializable)
	 */
	@Override
	public Clube findById(Long id) {
		return super.findById(id);
	}

	public ClubesDao(){
		super(Clube.class);
	}

	/**
	 *
	 * @param name
	 * @return
	 */
	public List<Clube> findByName( String name ){
		return super.findByCriteria(Expression.like("nome", name, MatchMode.ANYWHERE));
	}
}

A definição deste serviço é tão simples quanto a construção do DAO acima, não foi feito o tratamento customizado das exceções já que o objetivo não é esse e, sim demonstrar a integração dos frameworks e como devem ser configurados, nada impede de você mesmo evoluir este código.

package com.lucianosilva.lab.webservices;

@WebService
public interface ClubeService {

	@WebMethod(operationName="ListAllClubes")
	@WebResult(name = "Clube")
	public List<Clube> listAll();

	@WebMethod(operationName="FindByClubeName")
	@WebResult(name = "Clube")
	public List<Clube> findByName(@WebParam(name = "clubeName") String name);

}

Implementação do serviço.

package com.lucianosilva.lab.webservices.impl;

import java.util.List;

import javax.jws.WebService;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.lucianosilva.lab.dao.ClubesDao;
import com.lucianosilva.lab.entity.Clube;
import com.lucianosilva.lab.webservices.ClubeService;

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
@WebService(endpointInterface="com.lucianosilva.lab.webservices.ClubeService")
public class ClubeServiceImpl implements ClubeService {

	private ClubesDao clubesDao; // configuracao no application-context

	public List<Clube> findByName(String name) {
		return clubesDao.findByName(name);
	}

	public List<Clube> listAll() {
		//
		return clubesDao.listAll();
	}

	/**
	 * @return the clubesDao
	 */
	public ClubesDao getClubesDao() {
		return clubesDao;
	}

	/**
	 * @param clubesDao the clubesDao to set
	 */
	public void setClubesDao(ClubesDao clubesDao) {
		this.clubesDao = clubesDao;
	}

}

Bem, até aqui nada de novo, pelo contrário tudo muito trivial. A configuração desta aplicação (application-context.xml) é o “pulo-do-gato”.

Adicionei comentários no bloco abaixo, para explicar cada parte da configuração.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:jaxrs="http://cxf.apache.org/jaxrs"
	xsi:schemaLocation="  

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-2.5.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-2.5.xsd

http://cxf.apache.org/core

http://cxf.apache.org/schemas/core.xsd

http://cxf.apache.org/jaxws

http://cxf.apache.org/schemas/jaxws.xsd

http://cxf.apache.org/jaxrs

http://cxf.apache.org/schemas/jaxrs.xsd"

	default-dependency-check="none" default-lazy-init="false">

	<!-- arquivo separado para a configuração dos EndPoints (WebServices) CXF veja mais abaixo -->
	<import resource="cxf-beans.xml" />

	<!-- Bean abstrato para evitar repetição de código -->
	<bean id="baseSessionFactory" abstract="true">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<!-- IoC - Implementação da interface ClubesDAO -->
	<bean id="clubesDao" class="com.lucianosilva.lab.dao.ClubesDao"
		parent="baseSessionFactory" />

        <!-- Configuração do DataSource para o Connection Pool - Este JNDI name está seguindo o padrão do JBoss -->
	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName">
			<value>java:/Laboratorio</value>
		</property>
	</bean>

	<!-- Configurações de uma Session Factories -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource">
			<ref local="dataSource" />
		</property>
		<property name="annotatedClasses">
			<list>
				<value>com.lucianosilva.lab.entity.Clube</value>
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLInnoDBDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">false</prop>
			</props>
		</property>
	</bean>
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
	</bean>
	<tx:annotation-driven transaction-manager="transactionManager" />
</beans>

Bem, lá no começo do application-context.xml fizemos o import da configuração do CXF, segue a descrição do arquivo cxf-beans.xml.

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<!-- Configurações do Apache CXF -->
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<!-- Configurações do endpoint WSDL -->
	<jaxws:endpoint id="clubeService" depends-on="clubeServiceImpl"
		implementor="#clubeServiceImpl" address="/ClubeService">
	</jaxws:endpoint>

	<!-- Bean que implementa o endpoint do nosso webservice -->
	<bean id="clubeServiceImpl" class="com.lucianosilva.lab.webservices.impl.ClubeServiceImpl">
		<property name="clubesDao" ref="clubesDao" />
	</bean>
</beans>

Compile, empacote e faça deploy no Jboss, agora vamos ver o serviço rodando no soapUI.

 

Por fim, você viu a configuração de um serviço simples, com acesso ao banco de dados utilizando DataSource, a qual considero importantíssimo como exemplo, já que NÍNGUEM utiliza a configuração do application-context informando os parâmetros do banco de dados (exceto para o uso do JUnit).

Você pode evoluir este código implementando o controle de erros com WebFault e também utilizando o Autowired no Spring, aumentando o controle da sua aplicação e diminuindo a configuração manual.

Download

 

Corrigindo problema do Jboss no Windows 7

Se você esta encarando o erro abaixo ao iniciar seu servidor Jboss no windows:

C:\jboss-5.1.0.GA\bin>run.bat
'findstr' is not recognized as an internal or external command,
operable program or batch file.

Traduzindo, o comando de sistema operacional findstr não foi reconhecido/encontrado.

O Windows 7 fez o favor de “esconder” algumas funcionalidades básicas do sistema operacional, tais como: ping e ipconfig. Se você esta acostumado em apenas digitar esses comandos no prompt, no Windows 7 é necessário modificar a variável de ambiente %path%.

Vá até Painel de Controle > Sistema > Configurações Avançadas > Variáveis de Ambiente
Acrescente o caminho ;%SYSTEMROOT%\System32;

Agora abra uma nova instância do prompt de comando, e faça o teste com ping e ipconfig.
Isto é o suficiente para que o servidor Jboss volte a funcionar normalmente.

Namastê.