Archive for the ‘ java ’ Category

Code: /dev/null ‘s like implementation for java

(This title is weird)

Just to remember, a implementation that send to garbage all the System.out.println messages:

//Java implementation for /dev/null
System.setOut(new java.io.PrintStream(new java.io.OutputStream() {public void write(int b) {}}));
System.out.println("This goes to the void");

Source: http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/2006-11/msg03469.html

ArrayStringBuilder makes StringBuilder acts as an array

String concat is something that we need to do a lot when creating SQLs but there is a problem by using string-plus-string concatenation (“string”+””string”): Every couple of quotations java will create and alocate one String class, this can be a trigger for memory problems.

The orientation (at Celepar) is to use StringBuffer that is faster than simple concat. Searching the web i found that StringBuilder is a bit faster than StringBuffer.

Now let me go to the point, i needed to make an join and use a separator at a group of strings, but memory was something i was worried, then i tried to simulate an array over StringBuilder,  the result was the following class.

p.s: I really doen’t feel that there aren’t a better and faster way to do this, but i didn’t found anything at this time;

package com.br.webcentro.utils;

import java.util.Arrays;

/**
 * This class works using the java.lang.StringBuilder,
 * but this simulates an array to implement a joinable splitable string
 *
 * may be better extend the class AbstractStringBuilder but for now it will only work using it;
 *
 * feel free to post implementations
 *
 * If you have some advice please contact me at webcentro(at)gmail.com
 * @author alandanielweiss
 * @since 2010-01-22
 */

public class ArrayStringBuilder implements java.io.Serializable{

	private StringBuilder builder;

	private boolean isMultiEnabled = false;
	private boolean isEmptyAllowed = true;

	private int start[];
	private int len[];
	private int counter=0;
	private int totalLen=0;

	private static final long serialVersionUID = -2443226579329551214L;

	/**
     * Constructs a string builder with no characters in it and an
     * initial capacity of 16 characters.
     */

	public ArrayStringBuilder() {
		this.builder = new StringBuilder();
		this.start   = new int[16];
		this.len     = new int[16];
    }

	/**
	 * Sets the initial StringBuilder capacity
	 * @param capacity
	 */
	public ArrayStringBuilder(int capacity) {
		this.builder = new StringBuilder(capacity);
		this.start   = new int[capacity];
		this.len     = new int[capacity];
    }

	/**
	 * Create class and append string
	 * @param string
	 */
    public ArrayStringBuilder(String string) {
    	this();
    	this.add(string);
    }

	/**
	 * Create class and the the StringBuilder
	 * @param string
	 */
    public ArrayStringBuilder(StringBuilder builder) {
		this.start   = new int[16];
		this.len     = new int[16];

		this.counter = 1;
    	this.start[0] = 0;
    	this.len[0] = builder.toString().length();
    	this.totalLen = this.len[0];

    	this.builder = builder;
    }

    /**
     * Append a string
     * @param str
     * @return
     */
	public ArrayStringBuilder add(String str){
		if (str == null)
			str = "null";
	    int len = str.length();
		if (len == 0 && !isEmptyAllowed)
			return this;

		//multi-line don't increment counter
		if(!this.isMultiEnabled)
			this.counter ++;

		if (this.counter > start.length)
		    expandCapacity(this.counter);

		if(!this.isMultiEnabled)
			this.start[this.counter-1] = this.totalLen;

		if(this.isMultiEnabled)
			len +=this.len[this.counter-1];

		this.len[this.counter-1]   = len;

		this.totalLen += str.length();
		this.builder.append(str);
		return this;
	}

	/**
	 * start multiline array
	 * when done use the method end()
	 * @return
	 */
	public ArrayStringBuilder start(String str){
		this.isMultiEnabled = false;
		this.add(str);
		this.isMultiEnabled = true;
		return this;
	}

	/**
	 * finish multiline array
	 * @return
	 */
	public ArrayStringBuilder finish(String str){
		this.add(str);
		this.isMultiEnabled = false;
		return this;
	}

	void expandCapacity(int minimumCapacity) {
		int newCapacity = (start.length + 1) * 2;
        if (newCapacity < 0) {
        	newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
        	newCapacity = minimumCapacity;
		}
        this.start = Arrays.copyOf(this.start, newCapacity);
        this.len = Arrays.copyOf(this.len, newCapacity);
    }

	/**
	 * Joins the StringBuilder using the passed separator
	 * @param separator
	 * @return
	 */
	public String join(String separator){
		StringBuilder str = new StringBuilder();
		for (int idx=0; idx<this.counter;idx++){
			str.append(this.builder.substring(this.start[idx], this.start[idx]+this.len[idx]));
			if(idx+1<this.counter)
				str.append(separator);
	    }
		return str.toString();
	}

	public String[] toArray(){
		String[] str = new String[this.counter];
		for (int idx=0; idx<this.counter;idx++){
			str[idx] = this.builder.substring(this.start[idx], this.start[idx]+this.len[idx]);
	    }
		return str;
	}

	/**
	 * To string...
	 * @return String
	 */
    public String toString() {
    	return this.builder.toString();
    }

    /**
     * Creates a StringBuilder with the actual object values
     * @return builder:StringBuilder
     */
    public StringBuilder getStringBuilder(){
    	return this.builder;
    }

    /**
     * when true every time you use add/start/finish with an empty string it will add a new array
     * if false the command add/start/finish empty has no effect
     */
    public void setEmptyAllowed(boolean isMultiEnabled){
    	this.isMultiEnabled = isMultiEnabled;
    }

    public static void main(String[] args) {
		//Sample 1
    	StringBuilder strb = new StringBuilder();
    	strb.append("to be");
    	ArrayStringBuilder arrb = new ArrayStringBuilder(strb);
    	arrb.start(" or ");
    	arrb.add("not ");
    	arrb.add("to ");
    	arrb.finish("be");
		ArrayStringBuilder arrb2 = new ArrayStringBuilder(arrb.join(","));
		System.out.println(arrb2.add(": that's").add("the").add("question").join(" "));

		//Sample 2
		ArrayStringBuilder fields = new ArrayStringBuilder();
		fields.add("id");
		if(1==1)
			fields.add("name");
		if(1==2)
			fields.add("profession");
		StringBuilder sql = new StringBuilder();
		sql.append("select ").append(fields.join(" , ")).append(" from table ");
		System.out.println(sql.toString());
	}
}

A good comparision between StringBuilder and StringBuffer can be found at: StringBuilder vs StringBuffer vs String.concat – done right

Please feel free to send comments, to improve this class.

Proposal: XMLBean Framework

In these days we listen a lot about MDA that ains liberty of programming language o technology and the problem the company i work was facing, the “neccesary redundancy” of creating data validation on server and client side, I was wondering:

Create instead o POJO , JavaBeans, DTO, FORM (struts), create some XML Schema that we can call XMLBeans, this way we can share between many technologies the ways the data is expected.

I fast-drawed this model:

This .XSD files will be useful for:

  • Form Validation
  • Data Transfer
  • Data Persistence

These FILE must have nothing to do with business logic, otherwise will be too much complexity!

Soon i will work on some proto.

I’ve searched the web to and found some reference that may help:

http://www.ibm.com/developerworks/library/x-flexschema/
http://www.javaworld.com/javaworld/jw-09-2000/jw-0908-validation.html
http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/validation/Validator.html
http://xmlbeans.apache.org/

Code: Methods that accept multiple arguments – Java

Pequeno exemplo do uso de HashMap, Varargs e Array para criar metodos que aceitem “multiplos argumentos”, também um exemplo de concatenação de arrays:

	@Test
	public void testMethodWithMultipleParams(){
		Map params = new HashMap<String, Object>();
		params.put("name", "Alan Daniel");

		//Iterate Over Map keys
		String[] arrKey = new String[]{};
		for (Object key: params.keySet()) {
			if(key instanceof String){
				arrKey = (String[])ArrayUtils.add(arrKey, key);
			}
		}
		//Iterate Over Map values
		String[] arrValue = new String[]{};
		for (Object value: params.values()) {
			if(value instanceof String){
				arrValue = (String[])ArrayUtils.add(arrValue, value);
			}
		}

		//Only to demonstrate how to merge / concat two arrays
		Object[] array = ArrayUtils.addAll(arrKey, arrValue);

		this.methodWithMultipleParams(params);//MAP
		this.methodWithMultipleParams((String[])array); //String[]
		this.methodWithMultipleParamsUsingVarArgs((String[])array);//String...
		this.methodWithMultipleParamsUsingVarArgs("this","way","works","too!");//String..
	}

	/**
	 * Method that accept a map as param, than you can work with the named params
	 * @param namedParams: Map
	 */
	public void methodWithMultipleParams(Map namedParams){
		System.out.print(namedParams.get("name"));
		System.out.print(namedParams.get("profession"));
		//...
	}

	/**
	 * Method that accept an array of strings than you can work with multiple args
	 * @param strings: String[]
	 */
	public void methodWithMultipleParams(String[] strings){
        for(String element : strings)
            System.out.print(element);
	}

	/**
	 * Method that accept multiple arguments via VARARGS (http://java.sun.com/j2se/1.5.0/docs/guide/language/varargs.html)
	 * @param varargs:String...
	 */
	public void methodWithMultipleParamsUsingVarArgs(String...varargs){
        for(String element : (String[])varargs)
            System.out.print(element);
	}

Code: Acessar URL via Proxy Autenticado no Java

Ontem fiquei curioso em saber como acessar um endereço web por através de uma conexão em um proxy autenticado então achei algumas referencias na net e fiz esse pequeno exemplo:

a seguir o código, que exibe uma caixa de dialogo para entrar com a senha:
ProxyTeste.java:

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.PasswordAuthentication;
import java.net.URL;

import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.xml.ws.http.HTTPException;

public class ProxyTeste {
	public static void main(String[] args) throws HTTPException, IOException {
		urlDump("http://www.alandaniel.com.br");		
	}
	public static void urlDump(String URLName){
		try {
			DataInputStream di = null;
			byte [] b = new byte[1];

			// INFORMAÇÕES DE PROXY, alterar para suas informações de proxy
			System.setProperty("http.proxyHost","10.15.54.10") ;
			System.setProperty("http.proxyPort", "8080") ;

			// AUTENTICAÇÃO DE PROXY
			Authenticator.setDefault(new Authenticator() {
				protected PasswordAuthentication getPasswordAuthentication() {

					JTextField jtf = new JTextField();
					JPasswordField jpf = new JPasswordField();
					if(JOptionPane.showConfirmDialog(null, new Object[]{jtf, jpf}, "Senha:", JOptionPane.OK_CANCEL_OPTION)==0){

						String usuario = jtf.getText();						
						char[] senha = jpf.getPassword();

						return new PasswordAuthentication(usuario,senha);
					}else{
						System.exit(0);
						return null;
					}
				}});


			//REALIZA AS CHAMADAS
			URL url = new URL(URLName);
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			di = new DataInputStream(con.getInputStream());
			//IMPRIME CONTEUDO
			while(-1 != di.read(b,0,1)) {
				System.out.print(new String(b));
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Fonte: Google…

Maven: Alterar “/src/main/webapp” no arquivo “pom.xml”

Problema: Necessidade de alterar o diretório padrão dos fontes de aplicação web (js, css, jsp,…) de um projeto Maven de “src/main/webapp/” para “context/”
Solução: Definir a configuração warSourceDirectory para o plugin “maven-war-plugin”

Problem: Change standard directory for web application sources on a maven project from “src/main/webapp/” to “context/”
Solution: Define the config warSourceDirectory for the “maven-war-plugin” plugin

Ferramentas envolvidas: Eclipse, NetBeans, M2Eclipse (plugin maven para eclipse)

Descrição:
O padrão para códigos de fonte de aplicação web (js, css, jsp,…) é “/src/main/webapp” como descrito em http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html,
porém existem casos em que se mostra necessário alterar a localização, como por exemplo na minha empresa, que usar como padrão o diretório “context/”.

Quando trabalhamos com um projeto web devemos definir o packaging como war “<packaging>war</packaging>”, quando isso é feito o maven já sabe que terá que usar o plugin “maven-war-plugin” para trabalhar com esse projeto, assim devemos nos preocupar em configurar as propriedades do plugin, como descrito em http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html,
porém existe uma pequena confusão  entre webappDirectory e warSourceDirectory, para que o NetBeans e o M2Eclipse(Eclipse) reconheçam esse diretório Web Pages/Web Resources é necessário que <warSourceDirectory> seja especificado,como no exemplo a seguir:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-alpha-1</version>
<configuration>
<!--warSourceDirectory>src/main/webapp/</warSourceDirectory-->
<warSourceDirectory>context/</warSourceDirectory> <!--Atencao: path relativo, sem barra no inicio -->
</configuration>
</plugin>
</plugins>
</build>

Dessa forma o projeto ficará independente de IDE, podendo ser aberto no NetBeans ou importado no Eclipse.
Para atualizar as configurações de projeto do eclipse se baseando no pom.xml clique com o botão direito no projeto > Maven > Update Project Configuration
//!\ ATENÇÃO: Caso existam declarações de <resources> aprontando para algum diretório, no escopo build, estes serão enviados para diretórios diferentes do desejado, pois uma vez já enviados os arquivos o maven não os envia novamente

Java ClassNotFoundException javax.transaction.Synchronization

Solução: adicionar jta.jar no classpath

Java Transaction API: http://java.sun.com/javaee/technologies/jta/index.jsp

java.lang.NoClassDefFoundError: javax/transaction/Synchronization

Configurar Jboss no Linux e inclui-lo no RHDS

Neste tutorial utilizarei o jboss-4.0.5.GA.zip também pode utilizar outra versão ( 4.2.2 ou outra ) e demonstrarei como configura-lo em um ambiente de desenvolvimento. ( Esse tutorial não tem como objetivo configurar um servidor de produção )

O Jboss assim como a maioria dos aplicativos java só necessita o descompactamento e está pronto para utilizar

  1. Faça o download de http://www.jboss.org/jbossas/downloads/
  2. Descompacte-o
  3. Mova para um lugar de sua preferencia (no linux normalmente para /usr/lib/jboss4 no windows por ser em c:/jboss4).
  4. para testar entre na pasta /usr/lib/jboss4/bin/  (caso linux) e execute o comando
    $ ./run.sh
    ou execute o arquivo run.bat caso no windows
  5. caso run.sh não tenha permissão de execução (bash: ./run.sh: Permissão negada) execute o comando como root:
    # chmod +x run.sh
  6. Quando aparecer uma linha de texto no terminal similar a:
    [Server] JBoss (MX MicroKernel) [4.2.1.GA] Started in 11s:198ms
    o servidor terá executado com sucesso.
  7. teste abrindo em seu navegador: http://localhost:8080

Com o jboss devidamente instalado vamos adiciona-lo no RHDS / Eclipse:

  • Em uma nova instalação do RHDS ou em um workspace novo, recomendo remover o servidor que o RHDS instalou automaticamente e reiniciar o RHDS, pois ele gera alguns bugs.
  • Window > Preferences > Server > Installed Runtimes
  • Clique em Add…
  • Selecione a versão do Jboss na qual você deseja configurar, e marque a opção “Also create a new local server”, dessa forma ele adicionará automaticamente o servidor na aba Server.
    clique em Next
  • Em Home Directory localize a raiz do Jboss que você instalou, /usr/lib/jboss4 no nosso exemplo, configuration deixe Default selecionado:
    Clique em Next
  • Finish

A pasta default que são feitos os deploys é %raiz do jboss%/server/default/deploy/ quando publicar algum projeto certifique-se que nessa pasta é criado um arquivo chamado nome_do_projeto.war e se dentro dele estão todos os arquivos necessários para o funcionamento do mesmo.

Dicas:

  • Em geral o Eclipse (base do RHDS) é bem instavel, algumas vezes é necessário remover o servidor e adicionar novamente, muitas vezes também o workspace pode esta bugado, sendo necessário remover o mesmo e começar a configurar todos os projetos denovo (palavra de alguem que sofreu bastante com coisas do tipo)

Criando um simples projeto web com Struts no RHDS

Retificando: De preferencia instale você mesmo o Jboss, como demonstrado no artigo  http://www.webcentro.com.br/2008/10/09/configurar-jboss-no-linux-incluir-no-rhds/ pois a versão instalada pelo RHDS gera muitos problemas.

Nesse artigo quero mostar como criar um projeto web utilizando Struts no Red Hat Developer Studio, caso você não o tenha baixado veja o artigo: https://webcentro.wordpress.com/2008/09/18/rhds-red-hat-developer-studio-download/

Utilizarei o nome de projeto de academico_secretaria, mudem para o nome do projeto de vocês ou nomeiem como teste. Vamos aos passos:

  • Selecione a perspectiva Web Development Perpective:
    Window > Open Perspective > Other > Web Development Perpective
  • File > new > Struts Project
  • Preencha os dados em tela, onde diz Template selecione o único existente: KickStart e clique em Next
  • Nesse passo é muito importante que você selecione Servlet Version 2.4 (as versões 2.3 e 2.5 parecem não dar suporte a Expression Language), caso não exista um servidor (recomendo o jboss, alem de que este é instalado automaticamente durante a configuração do RHDS, senão instale ), clique em next
  • Marque todas as opções, ainda não tive a oportunidade de testar as configurações destes tld’s mas marque de qualquer jeito, clique em Finish

Pronto, seu projeto está criado, vamos realizar o Deploy:

  • Clique na aba Server, caso ela não esteja aparecendo, clique em Window > Show View > Other > Server
  • Observe que o projeto já se encontra selecionado para Publicação no server, caso não esteja, clique com o botão direito sobre o servidor > Add and Remove Projects (veja Dicas mais abaixo).
  • Clique no botão verde com o simbolo de play para iniciar o servidor. Todas vez que você efetuar uma alteração o RHDS automaticamente fará hot deploy, porém isso é configuravel (dando clique duplo no server) e as vezes não é totalmente seguro que atualizará, você também pode efetuar um deploy clicando no icone mais a direita.

Agora que publicamos o projeto, vamos vizualiza-lo:

Dicas:

  • No linux, caso você encontre problemas ao dar deploy é por que você não tem permissão de escrita na pasta do servidor, execute o seguinte comando como root:
    # chmod -R 777 /usr/local/rhdevstudio/
  • Se o Deploy não funcionar e no console exibir o seguinte erro: “Unable to process deployment descriptor for context ‘null'”, remova o Jboss configurado clicando com o botão direito > delete, e configure como explicado no seguinte artigo: https://webcentro.wordpress.com/2008/10/09/configurar-jboss-no-linux-incluir-no-rhds/
  • Algumas vezes os deploys não são efetivos para resolver você pode:  Clicar com o botão direto > Clean ou Remover o projeto e adicionar novamente ou reiniciar o servidor.
  • Sempre olhe a aba Console para visualizar algum possivel erro.
  • Clicando duas vezes sobre o Server você abre as opções de configuração, clique em Automatic Publishing e marque Never publish automatically, para somente fazer deploy quando você desejar.

Compilar multiplos diretórios por linha de comando

Estou estudando algumas coisas básicas do Java e por isso optei em compilar por linha de comando.
O problema é que para se compilar múltiplos diretórios ( as packages) é necessário listar cada arquivo que deve ser compilado após o comando javac, exemplo:

$ javac package01/Classe.java package02/Classe2.java;

Claro que listar uma infinidade de arquivos seria sacal, a forma a seguir facilita bastante o trabalho. A idéia é buscar todos os arquivos de extensão .java e gravá-los em um arquivo e depois compilar utilizando desses dados:

$ find src -name \*.java -print > file.list
$ javac @file.list