Javadb com os arquivos do banco dentro de um .jar utilizando JPA

Boa tarde pessoal,

Estou com um problema ao rodar uma aplicação desktop fora de minha IDE.
Estou utilizando JavaDB e JPA para acessar o banco.
Dentro da IDE (Netbeans) subo a aplicação, inicio o servidor e conecto no banco normalmente, mas quando executo o jar criado me dá a seguinte Exception:

[EL Severe]: 2013-05-29 17:08:08.533--ServerSession(1653647)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLNonTransientConnectionException: A conexão foi recusada, porque o banco de dados msdnaa não foi encontrado

o código que carrega o banco está aqui:

System.setProperty("derby.system.home", Programa.class.getResource("/database").getPath()); NetworkServerControl servidor = new NetworkServerControl(InetAddress.getByName("localhost"), 1527); servidor.start(new PrintWriter(System.out));

E o meu persistence.xml

<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="MsdnaaPU" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>entidades.Cadastro</class> <class>entidades.Escola</class> <class>entidades.Curso</class> <properties> <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/msdnaa"/> <property name="javax.persistence.jdbc.password" value="root"/> <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/> <property name="javax.persistence.jdbc.user" value="root"/> </properties> </persistence-unit> </persistence>

Ao rodar o código dentro da aplicação a linha

System.out.println(Programa.class.getResource("/database").getPath());

retorna

/opt/Projects/Msdnaa/build/classes/database

rodando o .jar o resultado é o seguinte:

file:/opt/Projects/Msdnaa/dist/Msdnaa.jar!/database
Alguém tem idéia de como fazer para que o JavaDB encontre os arquivos do banco que estão dentro do .jar da aplicação?

Não testei isso, mas segundo alguém que postou no JavaRanch, é possível você incluir os arquivos do banco se o banco for read-only.

http://www.coderanch.com/t/545378/java/java/build-derby-database-jar

Os links desse post não estão funcionando. Você vai ter de procurar as coisas na documentação, infelizmente.

Se o banco precisar ser atualizado, não tem jeito…

Como regra geral, sempre imagine que não é possível atualizar um jar em tempo de execução de maneira trivial. Sabendo isso você irá evitar muitos problemas.

Já revirei de tudo e nada. Este link já tinha visto também. Mas muito obrigado.

Como seria uma boa estratégia para enviar apenas um arquivo para o cliente e ter tudo embutido nele? Sem utilizar um instalador.

Uma forma bem simples é a seguinte: crie um “template” de um banco já preenchido com os arquivos necessários. Então, você extrai de dentro de seu jar esse “template” e o copia para o diretório de usuário adequado, onde você tem permissões de escrita.

Para extrair um arquivo do jar do seu programa é relativamente simples - use um getResourceAsStream() para obter um InputStream, e copie os bytes lidos do InputStream para um FileOutputStream. Isso é relativamente fácil e pode até ser achado aqui no GUJ com um pouco de sorte.

Eu não recomendo, na verdade, dispensar um instalador, porque você precisa se lembrar que, ao dar um duplo-clique em um arquivo .jar, você não tem controle sobre:
a) A versão da JVM que está sendo usada (vai que o cliente tem só uma JVM 5 e você compilou seu código para funcionar na versão 7 :frowning: );
b) Os parâmetros de execução da JVM - normalmente o default é usar muito pouca memória, e para se você vai usar o Derby, que é um banco de dados bem poderoso, eu recomendaria mudar os parâmetros -Xmx para não usar os padrões (que são por volta de 30 MB de memória, muito pequenos por sinal).