Feed Artigos Comentários

Arquivo de CategoriasJava



Java & Dicas Hildebrando em 15 Out 2008

Java no Ubuntu : Inicio

Estamos fazendo um estudo para migrar as estações de desenvolvimento que não são .NET para o Sistema Operacional Ubuntu.

Nosso primeiro requsito é a parte de instalação do JDK no Ubuntu e para isso é preciso intalar o Java e configurar a variavel de ambiente JAVA_HOME.

Instalar o Java, pode ser feito tanto pelo gerenciador de pacotes do Ubuntu quanto fazendo download pelo site da Sun. Se for feito pelo gerenciador a opção que se tem é o OpenJDK e é so fazer um next>next>finish, sem mistério.

Se for baixar do site da Sun (http://java.sun.com) baixe a versão binaria (é a não RPM).

O unico detalhe é que o arquivo não vem executável, para isso :

chmod 777 jdk1.5....

Execute o arquivo

./jdk1.5...

Após a instalação do JDK ser realizada com sucesso o próximo passo é configurar a variável de ambiente.

Para que todos os usuarios acessem essa variavel de ambiente, é preciso adicionar algumas configurações nos arquivos /etc/bash.bashrc e /etc/profile.

As configurações precisam ser feitas nos dois arquivos pois um é para login shel (console) e o outro é login no shel (gnome por exemplo).

export JAVA_HOME=/usr/lib/jdk1.5
export PATH=$JAVA_HOME/bin:$PATH

Noticias & Java & Desenvolvimento de Software Hildebrando em 08 Jul 2007

Projeto querotrabalharcomjava.com.br

Colocamos no ar um produto 2Solutions chamado “www.querotrabalharcomjava.com.br”. Basicamente é uma iniciativa para capacitar o pessoal que esta querendo entrar no mercado de trabalho Java.

Vale a pena para pessoas que tem conhecimento na linguagem (fizeram cursos ou aprenderam na faculdade) mas não conseguiram o seu emprego na área pois as empresas querem pessoas com experiência (mesmo para Junior - contraditório não ?), ou mesmo para quem esta procurando uma recolocação para a área de desenvolvimento Java.

Para valores e mais informaçoes acessar o site http://www.querotrabalharcomjava.com.br.

Java & Desenvolvimento de Software Hildebrando em 01 Jun 2007

Projeto OpenSource (GPL) - Hibernate Web Paginator

Colocamos no java.net o projeto Hibernate Web Paginator. É uma biblioteca para facilitar a criação de tabelas de paginação nas aplicações que usam Hibernate. O grande diferencial da biblioteca frente a outras implementações é a simplicidade e também a integração com Hibernate, possibilitando paginações com recursos de maxResults, ou seja, evitar apenas as paginações com dados de sessão.

Se quiser participar é só entrar no endereço https://hibernatewebpaginator.dev.java.net

Java Hildebrando em 24 Nov 2006

Trabalhando imagens com Java.

A API de Java para tratamento de imagens é bem complexa. Envolve decodificadores, renderizadores, byte[] para ca, byte[] para la, BufferedImage, etc. Para servir de repositorio tanto para mim quanto para quem visitar esta pagina sempre que eu (ou alguem que ajudar) desenvolver um novo util para tratar imagens eu posto aqui.


public static void gerarThumbnail(InputStream inputStream, OutputStream out, int thumbAltura, float quality) throws Exception{

Image image = null;
int largura = 0;
int altura = 0;

try {
//Recuperar os valores de LARGURA/ALTURA e ALTERAR no registro da FOTO
image = ImageIO.read(inputStream);
largura = image.getWidth(null);
altura = image.getHeight(null);
} catch (Exception e) {
throw new Exception("ERRO ALTERANDO TAMANHO DA IMAGEM " + e);
}

try {

//Fazer a geracao do TumbNail levando em conta o tamanho da ALTURA
MediaTracker mediaTracker = new MediaTracker(new Container());
mediaTracker.addImage(image, 0);
mediaTracker.waitForID(0);

// determine thumbnail size from WIDTH and HEIGHT
double thumbPorcentagem = ((thumbAltura*100.0)/altura)/100.0;
int thumbLargura = (int)(largura * thumbPorcentagem);

// draw original image to thumbnail image object and
// scale it to the new size on-the-fly
BufferedImage thumbImage = new BufferedImage(thumbLargura,thumbAltura, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = thumbImage.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC); //For speed better use RenderingHints.VALUE_INTERPOLATION_BILINEAR
graphics2D.drawImage(image, 0, 0, thumbLargura, thumbAltura, null);

// save thumbnail image to OUTFILE
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(thumbImage);

param.setQuality(quality, false); //The quality argument from the command line is converted from the interval 0 to 100 to the interval 0.0f to 1.0f, because that's what the codec expects (I mostly use 0.75f).
encoder.setJPEGEncodeParam(param);
encoder.encode(thumbImage);
out.close();

} catch (Exception e) {
throw new Exception("ERRO SALVANDO O THUMBNAIL DA IMAGEM " + e);
}
}

public static void gerarWatermark(InputStream imagemOriginal, InputStream imagemWatermark, OutputStream imagemGerada){

try {

BufferedImage im = ImageIO.read(imagemOriginal);
BufferedImage im2 = ImageIO.read(imagemWatermark);
Graphics2D g = im.createGraphics();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
g.drawImage(im2, (im.getWidth()-im2.getWidth())/2, (im.getHeight()-im2.getHeight())/2, null);
g.dispose();
ImageIO.write(im, "jpeg", imagemGerada);

} catch (Exception e) {
System.out.println(e);
}
}

public static void gerarWatermark(InputStream imagemOriginal, String textoWatermark, OutputStream imagemGerada){

try {

BufferedImage im = ImageIO.read(imagemOriginal);

//Preparando o Graphics 2D para incluir o texto na imagem
Graphics2D g = im.createGraphics();
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

//Setar a font utilizada no texto
g.setFont(new Font("Lucida Bright", Font.ITALIC, 60));

//Efeitos de rotacao no texto
g.rotate(-Math.PI/4, im.getWidth()/2, im.getHeight()/2);

//Setando o valor do texto
TextLayout tl = new TextLayout(textoWatermark, g.getFont(), g.getFontRenderContext());

//???
Rectangle2D bounds = tl.getBounds();
double x = (im.getWidth()-bounds.getWidth())/2 - bounds.getX();
double y = (im.getHeight()-bounds.getHeight())/2 - bounds.getY();

//
Shape outline = tl.getOutline(AffineTransform.getTranslateInstance(x+2, y+1));

//Montando a saida
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
g.setPaint(Color.WHITE);
g.draw(outline);
g.setPaint(new GradientPaint(0, 0, Color.WHITE, 30, 20, new Color(128,128,255), true));
tl.draw(g, (float)x, (float)y);
g.dispose();

ImageIO.write(im, "jpeg", imagemGerada);

} catch (Exception e) {
System.out.println(e);
}
}

Java Hildebrando em 04 Nov 2006

Desenvolvimento de Aplicativos para dispositivos móveis.

A ideia de desenvolver um aplicativo para um celular ou PDA envolve um plano diferente. Parece que você esta entrando em um seleto grupo de profissionais, aquela força tarefa que faz as coisas acontecerem. Você esta saindo do arroz com feijão WEB-Struts-Hibernate (Arroz-com-feijão bem servido por sinal).

Na semana passada fiz um mentoring para uma grande empresa integradora de telefonia, e como havia muita comparação entre tecnologias, quero compartilhar algumas ideias.

Primeiramente vou tratar neste artigo da tecnologia J2ME (Java Micro Edition). Apresentar alguns pontos e após você estar craque vamos aos obstáculos.

1 - Inicio

Java você ja sabe, então precisamos aplicar este conhecimento em APIs diferentes. A boa notícia é que as specs para trabalhar com J2ME são simples. Pense que para programar para um celular os seus recursos são limitados e portanto o que diferencia é a forma como você deve utiliza-las.

Existem muitas ferramentas com plugins para tratamento deste mercado móvel. Vamos fugir delas, por enquanto.

Comece baixando o WTK da Sun - Sun Java Wireless Toolkit 2.2. A Sun possue um Kit (gratuito) para desenvolvimento de J2ME. A maioria dos fabricantes possue o seu, com a vantagem da utilização de emuladores do próprio. Porém isso não afeta em nada o seu software, apenas pode deixar voce mais confortavel em determinados trabalhos. Obrigatório porém se o que você procura é utilizar as APIs proprietárias.

A instalação é muito simples. Famoso Next,Next,Finish.

2 - Código

O WTK é um empacotador de projetos, ou seja, ele não é um editor/compilador. Sua unica tarefa é criar o seu projeto, organizando seus arquivos em pastas específicas e construção do pacote para deploy. Para completar ele possue alguns emuladores para você testar seu código.

Comece criando seu projeto no WTK.

a) Execute o Ktoolbar
b) New Project [Project Name : WhereIsWally][MIDlet Name : WhereIsWally]
c) Mude em ‘Configurations’ para CLDC 1.1

Seu diretorio de trabalho será:

\WTK22\apps\WhereIsWally\src

Todo aplicativo que você for desenvolver deve seguir um contrato de código. Este contrato é estabelecido pela classe abstrata javax.microedition.midlet.MIDlet. Por tanto abra o seu editor Java favorito e construa esta classe.


public class WhereIsWally extends MIDlet {
}

A ideia de você estender da classe MIDlet é tanto para herdar alguns metodos quanto para definir outros.


import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class WhereIsWally extends MIDlet {
public void startApp() {
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}
}

Ao digitar este codigo lembre-se de adicionar no classpath do seu editor ou do sistema os jars midpapi20.jar e cldcapi11.jar. Ambos estão no diretorio lib, dentro do diretorio de instalação do WTK.

Os metodos apresentados acima são chamados de métodos de ciclo de vida e como o nome de cada um ja descreve são invocados a cada mudança de estado. Portanto lembre-se quem chama estes métodos é o Dispositivo móvel, e não o seu código.

Assim toda vez que o MIDlet for inicializado, o método startApp sera invocado, por exemplo.

3 - Código Usual

Para prosseguirmos com o processo de aprendizado você deve rechear os métodos com chamadas a API JME. E é somente estas APIS que podem ser utilizadas. Lembre-se que você esta desenvolvendo não mais com JSE, portanto algumas funcionalidades foram retiradas. A classe String por exemplo perdeu muitos dos seus métodos, a classe Math também, o pacote io mais ainda, as bibliotecas graficas AWT e SWING não existem. E muitas outras coisas.

Portanto para você saber o que você pode utilizar veja a documentação referente ao CLDC - JSR139. Imagine esse CLDC como o conjunto de classes fundamentais.

Porém só o CLDC não vai te levar a muito lugar não. Você precisa utilizar de recursos mais funcionais como acesso a chamadas HTTP por exemplo, ou utilização de sons e animações. Para isso voce deve conhecer o Profile MIDP - JSR118. Pense em Profile como recursos adicionais a parte core.

As APIs são curtas no entanto com um certo grau de complexidade (senão não existiram cursos de JME). Para impressionar seus amigos faça um programa bem básico.


import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class WhereIsWally extends MIDlet {
public void startApp() {
Alert alert = new Alert("Titulo","Texto no Alerta",null,AlertType.INFO);
Display.getDisplay(this).setCurrent(alert);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}
}

WTK >> Build >> Run

Esse é o HelloWorld. As APIS são simples, e bem organizadas. Seguindo sua estrutura hierárquica da para entender bem o que pode se colocar na tela ou não.

4 - High-level

Em JME existe a categoria de componentes de alto nível como o Alert, utilizado no exemplo anterior. A principal caracterítica deles é a facilidade na utilização, porém com isso é sacrificado a parte de customização, que pode ser essencial em alguns projetos. Existem outro componentes como o TextBox, List e o Form que também estão na mesma categoria. O principio da utilização deles é o mesmo. Instanciar um objeto e chamar o Display.getDisplay(this).setCurrente(objeto_criado).

O Form é o mais utilizado pois este possibilita agregar outros componentes dentro dele. Todos os filhos de Item. Assim montando uma tela com vários componentes.

5 - Low-level

E se você quiser criar uma tela de Splash ou um botão customizado ou mesmo um gráfico? Para isso você precisa conhecer os componentes de low-level, ou seja, aqueles que você vai desenhar, tratar eventos de tecla e tudo mais. Na AWT existe um objeto com essa funcionalidade. É o Canvas. Então no desenvolvimetno JME ele esta de volta, porém com algumas limitações, mas seguindo o mesmo modelo de desenhar utilizando o objeto Graphics (drawString, fillRect, etc).

6 - Jogos

Os jogos ganharam o pacote javax.microedition.lcdui.game (MIDP 2.0). Use e abuse deste pacote pois ele contem inumeras vantagens sobre o canvas no que se refere a parte de buferização para atualização da tela, essencial em jogos para garantir o dinamismo.

7 - Eventos

O tratamento de eventos é diferente para High-level, low-level e games. Para os de alto nível você precisa criar Listeners, parecido com o padrão AWT/Swing. Para os de low-level voce captura as teclas sobreescrevendo métodos específicos por ação como keyPressed. Para os games o tratamento é um pouco diferente pois obriga a verificação se o botão foi apertado através do start() de uma Thread. Esta garante a velocidade do jogo também.

8 - GCF

Generic Connection Framework é o comunicador com qualquer coisa. Se você quer abrir um Socket, enviar uma requisição HTTP ou enviar um SMS é através deste conjunto de classes que você vai conseguir. Pela especificação somente HTTP e HTTPS são mandatórios no MIDP 2.0, portanto você deve verificar se o dispositivo suporta as outras formas.

9 - Fim

Agora que você ja conhece boa parte da API e algumas funcionalidades vamos adiantar algumas restrições.

1 - Componente de High-level é de alto-nível mesmo. Se você não achar o método que o customize, esqueça. Quem o implementa é o dispositivo, assim se você manda abrir um Alert, este sera apresentado de acordo com o Alert do dispositivo.

2 - Para customizar um componente de High-level tente antes criar um com o CustomItem. Somente se não tiver possibilidade de adapta-lo baixe o nível para Canvas.

3 - A implantação em um celular envolve a geração de 2 arquivos, um JAR e um JAD. o JAD é um arquivo texto com um conjunto de pares chave/valor que descrevem sua aplicação, o arquivo JAR contem as suas classes compactadas. Para fazer a atualização do aplicativo no dispositivo utilize sempre o AMS (Gerenciador de Aplicações) pois nele podem ser configuradas regras de segurança. Para protegere seu codigo procure utilizar ofuscadores. Estes conseguirão embaralhar o codigo de forma que se alguem descompilar o seu JAR perderá muito tempo para entender seu algoritmo.

4 - Recurso vale ouro. Procure sempre declarar tipos pequenos como byte e short. Procure desenvolver regras de reutilização de objetos.

Java Hildebrando em 20 Set 2006

Hibernate do começo ao fim - Diálogo do Sr. com o Jr.

Diálogo entre o pessoal de Desenvolvimento.

Sr. : Entao, neste projeto utilizaremos Hibernate?
Jr. : É mesmo? Ja ouvi falar, mas é bom mesmo? Me parece que voce não precisa mais fazer Query? Parece meio utópico isso ein.
Sr. : É bem interessante. Com o lance do mapeamente O/R da para ter uma produtividade muito grande. Facilita muito. Faz o seguinte, da uma olhada no tutorial do guj http://www.guj.com.br/java.tutorial.artigo.174.1.guj que da para você entender bem.
Jr. : Beleza, mas como funciona esse mapeamento? É com XML?
Sr. : Isso, da uma olhada no tutorial que vc vai entender bem.
// Alguns Exemplos, POJO e Hbm depois
Jr. : Estou tendo um problema que é o seguinte. Tem um tal de Lazy Loading que nao ta dando certo. Quando eu quero acessar um objeto de dentro de outro objeto ta dando pau. Parece que a sessao esta fechada.
Sr. : O lance é conceitual. Aqui no seu DAO, voce esta fazendo o seguinte. Pegar o session, executar a query e fechar o session. Quando o JSP for ser renderizado é neste momento que sera feito o acesso aos atributos Lazy (Lazy que dizer preguiçoso, ou seja, so sera feito a busca deste objeto quando for necessário). O que acontece é que você não pode fechar a sessão.
Jr. : Mas dai vou deixar a sessao aberta?
Sr. : Negativo. O que vc vai fazer é abrir e fechar em outro momento. Utilizando um filtro para esse controle é uma boa. Da uma olhada nesse link http://www.hibernate.org/43.html
Jr. : Mas utilizar um filtro? Nao vou estar misturando as camadas (Hibernate na view)?
Sr. : Da forma como esta implementada o artigo não. Da uma olhada no artigo.
//Depois de implementado o Filter
Jr. : Poxa, mas nao ta salvando. Que #?*&% esse Hibernate.
Sr. : Calma. Voce lembra do artigo? Para operações de insert/update/remove voce tem que abrir uma transação. Senão nao rola.
Jr. : Ah tá. Beleza.
//Transação com begin no filtro e comit no filtro também.
Jr. : Poxa, ta dando um outro erro. Se da problema no Servlet o filtro nao esta retornando para a tela de retorno do servlet. Poxa, estragou tudo. Preciso arrumar uma forma de passar a pagina de retorno do Servlet para o filtro para ele poder fazer o dispatcher disso. Como vou fazer? $%¨&# Hibernate.
Sr. : Calma. O lance é conceitual de novo. Você não pode abrir uma transação no filtro, pois o Hibernate só da flush das querys no commit. Assim o seu servlet ‘pensa’ que esta tudo ok, porém quando for feito o commit, la no filtro, vai dar pau. A parte de transação é uma funcionalidade de Negocio, portanto deve ser feita na camada de negócio. Da uma olhada em outro tutorial do guj.http://www.guj.com.br/java.tutorial.artigo.182.1.guj
//Transacao com Hibernate implementada.
Jr. : Nooooooooooosa. Show de bola ein. Poxa, sem comentarios, quando for um metodo transacional é só colocar o Annotation la. Elegancia.
Sr. : Pois é. Este é so o começo. Depois você da uma estudada em ferramentas de mapeamento, para gerar os HBM de acordo com suas tabelas, também tem toda a parte de cache, muito legal,porém o tipo de aplicação é influenciada diretamente nisso, também tem a parte da utilização do DataSource do Servidor, mapeamento de coleções, mapeamentos avançados como timestamp, version, herança, etc. Mas entendendo esses conceitos principais de mapeamento, session e transação, o resto é só correr atras.

Esse diálogo representa os pontos importantes da utilização do framework Hibernate. O caminho é meio arduo porém como tem mais carga conceitual do que decoração de API. Boa Sorte