Bom black fire eu também sei que vc baixou o código e alterou algumas coisas para que o framework ficasse mais adaptado ao seu caso. Essa é a essência do open source. Algumas vezes alguém me pede uma alteração ou reclama de algo, mas na verdade basta baixar o código e modificá-lo. No caso do BoxSQL o código é estupidamente simples de ser entendido e corrigido.
Não me lembro desse problema. Talvez ele retorne 0 se o atributo for numérico. Mas se for o caso podemos deixar um default para isso e colocar um parâmetro de configuração para quem quiser mudar o default.
Bom, mas deixando de lado, vou terminar a versão 2.0 do BoxSQL ainda este ano. Demorei porque estou implementando tudo de novo em Groovy (não há um bom motivo a não ser opção pessoal. Enjoei de Java.). O bom é que ele será compilado para BytoCode e todo mundo poderá utilizar na boa o framework. Também vou publicar o projeto com mais conteúdo como tutoriais e documentação, mas só para o ano que vem, pois to muito corrido com a InfoQ.
Oi Felipe, pelo que notei vc é um dos criadores do boxsql, por isso resolvi tentar te contactar por aqui.
Estou trabalhando em um projeto no qual optei por adotar o boxsql devido a sua flexibilidade e etc. Estou neste momento enfrentando um problema que talvez seja de fácil solução para vc.
Logo no momento do login do sistema, ao tentar acessar o BD mysql pela primeira vez, recebo um erro java.lang.IllegalArgumentException: URI is not hierarchical.
Quando rodo o sistema no Eclipse tudo funciona bem, mas quando gero um jar no ANT e rodo o sistema direto no browser, apesar de carregar a tela inicial, no primeiro acesso ao BD para validação de login e senha, recebo este erro.
Não achei nada esclarecedor sobre isso na internet.
Meu arquivo boxsql.properties está configurado assim:
box.connectionType=jdbc
box.pathBase=br/com/atchik/resources
log.path=/c://java/workspace_atchik/
log.active=true
jdbc.url=jdbc:mysql://localhost/quebrabases
jdbc.driver=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=2108
O erro ocorre no metodo abaixo quando chamo box.getList :
public static Boolean Login_Validation (String username, String password){
BoxSQL box = new BoxSQL();
Só corrigindo, pois a linha log.path correta é: log.path=c://java/workspace_atchik/. Mas o problema certamente não é esse.
Outro ponto que vale a pena citar é que este projeto utiliza STRUTS2.
Espero que vc possa me dar uma luz nesse problema.
Com base no que você me passou, o problema parece na URL de conexão. Não tá faltando a porta em que o banco roda não?
Porém, pela Exception pode ser erro na hora de ler os templates. Talvez com a stack_trace completa seja mais fácil de identificar.
Isso pode ser erro até mesmo do Struts2. Pelo fato de funcionar de dentro do eclipse e depois não funcionar no Browser, pode ser falta de alguma dependência também. Mas aí acho que Exception seria outra.
E pra terminar, acho que vale a tentativa também, você já experimentou colocar uma barra na frente do ‘br’ na linha ‘box.pathBase=br/com/atchik/resources’ ?
Tentei colocando o “/” antes do BR, mas não adiantou.
Abaixo envio todo o stack para que, quem sabe, vc possa identificar se o erro é no acesso ao BD ou na tentativa de ler os templates (.sql).
Agradeço desde já pela ajuda!
May 15, 2009 11:06:01 AM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
May 15, 2009 11:06:01 AM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
May 15, 2009 11:06:24 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet default threw exception
java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.(File.java:363)
at org.boxsql.ioEngine.IOEngine.readResourceFile(IOEngine.java:23)
at org.boxsql.templateEngine.TemplateEngine.getSQLQuery(TemplateEngine.java:36)
at org.boxsql.BoxSQL.getTemplate(BoxSQL.java:254)
at org.boxsql.BoxSQL.getList(BoxSQL.java:298)
at br.com.atchik.dao.LoginDAO.Login_Validation(LoginDAO.java:25)
at br.com.atchik.actions.LoginAction.checkLogin(LoginAction.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:404)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:267)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:229)
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:221)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:150)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:48)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:123)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:186)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:105)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:83)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:207)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:74)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:127)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:107)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:206)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:115)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:143)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:121)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:170)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:123)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:50)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:504)
at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:419)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Se o problema for no acesso aos templates, para eliminar a linha box.pathBase=br/com/atchik/resources ( que no caso, por alguma razão não estaria encontrando os respectivos arquivos). Onde devo colocar os templates (.sql) para que os metodos das classes do pacote br.com.atchik.dao possam encontrá-los por default ?
PS: Só para informação tentei colocar a porta usada pelo BD, mas não adiantou também.
Não há uma convenção para isso. Ainda não. =(
Estou trabalhando numa nova versão do BoxSQL, mas as coisas estão corridas demais. Porém posso dizer que será interessante essa nova versão. E pelas funcionalidade e escopo irá receber outro nome.
Votando ao problema:
Sim o erro é na leitura dos templates. Você mencionou que funciona no eclipse?
Se funciona no eclipse e não funciona fora do eclipse o erro só pode estar no ambiente. Falta algo no classpath (como esse pacote em que estão os templates por exemplo).
Voc6e consegue verificar se no servidor de aplicações este pacote existe? Talvez você deva verificar se o .war foi descompactado. Não se isso influenciaria (eu acho que sim).
Tentei, como vc pode ver neste XML acima, copiar os templates para diferentes pastas para ver se a aplicacao os encontrava. Mas não funcionou.
Estou infelizmente usando o windows Vista, mas até agora não havia apresentado nenhum problema, e acho que este especificamente não tem a ver com esse fato.
Inclui no meu classpath a pasta aonde são colocados os templates após rodar o ant, veja abaixo:
.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip; c:\Java\ANT_HOME; c:\Java\xerces-2_9_1;c:\Java\Tomcat 6.0\webapps\QuebraBases\WEB-INF\src\br\com\atchik\resources;
Porém a aplicação continua não encontrando os templates…alguma luz no fim desse tunel?
Como eu falei antes, o problema é que os recursos estão em um arquivo compactado (.jar ou .war por exemplo). Esse tipo de arquivo possue um classpath interno apenas. Isso quer dizer que ele só enxerga as classes e pacotes que estão dentro dele, a não ser que seja especificado outros jars para que ele busque.
Esse é o problema. Esse também é o motivo pelo qual o projeto funciona no Eclipse e nõa funciona fora dele.
Uma pequena busca no google sobre essa exception trouxe a solução.
Muito obrigado. Sem dúvida o caso que vc descobriu é igual ao meu. Porém existe uma pequena diferença que talvez vc tenha alguma dica de como solucionar.
No meu caso, seguindo o seu framework, eu uso o getList para recuperar o template, e este vai buscá-lo de acordo com a linha box.pathBase=br/com/atchik/resources, ou seja, eu não busco por este arquivo .sql diretamente pois pelo que entendi é preciso usar a propriedade box.pathBase.
Como meu procedimento ANT gera um arquivo .jar com o projeto, segundo o artigo em questão, eu deveria acessar os templates usando ClassLoader.getSystemResourceAsStream (DEFAULT_PATH + FILE). A questão é que não sei se é possível fazer isso utilizando o boxsql.
Enfim, a questão é como usar ou substituir o box.getList para que ele pegue o template via ClassLoader.getSystemResourceAsStream.
Neste caso, se não der mesmo pra não colocar dentro do Jar, a solução é baixar o fonte do BoxSQL e modificar a classe org.boxsql.IOEngine na linha 23. Assim você pode colocar a alteração necessária. Depois gera um jar do BoxSQL e pronto.
O BoxSQL é um framework de 7 classes em sua versão 1.5.1. Muito simples de customizar. =)
Na verdade os templates estão todos dentro do jar, porém a aplicação não consegue exergá-los.
Não existe um caminho fisico ou logico que colocando no boxsql.properties, a aplicação conseguiria encontrar os templates?
Afinal eles estão dentro do jar, e se a aplicação consegue encontrar os arquivos .properties, não há uma forma de fazê-la encontrar os .sql (pois posso colocá-los em qualquer pasta do projeto)?
Queria realmente evitar mexer nos fontes do boxsql…
Porque esses arquivos estão dentro de um jar?
Você pode retirá-los do jar como acontece com aplicações web normal. Pelo menos os .sql
A linha de código da classe IOEngine.java que lê o arquivo é essa:
onde “file” é o pathBase + nomeDoTemplate passado para o getList()
Você pode mudar essa linha de código, o que seria mais rápido do que responder aqui no fórum.
Gerar um Manifest melhor para seu jar
No Manifest você consegue indicar quais outros jars fazem parte do classpath de seu jar. Isso quer dizer que no .war de sua aplicação você precisa ter um Manifest decente, se esse war não for descompactado.
Ir até o issue tracker do BoxSQL e cadastrar um issue para que verifiquemos isso.
Pode demorar bastante.
Particularmente, eu acho a 1 opção mais sensata. A segunda opção não é tão ruim assim também.
Esse também é um problema da forma que voc6e escolheu para fazer o deploy de sua aplicação.
Estou para iniciar um novo projeto e gostaria de utilizar o BoxSQL, porém gostaria de saber se você já tem uma previsão do lançamento do BoxSQL 2.0 (ou o novo nome) ainda este ano de 2010 ?
Cara… estou trabalhando nele, mas numa velocidade menor do que eu gostaria. Se alguém estiver a fim de me ajudar, numa atividade open source, eu ficaria muito feliz e o projeto!
Caro amigo rubensmm.
Eu já tive a oportunidade de utilizar o BoxSQL e gostei muito, pena que seu código não recebe a devida atenção e por este motivo esta praticamente descontinuado.
Procurando na internet alguma solução viável, eu acabei encontrando o QueryDSL-SQL, o qual possui semântica parecida com o BoxSQL, porém mais poderoso e com seu código sendo mantido até a presente data.
Dê uma olhada nos exemplos e surpreenda-se com as facilidades de programação…
Fala Felipe…Aqui é o Igson…kkkkk
EI nao eskece de colocar no boxsql a função pra inserção de arquivo e valores do tipo Date !!!
Espero que essas melhorar sejam pra evoluir o box . Gostei muito de utilizar ele aqui .
Paz e Bem