You are currently browsing the category archive for the 'Java' category.
Dizem que, em Java, tudo é muito complicado. Lidar com arquivos XML então, nem se fala. Agora imagine isso:
MinhaClasse objeto = new MinhaClasse(parametros);
Perfeito, instanciei um objeto da minha classe. Vamos transformar em XML rapidinho?
XStream xstream = new XStream(new DomDriver()); String xml = xstream.toXML(objeto);
O responsável por esta mágica é o XStream, que pode ser encontrado em http://xstream.codehaus.org/
Palavras-chave: Java, classes não encontradas, classpath
Os erros NoClassDefFoundError e ClassNotFoundException acontecem com frequência em aplicações Java e é importante entendê-los com clareza, a fim de diagnosticar problemas mais rapidamente.
Ambos os erros significam essencialmente a mesma coisa: uma classe não foi encontrada. A diferença é a maneira de que esta classe estava sendo procurada.
No caso do NoClassDefFoundError, a JVM estava tentando carregar uma classe para invocar um método ou criar uma instância e não a encontrou. Isso acontece tipicamente quando a JVM encontra uma referência a uma classe que ainda não foi carregada.
Para provocar isso como exemplo, crie um programa com duas classes, chamadas Main e Pessoa:
public class Main {
public static void main(String[] args) {
new Pessoa();
}
}
class Pessoa {}
Compile este código manualmente (javac *.java) e execute-o. O programa deve rodar sem nenhum problema. Agora, remova o arquivo gerado chamado Pessoa.class e re-execute o programa. Isso gerará uma saída parecida com esta:
# java Main
Exception in thread "main" java.lang.NoClassDefFoundError: Pessoa
at Main.main(Main.java:3)
Quando você compilou o código, a classe Pessoa estava também sendo compilada (ela poderia estar no classpath) e instrução ‘new’ fez uma referência direta a ela. No momento de executar o código, a classe Pessoa não estava mais disponível. Isso é um erro inesperado, portanto NoClassDefFoundError é um java.lang.Error.
Já a ClassNotFoundException é uma java.lang.Exception, um tipo de erro mais “suave”. Esta exceção acontece quando alguma parte do código (seu ou de alguma classe que você utiliza) está carregando explicitamente uma classe, através de métodos como Class.forName(), ClassLoader.findSystemClass() ou ClassLoader.loadClass(). Neste caso, o código não precisa ter sido compilado junto a classe referenciada.
Considere o exemplo a seguir:
public class Main {
public static void main(String[] args) throws Exception {
Object o = Class.forName("pacote.NaoExiste").newInstance();
}
}
Isso produzirá uma saída parecida com:
# java Main
Exception in thread "main" java.lang.ClassNotFoundException: pacote.NaoExiste
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
No momento da compilação, a classe não estava presente, mas o código foi compilado sem problemas. Na execução, porém, a ausência da classe fez o carregamento explícito falhar.
Palavras-chave: Java, JavaMail, email, SMTP, SMTP autenticado
Enviar emails é uma tarefa corriqueira, mas sempre precisamos olhar um exemplo da JavaMail API para montar uma classe utilitária. A seguir, um exemplo mínimo do envio de emails através de um servidor SMTP autenticado:
public void enviarEmail(String emailDest, String nomeDest,
String emailRemet, String nomeRemet, String assunto, String corpo)
throws Exception {
Properties props = System.getProperties();
props.put("mail.smtp.host", "smtp.firma.com.br");
props.put("mail.smtp.auth", "true");
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("fulano", "suasenha");
}};
Session session = Session.getInstance(props, auth);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(emailRemet, nomeRemet));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(emailDest, nomeDest));
message.setSubject(assunto);
message.setContent(corpo, "text/plain");
Transport.send(message);
}
Para executar este código, é preciso colocar o JavaMail (mail.jar) e o Java Activation Framework (activation.jar) em seu classpath. Se você usa Java 6, não vai precisar do JAF no classpath, pois este foi embutido nesta versão do Java.
Para testar o código, pode-se fazer algo como:
enviarEmail("todos@firma.com.br", "Lista da Firma", "fulano@firma.com.br",
"Fulano da Silva", "Codare", "Gosto do Codare. E vocês?");
Se você usa emails dentro de Servidores de Aplicação, pode fazer lookup da sessão no JNDI, ao invés de criá-la passando as propriedades. Você a receberá com as propriedades setadas pelo administrador do ambiente e, como desenvolvedor, não precisará se preocupar com coisas como “qual é o servidor de email do ambiente de produção”:
Session session =
(Session) new InitialContext().lookup("java:comp/env/mail/Sessao");
Palavras-chave: ping, ICMP, java.net.InetAddress, isReachable, Java 5
A partir do Java 5, fazer ping em um servidor usando Java ficou bastante simples. É só usar o método isReachable da classe java.net.InetAddress.
O método a seguir usa isReachable para pingar um servidor com tempo limite de cinco segundos (timeout igual a 5000 milisegundos):
private static void pingar(String host) {
try {
if (InetAddress.getByName(host).isReachable(5000))
System.out.println("Ping OK: " + host);
else
System.out.println("Ping FALHOU: " + host);
} catch (Exception e) {
System.err.println("Ping FALHOU: " + host + " - " + e);
}
}
Podemos testar este código da seguinte maneira:
pingar("www.google.com");
pingar("localhost");
pingar("www.umgooglequenaoexiste.com");
E uma possível execução é:
Ping FALHOU: www.google.com Ping OK: localhost Ping FALHOU: www.umgooglequenaoexiste.com - java.net.UnknownHostException: www.umgooglequenaoexiste.com
Neste caso, o servidor do Google foi encontrado no DNS, mas não se conseguiu pingá-lo. O host local pingou fácil e o último nome não foi encontrado no DNS.
O método isReachable funciona como um ping, mas é um pouco mais que isso. A implementação normalmente tentará enviar uma mensagem ICMP Echo Request. Caso não consiga, tentará abrir uma conexão TCP à porta 7.
Palavras-chave: classpath, wildcards, caractere curinga, Java 6
O Java 6 trouxe um recurso para facilitar a vida do programador: os caracteres curinga (wildcards) na definição do classpath. O que antes você fazia assim:
java -cp lib/codare-main.jar:lib/codare-utils.jar:lib/mail.jar \\ codare.MinhaClasse
Hoje pode fazer assim:
java -cp lib/\\* codare.MinhaClasse
Isso incluirá todos os arquivos *.jar dentro do diretório lib. Note bem: apenas os jars. Se você precisar de arquivos .class em diretórios, terá que incluí-los no classpath pela maneira tradicional:
java -cp lib/\\*:classes codare.MinhaClasse
Note também:
- A barra invertida (\) é apenas um caractere de escape para que o shell não faça a expansão do asterisco (*).
- A ordem dos arquivos .jar no classpath não é garantida.
- Este recurso, apesar de suportado pelo JDK 6 da Sun, não faz parte da especificação da JVM, portanto, você pode não encontrá-lo em outras implementações.
- Os curingas são expandidos na inicialização da VM. Assim, não adianta colocar novos arquivos .jar seguindo o padrão sem reiniciar a VM.
Porém, atenção: na versão atual, os caracteres curingas da JVM não são tão espertos como os do shell. A chamada a seguir, por exemplo, não funcionaria:
$ java -cp lib/\\*.jar codare.MinhaClasse Exception in thread "main" java.lang.NoClassDefFoundError: codare.MinhaClasse
Último detalhe: estes exemplos consideram um shell tipo UNIX. Em ambientes Windows, confesso, não consegui achar um comportamento previsível.
Palavras-chave: imagem, imagens, ler, salvar, carregar, editar, JPG, JPEG, GIF, PNG, imageio
Ler e escrever arquivos de imagens em Java é tão fácil que até nem parece Java:
BufferedImage imagem = ImageIO.read(new File("mariabonita.gif"));
// fazer algo com a imagem...
ImageIO.write(imagem, "PNG", new File("mariabonita.png"));
Já que foi fácil, vamos aproveitar esta dica para aprender também como alterar os pixels da imagem. Para isso, use os métodos getRGB()/setRGB() da classe BufferedImage. O método getRGB() retorna um array de int que representa os valores RGB de cada ponto da imagem.
Se você tivesse uma matriz, você poderia referenciar os pixels como matriz[lin][col]. Mas, aqui, como na maioria dos programas de processamento de imagens, temos um array para representar a imagem. Assim, temos que usar a notação pixels[w * lin + col], onde w é a largura da imagem.
O exemplo a seguir lê uma imagem, colore-a de maneira aleatório-psicodélica e a salva em outro arquivo:
BufferedImage imagem = ImageIO.read(new File("qualquer.jpg"));
int w = imagem.getWidth();
int h = imagem.getHeight();
int[] pixels = imagem.getRGB(0, 0, w, h, null, 0, w);
Random r = new Random();
for (int col = 0; col < w; col++) {
for (int lin = 0; lin < h; lin++) {
pixels[w * lin + col] =
new Color(r.nextInt(255), col % 255, lin % 255).getRGB();
}
}
imagem.setRGB(0, 0, w, h, pixels, 0, w);
ImageIO.write(imagem, "PNG", new File("arteabstrata.png"));
Palavras-chave: Java, jps, listagem de processos, parâmetros da JVM
O JDK 6 fornece algumas ferramentas de monitoração e diagnóstico de problemas que podem ser úteis no dia-a-dia de um ambiente de produção. A mais básica delas é o jps, que lista todos os processos Java que estão sendo executados na máquina.
Por exemplo, executando-se o comando sem parâmetros, são listados os identificadores (PIDs) e os nomes das classes que inicializaram cada processo (aquelas cujo método main foi chamado):
$ jps 12647 startup.jar 12777 Bootstrap 12972 Jps
Se você já sabe quais programas estão executando, provavelmente, só esta informação já lhe será suficiente. Mas, se quer mais detalhes, pode tentar as opções -l e -v, que mostram o nome completo da classe principal e os parâmetros da JVM:
$ jps -lv 12647 /opt/eclipse/./startup.jar -Xms40m -Xmx256m 12777 org.apache.catalina.startup.Bootstrap -Djava.util.lo... 13012 sun.tools.jps.Jps -Dapplication.home=/usr/lib/jvm/ja...
Nestes exemplos, os processos Java da máquina eram Eclipse (pid 12647), Tomcat (12777) e o próprio jps (12972 e 13012). Observe que a listagem de parâmetros foi abreviada.
Palavras-chave: Java 5, varargs, argumentos variáveis
A versão 5 da plataforma Java trouxe um recurso muito comum em diversas outras linguagens: número variável de argumentos na chamada de métodos.
A sintaxe é simples e intuitiva:
public class Varargs {
public static void main(String[] args) {
imprimirTipos("123", 123, 123F, 123L);
}
public static void imprimirTipos(Object... params) {
for (Object objeto : params) {
System.out.println(objeto.getClass().getName());
}
System.out.println("Número de parâmetros: "
+ params.length);
}
}
No corpo do método, o parâmetro de tamanho variável é visto como um array. Assim, nosso breve exemplo produzirá:
java.lang.String java.lang.Integer java.lang.Float java.lang.Long Número de parâmetros: 4







Comentários Recentes