Problema ao criar arquivo temporário - Applet

25 respostas
Pilantra

Olá pessoal.

Estou sofrendo aqui com essa applet. Consegui fazer o leitor biométrico funcionar perfeitamente, mas agora que eu preciso passar para applet pra rodar na web, o trem não funciona. Eu fiz exatamente do jeito que o exemplo do grfinger tem. O applet deles rodam, mas o meu não. Mudei o java.policy, fiz um monte de tranquerada e nada resolve, sempre retorna o seguinte erro:

java.lang.SecurityException: Unable to create temporary file at java.io.File.checkAndCreate(Unknown Source) at java.io.File.createTempFile(Unknown Source) at java.io.File.createTempFile(Unknown Source) at GrFingerJavaAppletInstaller.<init>(GrFingerJavaAppletInstaller.java:52) at GrFingerJavaAppletInstaller.getInstance(GrFingerJavaAppletInstaller.java:42) at cadastro_digital.init(cadastro_digital.java:27) at sun.applet.AppletPanel.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

Eu já não sei mais o que fazer. Já pesquisei em tudo que é lugar mas parece que só o meu problema não foi resolvido hehehe. Alguém pode me ajudar?? Eu já entrei em contato com o pessoal da Griaule mas ninguém me responde, inclusive no fórum deles.

Grato desde já.

25 Respostas

T

Por acaso “init” é a “public void init”, e “cadastro_digital” é o nome da classe que estende Applet ou JApplet?
Não ponha absolutamente nenhum código que requeira permissões (como criação de arquivos) nesse método.
Por mais que você assine o applet e mexa no java.policy, esse método não é considerado “confiável” pela JVM, e roda com permissões baixas.
Veja exatamente como é que a tal applet de exemplo do seu fornecedor funciona.

Pilantra
thingol:
at cadastro_digital.init(cadastro_digital.java:27) at sun.applet.AppletPanel.run(Unknown Source)

Por acaso "init" é a "public void init", e "cadastro_digital" é o nome da classe que estende Applet ou JApplet?
Não ponha absolutamente nenhum código que requeira permissões (como criação de arquivos) nesse método.
Por mais que você assine o applet e mexa no java.policy, esse método não é considerado "confiável" pela JVM, e roda com permissões baixas.
Veja exatamente como é que a tal applet de exemplo do seu fornecedor funciona.

Sim, o init é o public void init e o cadastro_digital é a classe que extende o JApplet. Eu fiz isso que você disse, tirei os codigos que mexem com arquivos, do init. Veja:

public void init() {        
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {
                public void run() {
                    initComponents();
                    instalar();
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public void instalar() {
        try {
            // install grfinger java files in a temporary directory
            GrFingerJavaAppletInstaller installer = GrFingerJavaAppletInstaller.getInstance();
            URL filesDirectory;
            filesDirectory = new URL(this.getDocumentBase(), this.getParameter("filesDirectory") + "/");
            installer.install(filesDirectory, true, true);

            // Creates a match context to perform fingerprint minutiae
            // extraction and match.
            matchContext = new MatchingContext();
            // Initializing GrCapture.
            GrFingerJava.initializeCapture(this);
        } catch (GrFingerJavaException e) {
            JOptionPane.showMessageDialog(this,e.getMessage());
        } catch (MalformedURLException e) {
            JOptionPane.showMessageDialog(this,e.getMessage());
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this,e.getMessage());
        }
    }
Agora não dá erro mas também não funciona hehehe. Será que eu devo criar uma classe separada e chamar o método pelo init?
T

Bom, o problema de permissões se propaga para todas as classes e métodos chamados pelo init, enquanto ele está funcionando.
Uma coisa que você pode tentar fazer é criar uma thread no init, chamando os tais métodos problemáticos.
Em termos de segurança a thread não herda essas limitaçóes de segurança, mas é necessário, no início do método run, configurar o “security manager”.

Pilantra

Putz como é complicado isso!!! Você tem algum exemplo de como fazer essa Thread? Eu nunca mexi com essa parte de segurança no Java, nunca achei que ia precisar também =\

T

Acho que é algo parecido com isto:

import java.security.Permission;
public class MySecurityManager extends SecurityManager {
    public void checkPermission(Permission perm, Object context) {
    }
    public void checkPermission(Permission perm) {
    }    
}

e

public void init() {
          new Thread (new Runnable()  {
          public void run () {
          System.setSecurityManager(new MySecurityManager());
          AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {          
                // fazer o que deve ser feito
                return new Object();            
            }
          });
          }).start();
Pilantra

Valeu cara, vou fazer esses testes, qualquer coisa posto aqui os resultados!!!

Pilantra

Cara, não deu certo. Ele não está dando erro mas também não funciona hehe. O leitor nem da sinal de vida. O que me deixa encucado é que eu fiz do mesmo jeito pra aplicação em desktop, e não quer funcionar. Mais alguma idéia do que possa ser?

Abraços.

T

Hum… agora não sei mais. Você pôs a parte de inicialização do seu pacote dentro do método “run” da classe anônima que estende PrivilegedAction?

Pilantra

Então, eu coloquei. Olha só:

<blockquote>/** Initializes the applet cadastro_digital */

public void init() {

new Thread (new Runnable()  {

public void run () {

JOptionPane.showMessageDialog(new cadastro_digital(),Está funcionando!);

System.setSecurityManager(new MySecurityManager());

AccessController.doPrivileged(new PrivilegedAction() {

public Object run() {

// fazer o que deve ser feito

new cadastro_digital().grfinger = new GrFinger(new cadastro_digital());

grfinger.start();

initComponents();

return new Object();

}

});

};

}).run();

}</blockquote>
T

Que coisa sinistra

Por que é que você chama o construtor de sua applet pelo menos 3 vezes (uma implicitamente ao carregar a applet, outra ao passar uma referência dela ao construtor de GrFinger, e uma terceira ao associar esse objeto GrFinger a um membro de uma nova instância de sua applet? Muito, muito sinistro. Não seria melhor:

É claro que grfinger deve ser declarada como “static” (ou como final, não sei muito bem) na sua classe cadastro_digital, para que você possa acessá-la a partir de uma “inner class”.

Pilantra

hehehehehe, é que quando eu to na base dos testes, eu faço essas gambiarras no código mesmo, mas depois eu deixo bonitinho o código.

Olha só que bizarro, fiz assim do jeito que você pediu, e veja o erro que tá retornando no console:

Exception in thread "Thread-24" java.security.AccessControlException: access denied (java.lang.RuntimePermission createSecurityManager) at java.security.AccessControlContext.checkPermission(Unknown Source) at java.security.AccessController.checkPermission(Unknown Source) at java.lang.SecurityManager.checkPermission(Unknown Source) at java.lang.SecurityManager.<init>(Unknown Source) at MySecurityManager.<init>(MySecurityManager.java:3) at cadastro_digital$1.run(cadastro_digital.java:25) at java.lang.Thread.run(Unknown Source)

Nossa, se fosse pra mim eu já teria desistido, mas infelizmente não tenho escolha hehe. Por que será que está dando esse problema de permissão?? Ah, detalhe, eu uso o Mustang.

T

Aham, eu não copiei isto direito. O correto é:

if (System.getSecurityManager() == null) {
    System.setSecurityManager(new MySecurityManager());
}
Pilantra

Ah legal, acho que o problema da permissão resolveu. Olha o erro que está dando agora:

Exception in thread "Thread-50" java.lang.SecurityException: Unable to create temporary file at java.io.File.checkAndCreate(Unknown Source) at java.io.File.createTempFile(Unknown Source) at java.io.File.createTempFile(Unknown Source) at GrFingerJavaAppletInstaller.<init>(GrFingerJavaAppletInstaller.java:52) at GrFingerJavaAppletInstaller.getInstance(GrFingerJavaAppletInstaller.java:42) at GrFinger.start(GrFinger.java:33) at cadastro_digital$1$1.run(cadastro_digital.java:31) at java.security.AccessController.doPrivileged(Native Method) at cadastro_digital$1.run(cadastro_digital.java:27) at java.lang.Thread.run(Unknown Source)

Nossa, se desse pra fazer em C isso, seria mais fácil hehe!

T

Acho que voltamos à estaca zero.

DISCLAIMER - Se puder não fazer com applets será melhor, porque o tipo de coisas que você quer fazer (acessar arquivos e hardware) não funciona no Windows Vista + IE 7 de jeito nenhum, nem usando Java + arquivos assinados, nem usando ActiveX © e arquivos .cab assinados - leia a documentação da Microsoft para saber por quê. Então você vai se ralar todo só para descobrir que não vai funcionar direito no IE7 + Windows Vista :frowning:

Pilantra

Nossa, eu estou trazendo meu notebook aqui pro trampo, por causa do Windows. E ele tem o Vista instalado =[

Bom, então eu vou passar o projeto pra máquina que tem Linux e começar a fazer tudo de novo hehe!!!

Eu fiz uma pesquisa gigantesca no google, nunca tinha rodado tantas páginas e todas elas ou a maioria, diziam que era pra alterar o java.policy mas mesmo assim não funcionou!! Deve ser por isso mesmo, por causa do Vista. Mas beleza, valeu pela ajuda cara!! Se você morasse aqui em Maringá eu te pagava uma cerveja hehe!!

Abraços!

T

Puxa vida, pensei que você estava se ralando todo em Linux, por causa de sua assinatura.

Mas pense bem: suponha que você tenha de vender a sua solução, mas ela só funciona em L___x, não em W___s Vista (que casualmente estava lhe causando todos esses problemas.)

Será que você consegue vender ou vai ter de sambar feito doido para conseguir resolver (ou pelo menos minorar) os tais problemas?

Veja exatamente quais são os requisitos de sua aplicação, para não ter esses problemas hediondos.

Pilantra

thingol:
Puxa vida, pensei que você estava se ralando todo em Linux, por causa de sua assinatura.

Mas pense bem: suponha que você tenha de vender a sua solução, mas ela só funciona em L___x, não em W___s Vista (que casualmente estava lhe causando todos esses problemas.)

Será que você consegue vender ou vai ter de sambar feito doido para conseguir resolver (ou pelo menos minorar) os tais problemas?

Veja exatamente quais são os requisitos de sua aplicação, para não ter esses problemas hediondos.

Então cara, o que eu acho mais ingraçado é que, a aplicação de exemplo da Griaule, funciona perfeitamente como Applet. Eu estava tomando café e lembrei disso hehe, então o fato de ser Windows Vista ou não, não é verdade. Deve ter algum esquema que eles fizeram pra rodar essa applet. Acho que vou pegar o código deles, e adaptar na minha applet, porque eles não respondem meus e-mails. Então o jeito é gambiarrar =D

Pilantra

Eis aí!! Vamos ver se agora eu consigo.

Pilantra

Somente para complementar. Eu fiz uns testes e fui adaptando o código deles, e recompilei. Deu o mesmo erro que o meu estava dando, mas dae eu fiz uma assinatura digital no .jar e adivinhem… Funcionou ¬¬

Eu acho que era só eu fazer a assinatura digital e tava pronto. Quando eu testei, eu só testei no .jar da aplicação e não da GrFingerJava…

Faz parte hehe.

H

eu estava acompanhando o tópico e achei bastante legal , as etapas percorridas.

eu passei por um problema parecido com este , e resolvi setando o
gerenciador de segurança como nulo.

System.setSecurityManager(null);

Testa é vé se resolve.

T

De fato, no Windows Vista é perfeitamente possível uma applet assinada criar um arquivo temporário, mas ela deve estar assinada. A única coisa chata é que ela, em vez de criar no seu diretório de arquivos temporários tradicional (C:\Documents and Settings\usuario\Application Settings\temp ou coisa parecida). Ele cria em um outro lugar meio escondido que só dá para descobrir navegando pelo Command Prompt. Isso é coisa do Windows Vista.

Pilantra

hugov:
eu estava acompanhando o tópico e achei bastante legal , as etapas percorridas.

eu passei por um problema parecido com este , e resolvi setando o
gerenciador de segurança como nulo.

System.setSecurityManager(null);

Testa é vé se resolve.

Poxa legal isso ein hugov, por via das dúvidas eu vou por isso na aplicação e vou testar sem assinar.

Pois é thingol, o Windows Vista ficou muito chato em alguns aspectos. Tive que remover o controle de conta por usuário porque estava enxendo o saco. O Linux que é mais sistemático não é chato hehe.

Bom, depois de muito esperar, os caras do griaule me responderam, apenas perguntando qual linguagem estou mexendo. Acho que applet só existe pra Java né? :x

Valeu pela força galera.

H

Para seu código funcionar, faça os passos abaixos:

1º O Java Policy

2º A estrutura do Applet

public class SeuApplet extends JApplet {

      public void init() {
		System.setSecurityManager(null);
      }

      public void start() {
            // Aqui você deve fazer as suas chamadas
      }

      public void stop() {
      }
}

3º O Applet

trgpwild

Se eu criar a javapolicy no computador cliente para meu applet eu naum precisarei assina-lo?

Se for isso, voce poderia me dizer como escrever o arquivo java policy?

Se naum for nada disso, voce tb poderia me alertar?

Muito Obrigado…

G

Pilantra:
Somente para complementar. Eu fiz uns testes e fui adaptando o código deles, e recompilei. Deu o mesmo erro que o meu estava dando, mas dae eu fiz uma assinatura digital no .jar e adivinhem… Funcionou ¬¬

Eu acho que era só eu fazer a assinatura digital e tava pronto. Quando eu testei, eu só testei no .jar da aplicação e não da GrFingerJava…

Faz parte hehe.

Cara como tu fez a assinatura digital!? pode mostrar os comandos?

Criado 12 de junho de 2007
Ultima resposta 23 de jul. de 2008
Respostas 25
Participantes 5