SetupMyProject open source!

Um pouco depois do meio do ano passado, foi lançado o SetupMyProject. De lá para cá podemos dizer que ele tem caminhado bem, já temos mais de 5000 downloads dos mais variados tipos de projetos. A ideia do SetupMyProject é facilitar a criação de novos projetos Java usando alguns dos frameworks mais conhecidos, como:

  1. Spring e Spring MVC
  2. Spring Boot
  3. VRaptor 4
  4. JSF 2.2
  5. JAX-RS(RestEasy)

Como a aceitação tem sido muito boa, achamos que um bom próximo passo era deixá-lo open source, e foi justamente isso que fizemos. Ele está disponível no github e todo mundo está convidado para ver nossas gambiarras, acertos e, se possível, contribuir para deixarmos o projeto ainda melhor. Tentei deixar o readme o mais convidativo possível, para que você baixe e tente até rodar na sua máquina.

Outro ponto que é legal de comentar é sobre a arquitetura do projeto, não é nada de outro mundo, mas vou deixar aqui registrado.

  1. Linguagem : Java
  2. Framework MVC : Spring MVC
  3. Spring Boot para facilitar setup e utilização de plugins do Spring
  4. ORM : Hibernate(bem pouca coisa para ser sincero)
  5. Engine para geração dos projetos : JBoss Forge 2

Olhando as tecnologias, tirando o JBoss Forge, não tem nada fora do normal. Além disso, pensando em design de código mesmo, tem bastante coisa legal. Usamos o Design Pattern Command para abstrair os passos necessários para geração de um projeto, além de um grafo ordenado, roubado do VRaptor 3, para que um comando possa informar se deve ser executado antes ou depois de outro. Da uma olhada, acho que você pode gostar :).

Caso você já tenha usado o SetupMyProject, gostaria de te pedir um pequeno favor, vai lá no github e da aquela estrela para gente :). É um jeito de sabermos o quanto a comunidade gostou e também é uma forma de incentivo. Outro ponto importante, vamos adorar que o maior número possível de issues sejam abertas. Tem um projeto que gostaria de gerar, ou algum plugin a mais que você quer ver configurado na geração do setup, nos avise por lá :).

 

 

 

Advertisements

[OFF-TOPIC] Geração de CRUDs automática no SetupMyProject

Ontem colocamos no ar uma nova versão do SetupMyProject. A maior novidade é que agora você tem a possibilidade de gerar o seu projeto já com um cadastro completo de qualquer entidade que você queira, os famosos CRUDs. Todos nós sabemos fazer um CRUD, isso não é segredo, o problema é o tempo que perdemos para fazer o trabalho. Criar as telas, entidades, daos e validações consomem um certo tempo. Todo o processo é realizado online, como já acontece atualmente, não queremos que você precise instalar nem configurar nada para ter acesso a funcionalidade.

Um decisão que tivemos que tomar foi: como o usuário vai entrar com os dados necessários para que nós possamos gerar o cadastro dele? Com certeza esse não foi um caminho fácil de ser decidido, mas por hora ficamos com a opção da escrita de um xml .

    <models>
	  <model name="Product">
		  <field name='name' type='java.lang.String'/>
		  <field name='description' type='java.lang.String' />
		  <field name='price' type='java.math.BigDecimal' />
       </model>
    </models>

No exemplo acima, solicitamos a geração de um cadastro para uma classe chamada Product e, além disso, especificamos quais são os atributos e tipos que queremos para ela. Para facilitar a escrita do xml, criamos uma documentação no github, além de fazer a validação do xml com um xsd para garantir que a estrutura mínima foi obedecida. Dá para ir um pouco além e gerar cadastros mais completos.

      <models>
         <model name="Product">
		   <field name='name' type='java.lang.String'/>
		   <field name='description' type='java.lang.String' />
		   <field name='price' type='java.math.BigDecimal' />
		   <field name='category' type='Category' javaType='false' formInputType="select" formInputName='category.id' selectLabelField="name" />
         </model>
         <model name="Category">
	        <field name='name' type='java.lang.String' />
	        <field name='description' type='java.lang.String' />
         </model>
      </models>

Na situação acima é informado a necessidade de dois cadastros. Especificamente na tela de produtos, informamos que queremos um select para que o usuário possa escolher a categoria do produto.  Perceba que para as entidades específicas do usuário não é necessário especificar o nome completo da classe, já que ela vai ficar em um pacote chamado models, relativo ao pacote base do projeto. Por exemplo, br.com.empresa.novoprojeto.models.Category. Um próximo passo é suportar que seja gerado uma relação do tipo oneToMany, já que por enquanto a geração automática só suporta relações do tipo ManyToOne. 

Por fim, existem situações onde não queremos a geração de um controller e uma view para cadastro, é o caso de uma entidade do tipo Checkout num sistema de e-commerce. Geralmente esse objeto é gerado a partir de um carrinho de compras. Para esse tipo de situação, basta que seja adicionado o atributo viewController.

      <models>
         <model name="Product">
	       <field name='name' type='java.lang.String'/>
	       <field name='description' type='java.lang.String' />
	       <field name='price' type='java.math.BigDecimal' />
	       <field name='category' type='Category' javaType='false' formInputType="select" formInputName='category.id' selectLabelField="name" />
        </model>
        <model name="Category">
	        <field name='name' type='java.lang.String'/>
	        <field name='description' type='java.lang.String' />
        </model>
        <model name="User">
	        <field name='login' type='java.lang.String'/>
	        <field name='password' type='java.lang.String' />
        </model>
		<model name="Checkout" viewController="false">
	        <field name='value' type='java.math.BigDecimal'/>
	        <field name='user' type='User' javaType="false" />
		</model>
     </models>

Como não poderia deixar de ser, as opções de projetos com SpringMVC direto e Spring Boot já suportam a geração de CRUDs. Ficaremos muito felizes se vocês puderem ir lá e testar :). Aproveitando o espaço, também geramos cadastros para projetos baseados em JSF 2.2 e VRaptor 4, tem para todo gosto. Um último toque que adicionamos foi a geração do readme do projeto, para os passos finais de configuração dos plugins que foram selecionados :).

Para tentar ficar mais perto do desenvolvimento do projeto, e não só do começo, a nossa próxima feature é que você consiga gerar configurações de plugins, ou cadastros adicionais, para projetos que já estão em andamento!

Spring Security, Spring JPA e o JAVAEE

Quando pensamos em adicionar a parte de segurança dentro da nossa aplicação, a primeira solução que vem a nossa cabeça é usar o Spring Security. Por sinal é um pensamento que faz todo sentido, já que hoje em dia ele é o projeto de segurança mais completo do mercado. Só que quando estamos no mundo JAVAEE, já existe uma especificação responsável por essa área, a JAAS. Colocando as duas lado a lado, não é complexo perceber que o Spring Security é uma solução bem mais moderna, com uma arquitetura mais bem bolada e com pontos de extensões mais definidos. Além disso é muito mais sincronizado com a realidade da maioria dos projetos. Queremos fazer segurança baseada em roles urls e ter uma maneira fácil de fazer essa associação é um grande diferencial. Este post é para você, que está numa aplicação JAVAEE, mas tem o desejo de usar o Spring Security como framework de segurança. Vou assumir que o leitor já sabe o básico do framework.

A configuração inicial não muda muito, supondo que você usa Maven, é necessário adicionar as novas dependências no pom.xml. 

		<!-- spring -->

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>4.0.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>4.0.1.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>4.1.0.RELEASE</version>
		</dependency>

O primeiro ponto diferente é em relação a configuração do filtro. Normalmente basta que você declare uma classe que herde AbstractSecurityWebApplicationInitializer e pronto. Só que como não estamos usando nada além do Spring, precisamos mudar um pouco código e passar todas as nossas classes de configuração que devem ser carregadas.

   public class SpringSecurityFilterConfiguration extends
		AbstractSecurityWebApplicationInitializer {

	public SpringSecurityFilterConfiguration() {
		super(SecurityConfiguration.class,SystemUserDAO.class,JPAConfiguration.class);
	}
   }

Geralmente você não precisa fazer isso, porque este passo já foi realizado na classe de configuração do Spring MVC. A classe SecurityConfiguration não tem nada demais, você pode acessá-la seguindo o link. Ela basicamente define as regras de segurança, da mesma forma que seria feito em um projeto usando unicamente a stack do Spring. A classe SystemUserDAO também não tem nada demais, ela implementa a interface UserDetailsService e precisa de um EntityManager injetado. E agora sim, temos uma situação. Qual EntityManager deve ser injetado? Lembre que estamos dentro de um servidor de aplicação e o melhor que usemos o contexto de persistência provido pelo container. Para a nossa sorte, o Spring é bastante extensível e não tem a menor pretensão de ser apenas usado isolado de todo mundo.

Como já temos um persistence.xml configurado, integrado com a JTA e utilizando o DataSource configurado no servidor, precisamos apenas ensinar ao Spring que queremos tirar proveito de todas essa configuração. Para isso vamos dar uma olhada na classe JPAConfiguration.

	package br.com.casadocodigo.security;

	//imports

	import org.springframework.context.annotation.Bean;

	public class JPAConfiguration {

		@Bean
		public EntityManagerFactory emf() throws NamingException {
			Context ctx = new InitialContext();
			EntityManagerFactory lookup = (EntityManagerFactory) ctx
					.lookup("java:comp/env/persistence/casadocodigo-emf");
			return lookup;
		}
	}

Simplesmente buscamos a referência para a EntityManagerFactory a partir da JNDI. Uma especificação muito usada no mundo Java, onde conseguimos associar nomes a objetos que podem ser recuperados no servidor. Uma pergunta que pode estar na sua mente é: de onde veio esse nome? Para isso vamos usar outro recurso da especificação JAVAEE, nesse caso a de Servlets. Conseguimos expor a EntityManagerFactory na JNDI, a partir do nosso arquivo web.xml.

	<persistence-unit-ref>
		<persistence-unit-ref-name>persistence/casadocodigo-emf</persistence-unit-ref-name>
		<persistence-unit-name>casadocodigo-persistence-unit</persistence-unit-name>
	</persistence-unit-ref>

A tag persistence-unit-ref-name define o nome que você quer expor na JNDI. Já a tag persistence-unit-name faz referência ao nome configurado no arquivo web.xml.

Pronto! Dessa forma conseguimos adicionar o Spring Security por exemplo, em um projeto usando JSF dentro de um servidor JAVAEE. Aproveitamos as configurações da JPA já feitas pela aplicação e simplesmente escrevemos a ponte para o Spring. Uma outra pergunta que pode ficar na cabeça é: o servidor JAVAEE já tem o CDI, só que o Spring faz a  mesma coisa. Não tem problema algum, não estamos querendo colocar o Spring para ser o controlador da Injeção de Dependências do sistema, estamos apenas usando o necessário para o Spring Security funcionar. Outra detalhe bem interessante é que a parte principal do Spring Security funciona dentro de um Filterpor isso conseguimos usar ele para fazer a segurança de qualquer aplicação web.

O Spring foi pensado justamente para ser extensível. É claro que o melhor dos mundos é usar os módulos do próprio Spring e ser feliz, mas isso nem sempre é possível. Também não fique preso ao estigma de usar Spring ou JAVAEE, use o que se encaixe melhor na sua aplicação. Encare tudo como ferramenta, nada de nutrir amor por tecnologia :).

[OFF-TOPIC] Novo projeto no ar, SetupMyProject!

Opa pessoal , essa é bem rápida. Eu, @mariofts e @sheldonchaves criamos o SetupMyProject, um projeto cujo objetivo é permitir que você crie a configuração inicial do seu projeto em apenas alguns minutos. Provavelmente a maioria de vocês já se pegou perdendo tempo na hora de começar um projeto usando, por exemplo,  o Spring MVC. Segue uma lista de coisas que você deve fazer para ter ele funcionando.

  1. Configurar dependências no  Maven(framework, banco de dados, versão do java)
  2. Criar classes de configuração do Spring(configuração de Servlet, beans)
  3. Primeiro Controller

Supostamente esses passos não deviam te atrasar, mas não é incomum pessoas perderem uma ou mais horas para conseguir ter o básico rodando. Caso você some a isso o uso de outras extensões, como a integração com a JPA, Security entre outras, isso pode ficar realmente demorado. O time do Spring até criou um site para facilitar, mas ele configura apenas as suas dependências. O que, de longe, não é o mínimo necessário para rodar o projeto.

Não estamos presos apenas ao Spring, criamos configurações de projetos que queiram usar JSF, VRaptor e Vaadin. Nossa ideia é expandir cada vez mais, adicionando possibilidades de adicionar mais plugins para que você realmente não perca tempo em um passo que deveria ser simples :).

Esperamos que vocês gostem e usem o projeto, queremos muito que nosso servidor caia por não suportar a geração de tantos projetos :). Acessa lá!