terça-feira, 22 de janeiro de 2013

Criando seu primeiro serviço Java-First com JAXWS e Maven

Neste artigo, criaremos nosso primeiro serviço utilizando a API JaxWS. Para implementar os exercícios mencionados aqui, é necessário fazer algumas configurações no seu ambiente de desenvolvimento (seu ambiente necessitará de acesso a web).

A primeira modificação necessária, é instalar o plugin para adicionar suporte a Maven no eclipse (sim, utilizaremos o eclipse como IDE). Para efetuar esta instalação, abra o eclipse market e instale o plugin M2E. Outro ponto importante é atualizar sua biblioteca Jaxb (se estiver utilizando o JDK 1.6). Para executar esta atividade, copie a biblioteca do jaxb 2.2.0 ou superior para a pasta endorsed da JRE em execução (no meu caso, copiei para <i>/usr/lib/jvm/jdk1.6.0_37/jre/lib/endorsed</i> (caso a pasta endorsed não exista, você deverá criá-la).

Lembre-se também que será necessário ter o servlet container Tomcat devidamente configurado e executando em sua máquina (não coberto pelo artigo).

Crie um projeto do tipo Maven (File -> New -> Project -> Maven -> Maven Project), e selecione a opção "Create a simple project (skip archetype selection)" e preencha as informações básicas do projeto (seção Artifact) de acordo com os dados disponibilizados abaixo:

Group Id: br.com.ws.exemplo
Artifact Id: helloplanet-jaxws
Version: 1.0.0
Packaging: war


O projeto é criado e automaticamente é adicionado um arquivo chamado pom.xml. Este arquivo configura o processo de compilação e construção do pacote final de software. Precisamos alterá-lo para compilar o projeto de acordo com as nossas necessidades (gerar o serviço e a estrutura de um projeto war). Adicione um source folder no projeto (Clicar com o botão direito sobre o projeto -> New -> Source Folder), seguindo a estrutura main/src e nomeie como "webresources". Altere seu pom.xml de acordo com a estrutura abaixo:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>br.com.ws.exemplo</groupId>
  <artifactId>helloplanet-jaxws</artifactId>
  <version>1.0.0</version>
  <packaging>war</packaging>

  <dependencies>
      <dependency>
          <groupId>com.sun.xml.ws</groupId>
          <artifactId>jaxws-rt</artifactId>
          <version>${jaxb.version}</version>
          <scope>compile</scope>
      </dependency>
  </dependencies>

  <properties>
      <jaxb.version>2.2.7</jaxb.version>
  </properties>

  <build>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <webResources>
                    <resource>
                        <directory>${basedir}/src/main/webresources</directory>
                    </resource>
                </webResources>
                <warName>helloplanet-jaxws</warName>
            </configuration>
          </plugin>
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxws-maven-plugin</artifactId>
            <version>1.11</version>
            <executions>
              <execution>
                <goals>
                  <goal>wsgen</goal>
                </goals>
                <configuration>
                  <sei>br.com.exemplo.ws.impl.HelloPlanetImpl</sei>
                  <genWsdl>true</genWsdl>
                  <keep>true</keep>
                </configuration>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugin</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
              <source>1.6</source>
              <target>1.6</target>
            </configuration>
          </plugin>
      </plugins>
  </build> 
</project>


É importante explicar melhor algumas partes do projeto, como a seguinte:

          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <webResources>
                <!-- configura a pasta webresources como a pasta de recursos do projeto web -->
                    <resource>
                        <directory>${basedir}/src/main/webresources</directory>
                    </resource>
                </webResources>
            <!-- define o nome do web archive (war) que será gerado -->
                <warName>helloplanet-jaxws</warName>
            </configuration>
          </plugin>


O trecho abaixo também merece uma atenção especial, pois configura a execução do plugin de geração do serviço:

          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxws-maven-plugin</artifactId>
            <version>1.11</version>
            <executions>
              <execution>
                <goals>
                  <goal>wsgen</goal>
                </goals>
                <configuration>
                  <sei>br.com.exemplo.ws.impl.HelloPlanetImpl</sei>
                  <genWsdl>true</genWsdl>
                  <keep>true</keep>
                </configuration>
              </execution>
            </executions>
          </plugin>


Agora, vamos criar a pasta WEB-INF e colocar nosso arquivo web.xml dentro. Esta estrutura é necessária para aplicações web em java. Clique com o botão direito sobre a pasta webresources e adicione uma pasta denominada WEB-INF. Adicione um novo arquivo xml nesta pasta e nomeie este arquivo como web.xml. O conteúdo do web.xml deve ser o seguinte:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <display-name>HelloPlanetJAXWS Application</display-name>
    <description>
        This is a simple web application with a source code organization
        based on the Java web-apps standard.
    </description>
   
    <listener>
      <listener-class>
        com.sun.xml.ws.transport.http.servlet.WSServletContextListener
      </listener-class>
    </listener>
    <servlet>
      <servlet-name>HelloPlanetJAXWS</servlet-name>
      <servlet-class>
        com.sun.xml.ws.transport.http.servlet.WSServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
      <servlet-name>HelloPlanetJAXWS</servlet-name>
      <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <session-config>
      <session-timeout>120</session-timeout>
    </session-config>
</web-app>


Perceba que neste arquivo configuramos o servlet do JaxWS para para carregar nosso serviço. Agora que temos o webxml devidamente configurado, devemos configurar nosso projeto. Dentro desta mesma pasta (WEB-INF), adicione o arquivo sun-jaxws.xml para configuração do serviço. Este arquivo deve conter o seguinte conteúdo:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
  <endpoint name="HelloPlanetJAXWSEndPoint" implementation="br.com.exemplo.ws.impl.HelloPlanetImpl" url-pattern="/hello"/>
</endpoints>


Repare que a url do segundo arquivo (sun-jaxws.xml) é a mesma utilizada no primeiro (web.xml). Agora que já configuramos todo o projeto, vamos ao código. Primeiro vamos criar a interface do serviço. Para isso, clique com o botão direito sobre a pasta "src/main/java" e selecione New -> Interface.

No pacote, adicione br.com.exemplo.ws e dê o nome HelloPlanet. Insira o seguinte código para a interface criada:

package br.com.exemplo.ws;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlElement;

import br.com.exemplo.ws.domain.Planet;

@WebService(name="HelloPlanet", targetNamespace="http://www.helloplanet.com.br/jaxws")
public interface HelloPlanet {
    @WebMethod(operationName="SayHello", action="http://www.helloplanet.com.br/jaxws/sayHello")
    @WebResult(name="Greeting", targetNamespace="http://www.helloplanet.com.br/jaxws/sayhello/result")
    public String sayHello(@WebParam(name="PlanetName", targetNamespace="http://www.helloplanet.com.br/jaxws/domain/planet") @XmlElement(required=true, nillable=false) Planet planet);
}


Repare que a nossa interface renomeia o método, parâmetro e resultado retornado. Outro ponto importante é a anotação @XmlElement que efetuará a validação do parâmetro para o serviço (necessário ter sobrescrito a jaxb api conforme descrito no começo do artigo). Agora vamos criar o código da nossa classe. Para isso, clique com o botão direito sobre a pasta "src/main/java" e selecione New -> Class, configure o package como "br.com.exemplo.ws.impl", nomeie a classe como HelloPlanetImpl e adicione o seguinte código:

package br.com.exemplo.ws.impl;

import javax.jws.WebService;

import com.sun.xml.ws.developer.SchemaValidation;

import br.com.exemplo.ws.HelloPlanet;
import br.com.exemplo.ws.domain.Planet;

@SchemaValidation
@WebService(endpointInterface="br.com.exemplo.ws.HelloPlanet", portName="HelloPlanetPort",  serviceName="HelloPlanet")
public class HelloPlanetImpl implements HelloPlanet {

    public String sayHello(Planet planet) {
        return "Hello " + planet.getName() + "! Your id is: " + planet.getId() + " and your distance is: " + planet.getDistance();
    }

}


Neste ponto, você ainda deve estar vendo um erro no seu projeto. A classe Planet, que é recebida como parâmetro pelo método (operação do serviço) ainda não existe, então vamos criá-la. Para isso, clique com o botão direito sobre a pasta "src/main/java" e selecione New -> Class, configure o package como "br.com.exemplo.ws.domain", nomeie a classe como Planet e adicione o seguinte código:

package br.com.exemplo.ws.domain;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Planet", namespace="http://www.helloplanet.com.br/jaxws/domain/planet")
@XmlAccessorType(XmlAccessType.FIELD)
public class Planet {

    @XmlElement(name="ID", required=true, nillable=true)
    private Integer id;
    @XmlElement(name="Name", required=false, nillable=false)
    private String name;
    @XmlElement(name="Distance", required=true, nillable=false)
    private Double distance;
   
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Double getDistance() {
        return distance;
    }
    public void setDistance(Double distance) {
        this.distance = distance;
    }
   
}


Pronto! Agora vamos compilar o projeto. Para isso, clique com o botão direto sobre o arquivo pom.xml e selecione "Run as -> Maven Install". Aguarde o maven baixar as dependências e compilar o projeto. Ao final do processo de compilação você deverá ver uma mensagem semelhante a esta:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.439s
[INFO] Finished at: Wed Dec 12 20:10:13 BRST 2012
[INFO] Final Memory: 10M/25M
[INFO] ------------------------------------------------------------------------


Verifique a pasta target do seu projeto, e dentro, deverá existir o arquivo helloplanet-jaxws.war. Este arquivo será jogado dentro da pasta webapps do tomcat. Após copiar o arquivo, acesse a URL:

http://localhost:8080/helloplanet-jaxws/hello?wsdl

E você verá o wsdl pertinente ao seu serviço. Parabéns, você criou seu primeiro serviço utilizando JaxWS e ele está disponível em:

http://localhost:8080/helloplanet-jaxws/hello

Caso tenha percebido, o @XmlElement não gerou a validação corretamente para o serviço (xml retirado de exemplo de consumo utilizando SoapUI).

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:jax="http://www.helloplanet.com.br/jaxws" xmlns:plan="http://www.helloplanet.com.br/jaxws/domain/planet">
   <soapenv:Header/>
   <soapenv:Body>
      <jax:SayHello>
         <!--Optional:-->
         <plan:PlanetName>
            <ID>?</ID>
            <!--Optional:-->
            <Name>?</Name>
            <Distance>?</Distance>
         </plan:PlanetName>
      </jax:SayHello>
   </soapenv:Body>
</soapenv:Envelope>


Repare que o parâmetro PlanetName está demarcado como opcional (trecho retirado do contrato gerado) enquanto que a validação foi respeitada para o parâmetro planetId:

<xs:element ref="ns1:PlanetName" minOccurs="0"/>

Este é um bug do JaxWS (a validação através de @XmlElement é respeitada para tipos primitivos da linguagem mas não para objetos) e a para sanar o problema, podemos utilizar CXF para a construção do nosso serviço, como veremos no próximo post.

terça-feira, 25 de setembro de 2012

Bumblebee no Fedora 17 64 bits - Dell XPS 15z

Eu estava configurando a aceleração gráfica do meu dell xps no Fedora 17 e comecei a estudar qual seria a melhor forma de resolver. Durante a minha pesquisa, encontrei diversos artigos mencionando a utilização de uma solução da NVidia denominada Optimus para controlar quando utilizar a placa de video com memória dedicada e quando utilizar a alternativa com memória integrada.

Mas como assim? Seu notebook têm duas placas de vídeo? Sim, e esta estratégia é utilizada para economia de energia. Quando a máquina entra em "modo econômico", utiliza uma placa intel compartilhada e quando precisa de poder gráfico, utiliza a placa de vídeo NVidia (no meu caso uma 540m).

Tentei configurar o Bumblebee/Optimus de diversas formas diferentes, sendo que todas elas solicitavam que eu alterasse o xorg.conf, instalasse o akmodnivdia, etc. Dentre as minhas pesquisas acabei encontrando um processo bem simples para resolver o problema com poucos comandos. Inicialmente precisamos adicionar alguns repositórios ao yum, através do seguinte comando:

sudo yum -y --nogpgcheck install http://install.linux.ncsu.edu/pub/yum/itecs/public/bumblebee-nonfree/fedora17/noarch/bumblebee-nonfree-release-1.0-1.noarch.rpm

sudo yum -y --nogpgcheck install http://install.linux.ncsu.edu/pub/yum/itecs/public/bumblebee/fedora17/noarch/bumblebee-release-1.0-1.noarch.rpm

Após executarmos os comandos descritos acima, precisamos instalar o bbswitch, o bumblebee e o bumblebee-nvidia, conforme demonstrado abaixo:

sudo yum -y install bbswitch bumblebee

sudo yum -y install bumblebee-nvidia

Reinicie sua máquina e pronto! Para testar, basta executar os comandos demonstrados abaixo:

glxgears

A execução acima não utiliza aceleração gráfica, e no meu caso apresentou o seguinte número de FPS:

302 frames in 5.0 seconds = 60.276 FPS
300 frames in 5.0 seconds = 59.818 FPS

E para testar a execução com aceleração gráfica, vamos executar o comando:

optirun glxgears

Este caso apresentou o seguinte FPS, melhorando considerávelmente a execução, como podemos ver:

2696 frames in 5.0 seconds = 539.101 FPS
2761 frames in 5.0 seconds = 552.123 FPS
2778 frames in 5.0 seconds = 555.365 FPS


sexta-feira, 21 de setembro de 2012

Preparando o Fedora 17 64 bits para instalar o Oracle Service Bus 11g

Nesta postagem, instalaremos todos os componentes necessários para, futuramente, o Ofacle Fusion Middleware OSB 11.1.1. Este procedimento também instala os softwares necessários para gerar um ambiente de desenvolvimento baseado em Oracle Weblogic Server e Oracle Database. Inicialmente necessitamos instalar alguns softwares/Middlewares que serão referenciados ou utilizados pelo OSB, que são:

- JDK 1.6.0_35
- Oracle Database XE 11g
- Oracle Enterprise Pack for Eclipse
- Oracle Weblogic Server 11g (10.36)

Após instalarmos e e configurarmos estes softwares, partiremos para a instalação do OSB.

Para executar esses comandos, precisamos adicionar nosso usuário no grupo dos sudoers. Para isso basta executar o seguinte comando como root:

echo 'loginname ALL=(ALL) ALL' >> /etc/sudoers

Lembre-se de substituir "loginname" pelo nome do usuário que deseja adicionar.

Configurando a JDK 1.6.0_35

Baixe o instalador (no meu caso, usei o arquivo jdk-6u35-linux-x64.bin) do site da Oracle. Abra um terminal, vá até a pasta de download e execute os seguintes comandos:

chmod +x jdk-6u35-linux-x64.bin
./jdk-6u35-linux-x64.bin

Após executar estes comandos, uma pasta contendo a JDK será gerada no diretório corrente. Vamos movê-la para a pasta /usr/java e então configurar o sistema para utilizar a JDK:

sudo mkdir /usr/java
sudo mv jdk1.6.0_35 /usr/java

Agora vamos configurar o JDK no sistema. Inicialmente temos que exportar as variáveis de CLASSPATH e JAVA_HOME, porém, para que estas sejam exportadas automaticamente na inicialização do sistema, adicionaremos estas variáveis ao arquivo /etc/environment:

sudo vi /etc/environemt

Insira o seguinte conteúdo no arquivo:

CLASSPATH=/usr/java/jdk1.6.0_35/lib/
JAVA_HOME=/usr/java/jdk1.6.0_35/

Salve o arquivo (ESC, wq) e então execute o seguinte comando para disponibilizar as variáveis no ambiente:

source /etc/environment

Agora execute os seguintes comandos para criar diretórios necessários, links simbólicos e adicionar a JDK como alternativa java para o sistema:

sudo mkdir -p /usr/lib/jvm /usr/lib/jvm-exports

sudo alternatives --install /usr/bin/java java /usr/java/jdk1.6.0_35/bin/java 15000 \
--slave /usr/lib/jvm/jre jre /usr/java/jdk1.6.0_35/jre \
--slave /usr/lib/jvm-exports/jre jre_exports /usr/java/jdk1.6.0_35/jre/lib \
--slave /usr/bin/keytool keytool /usr/java/jdk1.6.0_35/jre/bin/keytool \
--slave /usr/bin/orbd orbd /usr/java/jdk1.6.0_35/jre/bin/orbd \
--slave /usr/bin/pack200 pack200 /usr/java/jdk1.6.0_35/jre/bin/pack200 \
--slave /usr/bin/rmid rmid /usr/java/jdk1.6.0_35/jre/bin/rmid \
--slave /usr/bin/rmiregistry rmiregistry /usr/java/jdk1.6.0_35/jre/bin/rmiregistry \
--slave /usr/bin/servertool servertool /usr/java/jdk1.6.0_35/jre/bin/servertool \
--slave /usr/bin/tnameserv tnameserv /usr/java/jdk1.6.0_35/jre/bin/tnameserv \
--slave /usr/bin/unpack200 unpack200 /usr/java/jdk1.6.0_35/jre/bin/unpack200 \
--slave /usr/share/man/man1/java.1 java.1 /usr/java/jdk1.6.0_35/man/man1/java.1 \
--slave /usr/share/man/man1/keytool.1 keytool.1 /usr/java/jdk1.6.0_35/man/man1/keytool.1 \
--slave /usr/share/man/man1/orbd.1 orbd.1 /usr/java/jdk1.6.0_35/man/man1/orbd.1 \
--slave /usr/share/man/man1/pack200.1 pack200.1 /usr/java/jdk1.6.0_35/man/man1/pack200.1 \ --slave /usr/share/man/man1/rmid.1.gz rmid.1 /usr/java/jdk1.6.0_35/man/man1/rmid.1 \
--slave /usr/share/man/man1/rmiregistry.1 rmiregistry.1 /usr/java/jdk1.6.0_35/man/man1/rmiregistry.1 \
--slave /usr/share/man/man1/servertool.1 servertool.1 /usr/java/jdk1.6.0_35/man/man1/servertool.1 \
--slave /usr/share/man/man1/tnameserv.1 tnameserv.1 /usr/java/jdk1.6.0_35/man/man1/tnameserv.1 \
--slave /usr/share/man/man1/unpack200.1 unpack200.1 /usr/java/jdk1.6.0_35/man/man1/unpack200.1


sudo alternatives --install /usr/bin/javac javac /usr/java/latest/bin/javac 15000 \
--slave /usr/lib/jvm/java java_sdk /usr/java/jdk1.6.0_35 \
--slave /usr/lib/jvm-exports/java java_sdk_exports /usr/java/jdk1.6.0_35/lib \
--slave /usr/bin/appletviewer appletviewer /usr/java/jdk1.6.0_35/bin/appletviewer \
--slave /usr/bin/apt apt /usr/java/jdk1.6.0_35/bin/apt \
--slave /usr/bin/extcheck extcheck /usr/java/jdk1.6.0_35/bin/extcheck \
--slave /usr/bin/jar jar /usr/java/jdk1.6.0_35/bin/jar \
--slave /usr/bin/jarsigner jarsigner /usr/java/jdk1.6.0_35/bin/jarsigner \
--slave /usr/bin/javadoc javadoc /usr/java/jdk1.6.0_35/bin/javadoc \
--slave /usr/bin/javah javah /usr/java/jdk1.6.0_35/bin/javah \
--slave /usr/bin/javap javap /usr/java/jdk1.6.0_35/bin/javap \
--slave /usr/bin/jconsole jconsole /usr/java/jdk1.6.0_35/bin/jconsole \
--slave /usr/bin/jdb jdb /usr/java/jdk1.6.0_35/bin/jdb \
--slave /usr/bin/jhat jhat /usr/java/jdk1.6.0_35/bin/jhat \
--slave /usr/bin/jinfo jinfo /usr/java/jdk1.6.0_35/bin/jinfo \
--slave /usr/bin/jmap jmap /usr/java/jdk1.6.0_35/bin/jmap \
--slave /usr/bin/jps jps /usr/java/jdk1.6.0_35/bin/jps \
--slave /usr/bin/jrunscript jrunscript /usr/java/jdk1.6.0_35/bin/jrunscript \
--slave /usr/bin/jsadebugd jsadebugd /usr/java/jdk1.6.0_35/bin/jsadebugd \
--slave /usr/bin/jstack jstack /usr/java/jdk1.6.0_35/bin/jstack \
--slave /usr/bin/jstat jstat /usr/java/jdk1.6.0_35/bin/jstat \
--slave /usr/bin/jstatd jstatd /usr/java/jdk1.6.0_35/bin/jstatd \
--slave /usr/bin/native2ascii native2ascii /usr/java/jdk1.6.0_35/bin/native2ascii \
--slave /usr/bin/policytool policytool /usr/java/jdk1.6.0_35/bin/policytool \
--slave /usr/bin/rmic rmic /usr/java/jdk1.6.0_35/bin/rmic \
--slave /usr/bin/schemagen schemagen /usr/java/jdk1.6.0_35/bin/schemagen \
--slave /usr/bin/serialver serialver /usr/java/jdk1.6.0_35/bin/serialver \
--slave /usr/bin/wsgen wsgen /usr/java/jdk1.6.0_35/bin/wsgen \
--slave /usr/bin/wsimport wsimport /usr/java/jdk1.6.0_35/bin/wsimport \
--slave /usr/bin/xjc xjc /usr/java/jdk1.6.0_35/bin/xjc


Para confirmar que o comando foi executado corretamente, verifique através da execução dos seguintes comandos:

java -version
javac -version

Seu sistema Fedora está configurado para trabalhar com a JDK 1.6.0_35 da Oracle.

Configurando o Oracle Database 11g XE

Primeiramente devemos baixar o Oracle Database Express Edition 11g Release 2 for Linux x64. Após o fim do download, devemos abrir um terminal e navegar para a pasta na qual o arquivo oracle-xe-11.2.0-1.0.x86_64.rpm.zip foi armazenado e executar os seguintes comandos:

unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip
sudo rpm -iv oracle-xe-11.2.0-1.0.x86_64.rpm

Após finalizar a instalação, o seguinte comando deve ser executado como root:

/etc/init.d/oracle-xe configure

Um processo de configuração da database será inicializado e solicitará uma porta para execução do Oracle Application Express. A porta padrão é a 8080, e eu gosto de mudar (por exemplo, 7787) pois esta porta é amplamente utilizada por servidores java. Depois o processo solicitará uma porta para rodar o listener do oracle, e nesse caso, mantenho a porta padrão (basta não inserir nenhum valor e pressionar enter para que seja mantida a porta 1521). O sistema solicitará uma senha para o usuário SYS e SYSTEM. Digite a senha, digite novamente para confirmar e pressione enter. O processo de configuração, perguntará então, se você deseja inicialiar o Oracle XE durante o boot da máquina, eu costumo deixar na inicialização, então digito "y". Finalmente seu oracle express está instalado e configurado.
Agora é necessário adicionar um script para exportar as variáveis de ambiente do Oracle, e para isso devemos alterar o .bashrc. Para isso lembre de não estar logado como root. Você deve abrir o .bashrc com seu usuário.

cd ~
vi bashrc


E insira o seguinte código no final do arquivo:

# Oracle Settings
TMP=/tmp; export TMP
TMPDIR=$TMP; export TMPDIR

ORACLE_HOSTNAME=localhost.localdomain; export ORACLE_HOSTNAME
ORACLE_UNQNAME=DB11G; export ORACLE_UNQNAME
ORACLE_BASE=/u01/app/oracle; export ORACLE_BASE
ORACLE_HOME=$ORACLE_BASE/product/11.2.0/xe; export ORACLE_HOME
ORACLE_SID=XE; export ORACLE_SID
NLS_LANG=`$ORACLE_HOME/bin/nls_lang.sh`; export NLS_LANG
ORACLE_TERM=xterm; export ORACLE_TERM
PATH=/usr/sbin:$PATH; export PATH
PATH=$ORACLE_HOME/bin:$PATH; export PATH

LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib; export LD_LIBRARY_PATH
CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib; export CLASSPATH

if [ $USER = "oracle" ]; then
     if [ $SHELL = "/bin/ksh" ]; then
        ulimit -p 16384
        ulimit -n 65536
    else
        ulimit -u 16384 -n 65536
    fi
fi

Para testar basta digitar no terminal:

sqlplus system

e abrir um browser (firefox ou chrome) e entrar na tela inicial do Oracle Application Express através do endereço:

http://localhost:7787/apex

Instalando o Oracle Enterprise Pack for Eclipse

Efetue o download do OEPE, e neste caso é muito importante que sua versão do OEPE seja a mesma do Oracle Service Bus a ser instalado. Eu estou usando o OEPE Indigo 11.1.1.8.0 64 bits nesta instalação. Após o término do download, descompacte o arquivo em uma pasta de sua vontade. Eu costumo criar uma estrutura que considero intuitiva para minhas ferramentas Oracle Fusion Middleware, conforme demonstrada a seguir:

mkdir /home/meuusario/Oracle/Tools/oepe-indigo-11.1.1

E descompacto lá dentro.

Instalando o Oracle Weblogic Server

Para instalar o Oracle Weblogic Server 11g em uma máquina contendo SO Linux 64 bits (com uma vm 64 bits, como é o nosso caso), devemos baixar o arquivo de instalação generic, empacotado em um JAR. Este arquivo está disponível em uma tabela, abaixo das releases atuais (Oracle WebLogic Server Previous Releases). A coluna que contém o arquivo é denominada "Additional Platforms (For 64-bit JVM Support, See Note Above)" e a linha possui o rótulo "Oracle WebLogic Server 11gR1 (10.3.6) + Coherence - Package Installer". O nome do arquivo que será baixado é wls1036_generic.jar. Após o término do download, abra um terminal, navegue para a pasta na qual o arquivo foi salvo e execute o seguinte comando:

java -jar wls1036_generic.jar

Siga o wizard de instalação com os valores padrões e, quando este processo for terminado, você possuirá o Oracle Weblogic Server 11g instalado em seu sistema (em artigos posteriores cobriremos a execução do RCU para criar os objetos necessários na base de dados, instalação do Oracle Service Bus e a criação de um domínio para utilização).

Referências:

http://blog.mclaughlinsoftware.com/2011/09/27/oracle-11g-xe-on-fedora/
http://www.rackspace.com/knowledge_center/article/how-to-install-the-oracle-jdk-on-fedora-15-16
http://www.mjmwired.net/resources/mjm-fedora-fc6.html#sudo

terça-feira, 4 de setembro de 2012

Instalando o JDK 6 e JDK 7 no Ubuntu 12.04 32 bits

Ontem formatei minha máquina e resolvi instalar o JDK diretamente do reposistório. Quando tentei utilizar o apt para instalar, me deparei com a surpresa de que o JDK e as JREs da Oracle foram removidas do repositório por questões de licensa. Vou descrever os passos que executei para auxiliar aqueles que se depararam com o mesmo problema.

Primeiramente baixei os arquivos de instalação da página da Oracle. No meu caso, baixei o jdk-6u35-linux-i586.bin e o jdk-7u7-linux-i586.tar.gz. Primeiro vamos instalar o JDK 6, após o término, vamos instalar o JDK 7 e por fim vamos atualizar o sistema para utilizar um ou outro (e implantar um jeito fácil de alternar entre eles).

Para instalar o JDK 6, abra um terminal, navegue para a pasta que contém os arquivos baixados e execute os seguintes comandos:

chmod +x jdk-6u35-linux-i586.bin

Esse comando criará uma pasta denominada (no meu caso) jdk1.6.0_35 e descompactará os arquivos do JDK. Agora precisamos mover essa pasta para dentro do local padrão de JVMs do Ubuntu:

sudo mv jdk1.6.0_35 /usr/lib/jvm

Agora vamos fazer um procedimento semelhante com o JDK 7. Primeiramente devemos descompacta-lo, o que criará uma pasta denominada (no meu caso) jdk1.7.0_07. devemos mover esta pasta para o mesmo diretório mencionado anteriormente:

sudo mv jdk1.7.0_07 /usr/lib/jvm

Agora deveríamos atualizar o sistema todo para pegar a configuração do JDK que desejamos utilizar, porém, ao invés de executar os update-alternatives manualmente, recomendo a utilização do script update-java-0.5b. Para utilizar este script, primeiramente devemos baixá-lo:

wget http://webupd8.googlecode.com/files/update-java-0.5b

Após o término do download, devemos dar permissão de execução ao script:

chmod +x update-java-0.5b

E por fim, executá-lo:

./update-java-0.5b

Uma janela será exibida oferecendo as JVMs disponíveis no sistema e então basta selecionar uma delas e clicar em OK. Agora basta aguardar alguns segundos para que o sistema seja atualizado. Quando a atualização for finalizada, caso queira verificar a versão de java instalado, basta executar o comando:

java -version

O sistema exibirá a versão do java em uso, e caso queira mudar para a outra versão, basta executar o update-java-05b novamente e selecionar a versão do java necessária. Essa solução permite que você tenha várias JDKs coexistindo e mude de acordo com suas necessidades de forma prática e rápida.

Adobe Flex - Contornando o erro #2032 relacionado ao textLayout_1.1.0.604.sw

Faço parte de um projeto e recentemente tivemos que reviver um sistema implementado no passado para extrair algumas regras de negócio e entender alguns comportamentos. O sistema foi feito em Adobe Flex, tecnologia que não está mais sob forte atualização (eu diria que não está mais sendo atualizada se tivesse como provar). Ninguém mexia no sistema legado já haviam meses (desde dezembro do ano passado) e eu havia configurado uma cópia local para executar na minha máquina em fevereiro.

Tudo parecia normal, porém, quando o deploy foi feito, antes de carregar qualquer tela, aparecia uma barra de progresso que parava em 100% e então, logo abaixo aparecia a mensagem:
error #2032
Depois de pesquisar sobre o problema por um dia, descobri que era erro de configuração das RSLs do projeto. Não trabalhei com Flex e não tenho experiência em Flash, porém, o tempo estava correndo contra e não havia tempo para aprender.

Utilizando o Fiddler, interceptei as requisições que minha máquina estava fazendo para servidores externos e descobri que um erro era retornado quando minha aplicação tentava validar um componente denominado textLayout_1.1.0.604.sw contra o FTP da adobe. Após pesquisar um pouco nos fóruns da Adobe encontrei uma solução (que não é a mais indicada) para contornar esse problema.

Para resolver o problema devemos adicionar -static-link-runtime-shared-libraries
aos parâmetros de compilação.

Dessa forma conseguimos executar novamente o sistema e entender os comportamentos e fluxos de navegações necessários. No meu ponto de vista, esse problema mostrou a atenção que a Adobe está dando ao Flex devido ao advento do HTML 5.

sexta-feira, 16 de julho de 2010

Como colocar autenticação básica no console web do Fuse Message Broker v5.3

Até a versão 5.4 o Fuse Message Broker disponibiliza livre acesso a ferramenta de administração. Este é o padrão de instalação, porém, quando disponibilizamos este servidor para acesso de outros recursos, muitas vezes não queremos que qualquer pessoa efetue modificações sem nossa permissão. Uma forma simples de resolver isso (quando os requisitos de segurança não forem muito rígidos, por exemplo, na criação de um servidor interno para desenvolvimento) é habilitar a autenticação básica para entrar em qualquer URL pertinente a área de administração.

O arquivo que iremos alterar está localizado na pasta conf do fuse message broker, e para encontrá-lo devemos executar os seguintes comandos (tomamos como padrão o exemplo de caminhos utilizados no artigo de que ensina a instalar o Fuse Message Broker publicado por mim neste mesmo blog):

cd /opt/fuse-message-broker-5.3.1/conf

Para executar este procedimento, primeiramente devemos alterar o arquivo jetty.xml adicionando as seguintes configurações:

<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.--><!-- An embedded servlet engine for serving up the Admin consoles, REST and Ajax APIs and some demos Include this file in your configuration to enable ActiveMQ web components e.g. <import resource="jetty.xml"/>-->

<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:jetty="http://mortbay.com/schemas/jetty/1.0"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userRealm" class="org.mortbay.jetty.security.HashUserRealm">
<property name="name" value="ActiveMQRealm"/>
<property name="config" value="${activemq.base}/conf/jetty-realm.properties"/>
</bean>
<bean id="securityConstraint" class="org.mortbay.jetty.security.Constraint">
<property name="name">
<util:constant static-field="org.mortbay.jetty.security.Constraint.__BASIC_AUTH"/>
</property>
<property name="roles">
<list><value>admin</value></list>
</property>
<property name="authenticate" value="true"/>
</bean>
<bean id="securityConstraintMapping" class="org.mortbay.jetty.security.ConstraintMapping">
<property name="constraint" ref="securityConstraint"/>
<property name="pathSpec" value="/*"/>
</bean>
<bean id="securityHandler" class="org.mortbay.jetty.security.SecurityHandler">
<property name="userRealm" ref="userRealm"/>
<property name="constraintMappings">
<list>
<ref bean="securityConstraintMapping" />
</list>
</property>
</bean>
<bean id="Server" class="org.mortbay.jetty.Server" init-method="start" destroy-method="stop">
<property name="connectors">
<list>
<bean id="Connector" class="org.mortbay.jetty.nio.SelectChannelConnector">
<property name="port" value="8161"/>
</bean>
</list>
</property>
<property name="handler">
<bean id="handlers" class="org.mortbay.jetty.handler.HandlerCollection">
<property name="handlers">
<list>
<ref bean="securityHandler" />
<bean id="contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection">
...


Este arquivo faz referência a um arquivo de properties que deve conter o nível de privilégio, usuário e senha este arquivo deve ser criado na mesma pasta (conf) e o nome deve ser jetty-realm.properties. Para executar este passo digite o seguinte comando:

sudo pico jetty-realm.properties

E insira o seguinte conteúdo:

## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: admin, admin


Então devemos alterar o owner do arquivo, para o mesmo usuário que é utilizado para inicializar o Fuse Message Broker:

sudo chown fuse-message-broker jetty-realm.properties

E então basta executar o comando para inicializar o Fuse Message Broker:

sudo service fuse-message-broker start

e tentar acessar a url de administração:

http://localhost:8161/admin

Se o procedimento for executado corretamente, uma janela pedindo usuário e senha será exibida antes que você possa navegar e utilizar o console.

Referências:
http://www.nighttale.net/activemq/securing-activemq-531-console.html
http://github.com/dejanb/activemq-util/blob/master/config/5.3.1/jetty/jetty.xml

segunda-feira, 12 de julho de 2010

Como criar novos tópicos e novas filas na inicialização do Fuse Message Broker v5.3

Previamente abordamos a instalação do Fuse Message Broker e como configurá-lo para inicialização através de serviço do Ubuntu. Neste novo artigo abordaremos como criar um novo destino de mensagens para o nosso message broker previamente instalado. Existem duas possibilidades para gerar um novo destino de mensagens no Fuse Message Broker. Uma delas é utilizar a criação em tempo de execução, e esta pode ser executada através de:

- chamada a createQueue() através de uma sessão JMS.
- criar uma instância de ActiveMQTopic ou ActiveMQQueue e registrar como um recurso JNDI para o seu servidor.


Ou podemos determinar que destinos serão criados ao inicializarmos a ferramenta (se configurado conforme artigo anterior, através do comando sudo service fuse-message-broker start). Para configurar uma fila ou um tópico seguindo o segundo exemplo devemos alterar a configuração do arquivo activemq.xml. Este arquivo se encontra na pasta conf dentro do caminho de instalação escolhido para a ferramenta. Seguiremos os caminhos especificados durante a nossa instalação demonstrada no artigo anterior:

cd /opt/fuse-message-broker-5.3.1/conf
sudo pico activemq.xml


E devemos inserir o seguinte conteúdo:

<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
...
<broker xmlns="http://activemq.apache.org/schema/core">
...
<destinations>
<queue physicalName="FOO.BAR" />
<topic physicalName="SOME.TOPIC" />
</destinations>
...
</broker>
</beans>


com esta configuração dizemos que ao inicializar o message broker, criaremos um tópico denominado SOME.TOPIC e uma fila denominada FOO.BAR.

Referência
http://activemq.apache.org/how-do-i-create-new-destinations.html
http://activemq.apache.org/configure-startup-destinations.html

quarta-feira, 30 de junho de 2010

Instalando o Fuse Message Broker v5.3 no Ubuntu 10.04 LTS

Para instalar o fuse message broker v5.3 no Ubuntu 10.04 LTS inicialmente devemos efetuar o download do arquivo de instalação. Para isso executamos os seguintes comandos:

cd ~
mkdir installs
cd installs
mkdir fuse-message-broker
cd fuse-message-broker
wget http://repo.fusesource.com/maven2/com/iona/fuse/fuse-message-broker/5.3.1-02-00/fuse-message-broker-5.3.1-02-00-unix.bin


Após o término do download, vamos executar o instalador em modo console:

chmod +x fuse-message-broker-5.3-unix.bin
sudo sh fuse-message-broker-5.3-unix.bin -i console


Devemos executar o instalador com o comando sudo pois instalaremos o aplicativo na pasta /opt e é necessário ter permissão de escrita para instalar nesta pasta. O termo de licença será apresentado e devemos pressionar até que este seja finalizado. Quando este terminar, devemos aceitar os termos e então será oferecido o seguinte caminho de instalação /opt/progress/fuse-message-broker-5.3.1-02-00 (ou algo semelhante dependendo da sua versão). Eu gosto de mudar esta estrutura para facilitar meus scripts para /opt/fuse-message-broker-5.3.1.

O script começará a instalação e uma barra de progresso será exibida. Ao finalizar o instalador oferece a opção de salvar a configuração da instalação caso seja necessário executar uma instalação idêntica em outros servidores ou caso queira efetuar a mesma instalação novamente posteriormente. Digite Y caso queira salvar ou N caso não seja necessário.

Uma mensagem de sucesso será exibida contendo a pasta em que o software foi instalado. Pressione para retornar ao prompt. É válido ressaltar que a qualquer momento durante a instalação podemos inserir o comando de desistência:

quit

vamos colocar o usuário fuse-message-broker como owner da nossa pasta:

sudo chown fuse-message-broker /opt/fuse-message-broker-5.3.1 -R

Para configurar o software gerenciador de filas, devemos executar o seguinte comando:

cd /opt/fuse-message-broker-5.3.1/conf
sudo pico activemq.xml


Este arquivo contém algumas configurações para o servidor de filas. Todas as linhas são comentadas e aconselho a ler cada um dos comentários com paciência e pesquisar á respeito quando tiver alguma dúvida. O primeiro item que mudo na minha configuração é a seguinte:

<broker ... brokerName="localhost">

para:

<broker ... brokerName="myname-broker">

Vamos adicionar um usuário para executar inicializar o Fuse Message Broker com permissões limitadas e criar um diretório de logs para jogar a saída da inicialização do nosso broker:

sudo adduser --system fuse-message-broker
sudo -u fuse-message-broker mkdir /home/fuse-message-broker/logs


E vamos criar um script para inicialização da nossa instância como um serviço do ubuntu:

cd /etc/init.d/
sudo pico fuse-message-broker


E inserir o seguinte conteúdo dentro do arquivo:

#! /bin/sh

FUSEMESSAGEBROKER_HOME=/opt/fuse-message-broker-5.3.1

start(){
echo "Starting Fuse Message Broker 5.3.1
sudo -u fuse-message-broker sh ${FUSEMESSAGEBROKER_HOME}/bin/activemq > /home/fuse-message-broker/logs/out.log
}
stop(){
echo "Stopping Fuse Message Broker 5.3.1"
sudo -u fuse-message-broker sh ${FUSEMESSAGEBROKER_HOME}/bin/activemq-admin stop >> /home/fuse-message-broker/logs/out.log
sleep 60
}
restart(){
stop
start
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo "Usage: fuse-message-broker {start|stop|restart}"
exit 1
esac
exit 0


Para inicializar o nosso broker utilizamos o seguinte comando:

sudo service fuse-message-broker start

Para parar o mesmo utilizamos:

sudo service fuse-message-broker stop

Para acompanhar a saída da nossa instância (que não está sendo redirecionada para a saída padrão) devemos executar o seguinte comando:

tail -f /home/fuse-message-broker/logs/out.log

Futuramente configuraremos nosso fuse message broker para habilitar outros protocolos e otimizar seu desempenho, mas por enquanto tempo o broker rodando com as configurações padrões.

Referências:
http://fusesource.com/docs/broker/5.3/getting_started/index.html

Instalando JBoss 5.1 GA no Ubuntu Server 10.04

Neste artigo presumo que você já tenha instalado a JDK 6 e tenha o servidor ubuntu executando corretamente. Primeiramente é necessário baixar o instalador do JBoss 5.1 GA do site da jboss.org. Para efetuar o download, primeiramente criaremos uma pasta para armazenar o arquivo.

cd ~
mkdir installs
cd installs
mkdir jboss
cd jboss
wget http://sourceforge.net/projects/jboss/files/JBoss/JBoss-5.1.0.GA/jboss-5.1.0.GA.zip.MD5/download


Quando baixamos o arquivo de instalação do JBoss, este vêm em formato .zip e será necessário descompactá-lo, para efetuarmos este procedimento precisamos da ferramenta unzip. Para instalar o unzip utilize o seguinte comando (ps. quando instalo o unzip já aproveito e instalo a ferramenta zip, para compactar arquivos):

sudo apt-get install unzip zip

Instalaremos o servidor de aplicação dentro da pasta /opt executando os seguintes comandos:

unzip jboss-5.1.0.GA.zip
sudo mv jboss-5.1.0.GA


Agora vamos criar um usuário para executar o servidor de aplicação:

sudo adduser --system jboss
sudo -u jboss mkdir /home/jboss/logs


E alterar o owner da nossa pasta jboss-5.1.0.GA para o usuário jboss (para que este tenha permissão de manipular os arquivos e executar os scripts existentes na pasta. A opção -R adiciona a permissão de forma recursiva para as subpastas e arquivos):

sudo chown jboss /opt/jboss-5.1.0.GA -R

E para facilitar nossa vida, vamos criar um script que permite inicializar o jboss como serviço no linux:

cd /etc/init.d/
sudo pico jboss


E insira o seguinte conteúdo no script em criação:

#! /bin/sh

JBOSS_HOME=/opt/jboss-5.1.0.GA

start(){
echo "Starting jboss.."
sudo -u jboss ${JBOSS_HOME}/bin/run.sh -b 0.0.0.0 > /home/jboss/logs/out.log &
}

stop(){
echo "Stopping jboss.."
sudo -u jboss ${JBOSS_HOME}/bin/shutdown.sh -S >> /home/jboss/logs/out.log &

#give time to shutdown jboss services.
sleep 60

#kill all java services started by user jboss
su -l jboss -c 'killall java'
}

restart(){
stop
start
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo "Usage: jboss {start|stop|restart}"
exit 1
esac

exit 0


Confirme que o script possui permissão de execução:
ls -l

e caso não tenha execute o seguinte comando:

sudo chmod +x jboss

E então use o seguinte comando para inicializar o jboss:

sudo service jboss start

Para parar o serviço do jboss basta executar:

sudo service jboss stop

E caso decida inicializar o serviço do jboss ao inicializar o sistema opercional, basta executar o seguinte comando:

sudo update-rc.d /etc/init.d/jboss defaults

Caso queira acompanhar a inicialização, basta seguir os seguintes passos:

sudo service jboss start

Mudar de terminal

tail -f /home/jobss/out.log

Referência:

http://dhydrated.wordpress.com/2009/09/25/setup-jboss5-in-ubuntu/

terça-feira, 8 de junho de 2010

Hierarquia de Sistema de Arquivos para instalação e distribuição de Aplicativos Linux

Ontem estava discutindo com um amigo sobre qual seria a melhor estrutura de instalação para um software no sistema operacional linux, e então resolvi fazer uma pesquisa simples á respeito do assunto. Simplificando a explicação, vamos utilizar como exemplo um servidor de aplicações (i.e. Weblogic). Em um cenário ideal, colocaríamos o software em /usr, os arquivos de configuração em /etc, as aplicações do servidor em /srv e por fim os logs em /var/log.

Esta seria a estrutura ideal porém muitos aplicativos não permitem tal divisão. Como exemplo disso temos o JBoss Application Server, que até a versão 5.1 não permitia que os arquivos de configuração fossem colocados em /etc. Neste caso, muitas vezes o problema pode ser resolvido colocando o seu software em /usr/local ou /opt. Este procedimento não é a melhor opção, mas ainda assim é uma prática válida.

Existe um site destinado a explicar a hierarquia de sistema de arquivos para linux (http://proton.pathname.com/fhs/) e este descreve as melhores práticas para instalação de softwares em estrutura linux para desenvolvedores e administradores de servidores.

Referências:
http://chiralsoftware.com/linux-system-administration/jboss-server-deployment.seam

quarta-feira, 19 de maio de 2010

Unified Process e Use Case Points: Transparência nos Prazos sem Esforços Adicionais

Atualmente presenciamos um grande crescimento da utilização do Unified Process (UP) como metodologia de desenvolvimento de software no mercado, porém, a maioria das empresas continuam utilizando Análise por Pontos de Função (Function Point Analisys ou FPA) para extrair métricas de software e gerar estimativas sem sequer estudar outras possibilidades existentes. Neste artigo introduziremos o método de Use Case Points (UCP), ressaltaremos seus pontos positivos, os pontos negativos, apresentaremos uma breve sugestão de como implantar o mesmo em empresas durante o processo de adoção do UP e concluiremos com um breve comentário sobre os temas abordados.

O UP determina que para obtermos o bom andamento de um projeto é necessário que os casos de uso sejam identificados, diagramados e descritos de forma correta pois estes definem as funcionalidades que devem ser entregues ao fim do projeto. Nada melhor que utilizar um documento que lista os requisitos funcionais para medir o tamanho do software a ser desenvolvido. O método UCP foi proposto em 1993 por Gustav Karner e têm como objetivo permitir que seja possível estimar o tamanho de um sistema durante a fase de levantamento de casos de uso, ou seja, aproveitar os diagramas de casos de uso criados por exigência da metodologia e o conhecimento dos analista que os desenvolveram em relação ao projeto para dimensionar o sistema a ser implementado.

Utilizando UCP para extração de métricas teremos um procedimento condizente com a metodologia que estamos implantando, aproveitaremos o conhecimento dos analistas de sistema que efetuaram o levantamento de requisitos e criaram os casos de uso, teremos apoio de documentos previamente aprovados pelo cliente (diagramas de casos de uso) para explicar os prazos e esforços apresentados para desenvolver uma determinada funcionalidade solicitada. Desta forma não dependeremos de protótipos de telas para realizar a mensuração na fase inicial do projeto, tendo em vista que o desenvolvimento de protótipos de tela não são obrigatórios para a utilização do UP e o desenvolvimento de casos de uso na disciplina de requisitos são.

Depois de apresentarmos alguns pontos positivos devemos apresentar também os pontos negativos, sendo que durante a sugestão de implantação perceberemos que nem todos são necessariamente problemas na adoção e podem ser facilmente contornados. O UCP é um método que não disponibiliza muita fonte para consultas, dificultando o aprendizado para os interessados e também o solucionamento de dúvidas devido a existirem poucos profissionais capacitados. Atualmente este método não possui nenhum órgão certificador, impossibilitando desta forma, comprovar o conhecimento através de provas ou algo semelhante. Existem poucos profissionais com conhecimento avançado na criação de casos de uso, o que conduz a diagramas com decomposição funcional ou até mesmo diagramas “CRUD” (Create, Read, Update, Delete), como são conhecidos no mercado, resultando na extração de métricas incorretas. O UCP exige que uma base prévia de conhecimento seja utilizada para refinar as estimativas geradas, e esta base, devido a mudança do procedimento, dificulta ou até mesmo inviabiliza o reaproveitamento de conhecimentos adquiridos em projetos anteriores.

Inicialmente os pontos negativos parecem ser muito fortes, porém, através de uma análise mais detalhada podemos ver que a maioria destes podem ser contornados ou até mesmo utilizados como pontos positivos. Utilizar o UCP inibe a criação de diagramas de casos de uso incorretos pois os erros impactariam diretamente na estimativa de esforços para desenvolver o projeto, forçando a revisão dos diagramas previamente citados. Os casos de uso são utilizados para eliminar compreensões ambíguas e, para o sucesso de um projeto baseado na metodologia UP é essencial que o time seja composto por profissionais capacitados em desenvolvê-los com eficiência e corretude. Todos estes fatores agregam pontos ao acerto do dimensionamento do projeto e também a criação de diagramas de caso de uso corretos.

Para explicar como solucionar o problema de criação de uma base de conhecimento com informações de projetos anteriores exigida pelo UCP, utilizaremos a sugestão de procedimento de implantação citado no início do artigo. Quando uma corporação define migrar para o UP, a estratégia mais coerente (na maioria dos casos) é preparar um time, selecionar as disciplinas a serem implantadas inicialmente e destinar um projeto pequeno e de baixo risco á utilização da metodologia. Ao fim deste , os profissionais com o conhecimento adquirido atuam como mentores em outros projetos, que passam a utilizar a nova metodologia e o conhecimento vai sendo difundido na empresa de forma transparente. Neste processo, podemos mesclar a adoção do UCP, realizando a extração de métricas através deste método, durante o projeto inicial baseado em UP. Ao fim do projeto populamos a base de conhecimento, que crescerá juntamente com a utilização do UP dentro da corporação. Este procedimento torna transparente o impacto da falta de experiências passadas com UCP e faz com que a evolução seja transparente aos envolvidos.

Devido a todos os fatores apresentados anteriormente, acredito que o UCP já está suficientemente maduro para ser aplicado em ambientes corporativos e a sua utilização reforça a importância dos casos de uso bem definidos em um projeto baseado em Unified Process. Sua utilização auxilia na identificação de erros em requisitos ou casos de uso, sendo esta mais uma oportunidade de identificar casos de uso mal desenvolvidos que poderiam conduzir o projeto ao fracasso. Devido a sua afinidade com a metodologia UP, o crescimento da sua utilização é inevitável, tornando desta forma o procedimento para estimativas e mensuração de sistemas mais natural, transparente e preciso.

terça-feira, 18 de maio de 2010

Configurando o Samba para integração Windows/Linux no Ubuntu 10.04 LTS Server

Este procedimento foi executado em uma máquina virtual configurada sobre o Windows 7. O software de virtualização utilizado foi o VMWare Workstation. O Samba é um componente que permite a integração entre o Windows e o Linux (mais em http://www.samba.org/). No final da instalação do Ubuntu 10.04 LTS Server são oferecidos diversos serviços adicionais que podem ser instalados (ex. LAMP, DNS, etc) e um destes é o Samba.

Caso não tenha selecionado a sua inclusão durante a instalação do sistema operacional, é possível instalar o pacote através do aptitude (Gerenciador de pacotes do Ubuntu). Para instalar o samba e os componentes necessários devemos executar o seguinte comando:

sudo apt-get install samba

Para configurar o serviço, primeiramente necessitamos pará-lo, logo, Ubuntu 10.04 utilizamos o comando:

sudo service smbd stop

Enquanto que nas versões anteriores utilizávamos o comando:
sudo /etc/init.d/samba stop

Agora que já instalamos os pacotes necessários, precisamos começar a configuração do Samba. A configuração é feita no arquivo smb.conf, porém, devido a possibilidade de cometer algum erro, primeiramente efetuaremos um backup do arquivo existente (default):

sudo mv /etc/samba/smb.conf /etc/samba/smb.conf.template

Então efetuaremos um comando touch para alterar a data de criação/modificação do arquivo que será alterado (o comando touch cria um arquivo caso este não exista ou altera a data de criação/modificação caso o mesmo já exista):

sudo touch /etc/samba/smb.conf

O passo anterior não é obrigatório porém modifica as propriedades do arquivo que iremos alterar e facilita a distinção do mesmo. Agora efetuaremos as alterações necessárias para que a integração funcione:

sudo pico /etc/samba/smb.conf

Abaixo está a configuração que deve ser inserida no arquivo smb.conf:

[global]
; Configurações gerais do servidor
netbios name = NOMEDAMAQUINALINUX
server string =
workgroup = WORKGROUPDOWINDOWS
announce version = 5.0
socket options = TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192

passdb backend = tdbsam
security = user
null passwords = true
username map = /etc/samba/smbusers
name resolve order = hosts wins bcast

; defina como yes caso sua máquina windows possua um IP fixo e no para máquinas
; com IP dinâmico.
wins support = yes

printing = CUPS
printcap name = CUPS

syslog = 1
syslog only = yes

; NOTE: Caso você necessite de acesso aos diretórios home do usuário descomente
; as linhas abaixo e configure de acordo com a sua necessidade
;[homes]
;valid users = %S
;create mode = 0600
;directory mode = 0755
;browseable = no
;read only = no
;veto files = /*.{*}/.*/mail/bin/

; NOTE: É necessário configurar caso você execute o samba em um controlador de
; domínio primário.
; Não cobrimos configuração de controlador de domínio primário aqui.
;[netlogon]
;path = /var/lib/samba/netlogon
;admin users = Administrator
;valid users = %U
;read only = no

; NOTE: É necessário configurar caso você execute o samba em um controlador de
; domínio primário.
; Não cobrimos configuração de controlador de domínio primário aqui.
;[Profiles]
;path = /var/lib/samba/profiles
;valid users = %U
;create mode = 0600
;directory mode = 0700
;writeable = yes
;browseable = no

; NOTE: Aqui configuramos um local para construir repositório de drivers de
; impressora para o windows. Não foi coberto aqui.
[print$]
path = /var/lib/samba/printers
browseable = yes
guest ok = yes
read only = yes
write list = root
create mask = 0664
directory mask = 0775

[printers]
path = /tmp
printable = yes
guest ok = yes
browseable = no

; Descomente as linhas abaixo caso precise compartilhar o CD/DVD-ROM
;[DVD-ROM Drive]
;path = /media/cdrom
;browseable = yes
;read only = yes
;guest ok = yes

[MyFiles]
path = /media/samba/
browseable = yes
read only = no
guest ok = no
create mask = 0644
directory mask = 0755
force user = NOMEDEUSUARIOWINDOWS
force group = NOMEDEUSUARIOWINDOWS


Nas configurações demonstrada acima existem alguns valores que devem ser substituídos para a sua necessidade. Os valores são:

NOMEDAMAQUINALINUX = Nome da máquina windows envolvida na configuração. Pode ser obtido clicando com o botão direito sobre o ícone "Meu Computador", selecionando "Propriedades" e verificando o "Nome da Máquina".
WORKGROUPDOWINDOWS = para encontrar o valor a ser inserido no lugar deste texto devemos seguir o mesmo procedimento mencionado acima, porém desta vez verificando o item "Grupo de Trabalho".
NOMEDEUSUARIOWINDOWS = Nome do usuário utilizado para entrar no windows. Pode ser verificado navegando em "Painel de Controle", "Contas de Usuários" e então "Modificar Sua Foto". Na parte superior da janela será exibido seu nome de usuário.

Após finalizarmos a criação do arquivo acima precisamos criar o diretório a ser compartilhado e alterar suas permissões:

sudo mkdir /media/samba
sudo chmod 0777 /media/samba

Agora devemos inicializar o serviço novamente utilizando o seguinte comando no Ubuntu 10.04 LTS Server:

sudo service smbd start

Ou o seguinte comando em versões anteriores:

sudo /etc/init.d/samba start

Nosso serviço está em execução, porém é necessário inserir e habilitar um usuário para autenticação do windows no nosso servidor linux. Esse procedimento é executado da seguinte forma:

sudo useradd -s /bin/true NOMEDEUSUARIOWINDOWS
sudo smbpasswd -L -a NOMEDEUSUARIOWINDOWS
sudo smbpasswd -L -e NOMEDEUSUARIOWINDOWS


Finalizamos a configuração do Samba no nosso servidor e para efetuar um teste retornamos ao Windows e clicamos em "Iniciar", Selecionamos "Programas", "Acessórios" e então "Executar" ou pressionamos o atalho "Win + r". Na caixa que será aberta digitaremos o seguinte comando caso a configuração de wins tenha sido definida como "yes" (Máquinas com IP fixo):

\\NOMEDAMAQUINALINUX\MyFiles

ou o seguinte comando caso wins tenha sido definida como "no" (Máquinas com IP dinâmico):

\\IPDAMAQUINALINUX\MyFiles

Para pegar o ip da máquina linux basta acessar o servidor e digitar o seguinte comando em um terminal:

ifconfig

Agora sua máquina Windows consegue acessar um diretório do servidor Linux e esperamos que isso facilite sua transferência de arquivos entre um servidor de desenvolvimento ou uma máquina virtual. Lembramos que não é seguro liberar compartilhamento de pastas em servidores e este procedimento deve ser executado com parsimônia. Caso queira aumentar um pouco a segurança do compartilhamento é possível definir as interfaces de rede através das quais o compartilhamento pode ser acessado inserindo a seguinte linha no smb.conf:

[global]
...
interfaces = lo, eth0 ; apenas acesso local ou através da interface eth0
; que normalmente é a interface para RJ45.
bind interfaces = true;

Finalizamos assim a configuração do Samba no Ubuntu 10.04 LTS Server e estamos prontos para acessar a pasta e transferir arquivos entre nossa máquina Windows e Linux.

Referência:
http://ubuntuforums.org/showthread.php?t=202605

Instalando o MySQL 5.1 no Ubuntu 10.04 LTS Server

Ontem instalei o MySQL no Ubuntu 10.04 LTS Server e o procedimento foi bem simples. O passo a passo explicado abaixo foi realizado utilizando uma máquina virtual (VMWare) e esta tinha acesso a internet através de NAT.

Minha instalação do ubuntu estava limpa, então tive que editar a lista de recursos para que o apt me oferecesse todos os pacotes necessários. Para isso executei o comando:

sudo pico /etc/atp/sources.list

removi os comentários de repositórios indisponíveis (para isto basta remover o caracter # da linha a ser descomentada). Fechei o arquivo (ctrl + x) e mandei que salvasse na saída (ctrl + s).

Após atualizar o arquivo sources.list, executei o comando para que o apt verificasse os novos repositórios e disponibilizasse os softwares para instalação:

sudo apt-get update

Neste ponto o sistema operacional estava pronto para a instalação do MySQL, o qual foi executado com o seguinte comando:

sudo apt-get install mysql-server-5.1 libmysqlclient16-dev

Quando terminamos a instalação da base de dados o serviço é automaticamente inicializado. Para verificar se este foi inicializado com sucesso podemos verificar se existe alguma porta ouvindo requisições para o mysql através do comando:

netstat -tap

Caso este não tenha sido inicializado podemos fazê-lo através do comando:

sudo service mysql start

Por questões de segurança o MySQL permite conexões apenas do localhost (default bind address). Para aceitarmos conexões de endereços externos devemos abrir o arquivo my.cnf através do comando:

sudo pico /etc/mysql/my.cnf

e comentar a linha:

bind-address = 127.0.0.1

Para comentar a linha basta adicionar um # no começo:

# bind-address = 127.0.0.1

Após todas essas alterações reiniciei o serviço utilizando o comando

sudo service mysql restart

Para reforçar um pouco a segurança do servidor de base de dados efetuei alguns procedimentos básicos. Primeiramente conectei no Mysql através do seguinte comando:

mysql -u root -p

O prompt bash mudou para:

mysql>

indicando que estava dentro do aplicativo cliente, conectado ao MySQL. Então executei um comando para indicar que gostaria de utilizar a base de dados mysql:

use mysql;

Após executar este comando, executei um procedimento para remoção de possíveis contas de usuário guest (convidado) e atualizar os privilégios:

DELETE FROM user WHERE user='';
FLUSH PRIVILEGES;
EXIT;

Depois de executar estes procedimentos a configuração básica do servidor MySQL na minha máquina virtual estava disponível para uso. Futuramente colocarei instruções para reforçar a segurança da base de dados.