December 14, 2008
Java, Programação
No Comments
Ainda em relação ao post anterior, tive que extrair o conteúdo de um arquivo PDB (um formato de arquivo usado nos Palm’s).
Encontrei a solução parcial neste post:http://www.neowin.net/forum/index.php?s=d21af43a292e783de98d0644c0824b70&showtopic=689476&pid=590047756&st=0&#entry590047756
A solução descrita não funcionou, mas após algumas alterações na solução, serviu para o que eu precisava:
/***
* T3_allfiles
* based upon T3_APR.java from Shadowmite's forum
*
* This file will extract a binary file from it's
* Palm PDB prison. Just drop this in the directory
* that contains the *.pdb files, and run it. It'll
* get them all. Well, mostly. See next.
*
* This file is NOT made to extract the rom image.
* Use Grack's RomTool for that.
*/
import java.io.*;
public class T3_allfiles {
public static void main(String[] args) throws Exception {
File directory = new File(”/home/fabio/Desktop/pdb/”);
String[] files = directory.list(new PDBfilter());
for (String individualFile : files) {
pdb2(”/home/fabio/Desktop/pdb/” + individualFile);
}
}
static void pdb2(String file) throws Exception {
System.out.println(file);
RandomAccessFile in = new RandomAccessFile(file, “r”);
in.skipBytes(76);
int numRec = in.readShort();
int[] toc = new int[numRec];
for (int i = 0; i < numRec; ++i) {
toc[i] = in.readInt();
in.readInt();
}
for (int i = 0; i < numRec; ++i) {
in.seek(toc[i]);
short fileNameSize = in.readShort();
byte[] fn = new byte[fileNameSize];
in.read(fn);
String fileName = new String(fn);
System.out.println(”\t” + fileName);
String[] directories = fileName.split(”\\/”);
String directory = “.”;
for (int j = 0; j < directories.length - 1; j++) {
directory += File.separator + directories[j];
}
new File(directory).mkdirs();
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileName));
if (i < toc.length - 2) {
int bytesToRead = toc[i + 1] - toc[i] - fileNameSize - 2;
while (bytesToRead > 0) {
out.write(in.read());
bytesToRead–;
}
} else {
int b;
while ((b = in.read()) > -1) {
out.write(b);
}
}
out.close();
}
}
}
class PDBfilter implements FilenameFilter {
public boolean accept(File dir, String name) {
if (new File(dir, name).isDirectory()) {
return false;
}
name = name.toLowerCase();
return name.endsWith(”.pdb”);
}
}
December 14, 2008
Java, Programação
No Comments
Há algum tempo atrás, peguei um serviço pra fazer no qual o cliente não tinha o código fonte do sistema.
Após alguns dias procurando um descompilador java, achei este:
JD-Gui
Este descompilador é muito bom, devido à diversas features, como por exemplo, poder descompilar um jar inteiro, fazer links entre os arquivos descompilados, etc.
July 23, 2008
Java, Programação, Selenium
1 Comment
Hoje tive um problema no Selenium, no qual o mesmo não conseguia verificar a url do navegador, jogando uma exceção com a seguinte mensagem:
Permission denied to get property Location.href
Procurando no google, encontrei o seguinte blog:
http://www.woloszyn.org/2008/04/22/selenium-and-the-permission-denied-to-get-property-locationhref-problem/
Este blog mencionava que o problema era causado por um redirect enviado pelo response do servidor. A solução desse blog foi não utilizar o redirect.
Em outro site:
http://www.nabble.com/Permission-denied-to-get-property-Location.href-td8081383.html
Falava que só bastava utilizar o *chrome ou *iehta (no meu código estava sendo utilizado o *firefox). Após esta alteração, tudo voltou a funcionar normalmente.
June 6, 2008
Java, Programação
No Comments
Após duas longas semanas resolvi o problema que estava tendo com o Spring gerenciando as transações de banco de dados. O que acontecia é que nenhuma transação era aberta na classe marcada com a anotação “@Transactional”. Segue abaixo um exemplo de como utilizar o gerenciamento de transações do Spring:
package br.com.test;
public interface IService {
int myServiceMethod(String myServiceParameter);
}
Segue abaixo a implementação, repare no uso da anotação “@Transactional” na classe (isto indica que a classe toda deve estar associada à um contexto transacional. É possível também marcar métodos:
package br.com.test;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class ServiceBean implements IService {
public int myServiceMethod(String myServiceParameter) {
return Integer.parseInt(myServiceParameter);
}
}
Agora só falta configurar o “applicationContext.xml” do Spring:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="myService" class="br.com.test.ServiceBean"/>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
</beans>
Repare no uso da tag “<tx:annotation-driven transaction-manager=”txManager”/>”. Esta tag ativa a configuração de transações baseada em anotações.
Até aí é muito simples utilizar o gerenciamento de transações do Spring. O problema que tive foi o seguinte: meu serviço possuía uma interface, e esta interface estava sendo implementada por uma classe abstrata. Essa classe abstrata definia o método que eu queria que fosse transacional. Depois eu criei uma terceira classe que extendia essa classe abstrata. Coloquei a anotação “@Transactional” na classe concreta, e o Spring não gerenciava as transações no método definido na classe abstrata. Para resolver o problema só foi necessário colocar a anotação da classe abstrata.
June 6, 2008
Java EE, Programação
No Comments
Um grande problema com o JSF é que na especificação 1.1 não existe algum método para saber se a página está sendo executada no postback (quando você reenvia os dados para ela mesma). Mas existe o seguinte workaround:
package web.jsf.vh;
import java.io.IOException;
import java.util.Locale;
import java.util.Map;
import javax.faces.FacesException;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
public class PostBackViewHandler extends ViewHandler {
protected ViewHandler baseViewHandler;
public CustomViewHandler(ViewHandler viewHandler) {
super();
this.baseViewHandler = viewHandler;
}
public Locale calculateLocale(FacesContext facesContext) {
return baseViewHandler.calculateLocale(facesContext);
}
public String calculateRenderKitId(FacesContext facesContext) {
return baseViewHandler.calculateRenderKitId(facesContext);
}
public UIViewRoot createView(FacesContext facesContext, String arg1) {
setPostback(facesContext, false);
return baseViewHandler.createView(facesContext, arg1);
}
public String getActionURL(FacesContext facesContext, String arg1) {
return baseViewHandler.getActionURL(facesContext, arg1);
}
public String getResourceURL(FacesContext facesContext, String arg1) {
return baseViewHandler.getResourceURL(facesContext, arg1);
}
public void renderView(FacesContext facesContext, UIViewRoot arg1) throws IOException, FacesException {
baseViewHandler.renderView(facesContext, arg1);
}
public UIViewRoot restoreView(FacesContext facesContext, String arg1) {
setPostback(facesContext, true);
return baseViewHandler.restoreView(facesContext, arg1);
}
public void writeState(FacesContext facesContext) throws IOException {
baseViewHandler.writeState(facesContext);
}
public Map getRequestScope(FacesContext facesContext) {
return (Map)facesContext.getApplication().createValueBinding(“#{requestScope}”).getValue(facesContext);
}
public void setPostback(FacesContext facesContext, boolean value) {
getRequestScope(facesContext).put(“ispostback”, new Boolean(value));
}
}
O código acima é um View Handler do JSF, agora basta registrá-lo no “facesconfig.xml”:
<application>
<view-handler>web.jsf.vh.PostBackViewHandler</view-handler>
</application>
E para saber em sua página se é um postback:
public boolean isPostback() {
FacesContext facesContext = FacesContext.getCurrentInstance();
Map requestScope = (Map)facesContext.getApplication().createValueBinding(“#{requestScope}”).getValue(facesContext);
boolean ispostback = ((Boolean)requestScope.get(“ispostback”)).booleanValue();
return ispostback;
}
Obs.: Esse workaround só funciona se o estado da view não é salva no servidor.
May 23, 2008
Java EE, Programação
No Comments
Utilizando o DataTable do RichFaces em uma simples página, após um reload na página sempre era retornado o seguinte erro:
Duplicate component ID '_id0:_dataTable:_id1' found in view.
Segue abaixo o código da página que causava o erro:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
xmlns:rich="http://richfaces.ajax4jsf.org/rich">
<h:form binding="#{UserConsultPage.component}">
<rich:dataTable id="dataTable"
binding="#{UserConsultPage.dataTable}" var="item">
<rich:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{item.name}" />
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Email" />
</f:facet>
<h:outputText value="#{item.email}" />
</rich:column>
</rich:dataTable>
<h:commandButton id="btnLoad" actionListener="#{UserConsultPage.load}" />
</h:form>
</ui:composition>
A solução foi colocar id’s em todos os componentes “outputText”. Segue abaixo a página modificada:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
xmlns:rich="http://richfaces.ajax4jsf.org/rich">
<h:form binding="#{UserConsultPage.component}">
<rich:dataTable id="dataTable"
binding="#{UserConsultPage.dataTable}" var="item">
<rich:column>
<f:facet name="header">
<h:outputText id=”headerNameValue” value=”Name” />
</f:facet>
<h:outputText id=”nameValue” value=”#{item.name}” />
</rich:column>
<rich:column>
<f:facet name=”header”>
<h:outputText id=”headerEmailValue” value=”Email” />
</f:facet>
<h:outputText id=”emailValue” value=”#{item.email}” />
</rich:column>
</rich:dataTable>
<h:commandButton id=”btnLoad” actionListener=”#{UserConsultPage.load}” />
</h:form>
</ui:composition>
May 21, 2008
Java EE, Programação
1 Comment
Ao tentar fazer o deploy de uma aplicação utilizando JSF, Spring e JPA (com implementação do hibernate) é recebida a seguinte exception:
javax.persistence.PersistenceException: org.hibernate.SessionException: Session is closed!
Para resolver este problema, basta apenas adicionar o seguinte filtro no “web.xml”:
<filter>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
May 14, 2008
Java EE, Programação
No Comments
Para rodar um debug remoto no tomcat 5.5 no Ubuntu, basta editar o arquivo “/etc/init.d/tomcat5.5″ e colocar a seguinte linha:
-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
antes das linhas:
# Define other required variables
CATALINA_PID="/var/run/$NAME.pid"
BOOTSTRAP_CLASS=org.apache.catalina.startup.Bootstrap
JSVC_CLASSPATH="/usr/share/java/commons-daemon.jar:$CATALINA_HOME/bin/bootstrap.jar"
May 13, 2008
Java EE, Programação
No Comments
O botão back do navegador é muito útil ao usuário para ele conseguir navegar entre diferentes páginas e websites. Entretanto, o botão back pode trazer diversos problemas aos sites. Uma maneira de “travar” o botão é desabilitar completamente o cache das páginas que não devem permitir que sejam acessadas através do botão back.
Para se fazer isso no Java EE basta apenas criar um filtro e mapeá-lo para as url’s necessárias.
Segue abaixo o código do filtro:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class ClearCacheFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Expires", "Sat, 1 Jan 1990 12:00:00 GMT");
httpResponse.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
httpResponse.addHeader("Cache-Control", "post-check=0, pre-check=0");
httpResponse.setHeader("Pragma", "no-cache");
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
Basicamente o que o filtro faz é setar as diretivas de cache para o navegador. Primeiro ele seta a data de expiração da página para uma data passada. Depois, o código seta 3 diretivas para desabilitar o cache:
- no-store: não armazena o conteúdo no cache
- no-cache: o browser deve enviar o request para o servidor mesmo se ele possuir uma cópia do que será enviado
- must-revalidate: revalida o cache em outro request, se estiver expirado
Depois, são setadas duas diretivas específicas do Internet Explorer. Estas diretivas indicam que o conteúdo sempre deve ser atualizado. E por último, é desabilitado o cache para o protocolo HTTP/1.0 (já que as outras 3 são específicas do HTTP/1.1).
Por último é preciso configurar o filtro na aplicação web. Segue abaixo o trecho de código referente à configuração para o filtro, bem como para ele ser aplicado a todas as páginas da aplicação:
<filter>
<filter-name>ClearCacheFilter</filter-name>
<filter-class>br.com.uol.ps.common.web.ClearCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ClearCacheFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
May 11, 2008
Programação
No Comments
Se você estiver tendo algum problema ao tentar conectar ao MySQL de outra máquina, basta alterar o arquivo “my.cnf” localizado no diretório “/etc/mysql” e comentar a seguinte linha:
bind-address = 127.0.0.1
No caso, ela ficará da seguinte maneira:
#bind-address = 127.0.0.1
Após alterar o arquivo, e salvá-lo, bastar restartar o mysql:
sudo /etc/inid.d/mysql restart
Obs.: esses caminhos e executáveis foram testados no Ubuntu 8.04
« Previous Entries