Ir para o conteúdo

 Voltar a PW3270 Suporte
Tela cheia

[Dúvidas]Java

14 de Novembro de 2012, 9:54 , por Desconhecido - | Ninguém seguindo este artigo por enquanto.
Visualizado 928 vezes

 Perry, devo dizer que é um ótimo trabalho esse que você desenvolveu (e continua desenvolvendo). Muito obrigado.

 Perguntas todas sobre java:

1 - Só a versão 4.2.0 que possui plugin java mais recente?

2 - consegui instanciar um 'terminal' e conectar porém quando tenta pegar o conteúdo só mostra um vazio host.getScreenContent()  ...

System.out.println("Conexão :" + host.isConnected() +  "\nConteudo" + host.getScreenContent());

Resultado -> "Conexão :true
                      Conteudo              " 

 

3 - Em qual diretório devo colocar a classe teste.java  pro pw3270 executar?

4 - Tem algum método do tipo setVisible()  pra mostrar o pw3270 sendo executado? caso não tenha pensei em fazer um swing e atualizar a tela com getScreenContent() mas não seria muito bom pro tempo de execução.

 

Grato 

Autor: Lucas Viana Knochenhauer


3434 comentários

  • 3f09f0772d9354bc3661d73bf02b0f60?only path=false&size=50&d=404Perry Werneck(usuário não autenticado)
    16 de Novembro de 2012, 7:25

     

    Olá,

    Sim. A versão 5 não possui suporte à java;
    Dependendo do tempo entre a conexão e a leitura pode ser que a tela ainda não tenha chegado; uma possível solução é usar obj.waitForTerminalReady(segundos) para esperar um tempo ou testar se isTerminalReady() retornou true.
    Você se refere ao teste.class gerado depois da compilação não? Na verdade ele pode estar em qualquer lugar onde a jvm consiga encontrá-lo porém, para executar dentro do emulador você precisa criar um .xml associando uma opção de menu qualquer à sua classe.
    Se você está rodando em modo stand-alone não, porém, quando chamada por uma opção de menu a janela principal aparece normalmente.

    • 3a2fc82891744f6a6da61d02cba10a3d?only path=false&size=50&d=404Lucas Viana Knochenhauer(usuário não autenticado)
      16 de Novembro de 2012, 12:53

       

      Perry,

      usei o waitFor e o isReady e não funcionou. mas usei o waitForStringAt e deu certo \o/

      Eu estava achando que só tinha o método conect dei uma olhada no .jar com um decompiler e só mostra esse método, não entendo como funciona a ligação entre o .jar e o .dll mas logo aprenderei.

      A versão 5 não possui e não possuirá suporte à Java?

      Muitíssimo grato.

      • 3f09f0772d9354bc3661d73bf02b0f60?only path=false&size=50&d=404Perry Werneck(usuário não autenticado)
        29 de Novembro de 2012, 13:23

         

        Olá,

        Desculpe a demora mas as últimas semanas tem sido bem agitadas.

        A integração entre o .jar e a DLL segue o padrão da JNI; existem vários exemplos pela rede.

        Quanto à sua segunda pergunta "não possuirá suporte à Java" é uma coisa meio radical. (-:

        Até agora não houve necessidade ou pedido de desenvolvimento de uma jni para a versão 5 mas, surgindo necessidade e tempo disponível não é uma coisa muito complicada de se fazer.

        • B54069ff99e50b911de07f5b0f9332a3?only path=false&size=50&d=404Marcelo Bezerra(usuário não autenticado)
          18 de Março de 2013, 11:58

           

          Olá,

           Após renomear o arquivo libpw3270_jni.dll para pw3270_jni.dll e copiá-lo para C:\Windows\System32 (Windows Vista 32 bits) consegui criar uma sessão programaticamente, usando Java . Todavia, ao tentar criar uma sessão em ambiente Windows 7 64 bits o sistema retorna o erro " java.lang.UnsatisfiedLinkError  : C:\Windows\System32\pw3270_jni.dll : não foi possível encontrar o procedimento especificado", apesar de o aplicativo executar normalmente neste ambiente (através do arquivo pw3270.exe. Será que seria necessario criar uma dll em ambiente 64 bits para que o possamos criar uma sessão no Windows 7 64 bits?

          Grato,

          Marcelo

          • 3f09f0772d9354bc3661d73bf02b0f60?only path=false&size=50&d=404Perry Werneck(usuário não autenticado)
            18 de Março de 2013, 14:36

             

            Olá,

            É bem provável que o problema tenha a ver com divergência de arquitetura; que eu saiba uma aplicação de 64 bits não pode carregar DLLs de 32 bits.

             

            • B54069ff99e50b911de07f5b0f9332a3?only path=false&size=50&d=404Marcelo Bezerra(usuário não autenticado)
              18 de Março de 2013, 14:56

               

              Olá,

              Mas o programa (pw3270.exe) executa no windows 7 64 bits...

              Marcelo.

              • 3a2fc82891744f6a6da61d02cba10a3d?only path=false&size=50&d=404Lucas Viana Knochenhauer(usuário não autenticado)
                18 de Março de 2013, 15:13

                 

                dá uma olhada se a pasta do pw é arquivos de programas (x86)  , daí é 32 bits

                se for só arquivos de programas é 64, pra ter mais certeza executa o pw e olha no gerenciador de tarefas se consta (32bits) escrito ao lado de pw3270.exe

              • 3a2fc82891744f6a6da61d02cba10a3d?only path=false&size=50&d=404Lucas Viana Knochenhauer(usuário não autenticado)
                18 de Março de 2013, 15:25

                 

                sistemas 64 executam programas 32 bits, ainda mais o windows

                • 3f09f0772d9354bc3661d73bf02b0f60?only path=false&size=50&d=404Perry Werneck(usuário não autenticado)
                  18 de Março de 2013, 15:41

                   

                  Olá,

                  Uso muito pouco o windows, é verdade que sistemas 64 executam programas 32  mas acho extremamente improvável que programas 64 bits sejam capazes de carregar módulos 32 posto que você precisaria "linkar" um binário escrito para uma arquitetura dentro de outro binário feito para outra arquitetura. Nem quero ver como ficaria a passagem de parâmetros ou o stack numa aplicação desse tipo.

                   

                   

                   

                  • B54069ff99e50b911de07f5b0f9332a3?only path=false&size=50&d=404Marcelo Bezerra(usuário não autenticado)
                    18 de Março de 2013, 15:52

                     

                    Lucas/Perry

                    Está na pasta C:\Program Files (x86) e está rodando em 32 bits. Abri a dll através do Dependency Walker e observei que o sistema não consegue carregar os módulos GPSVC e IESHIMS. Vou tentar algumas coisas e qualquer novidadade eu posto aqui.

                    Grato,

                    Marcelo

                    • B54069ff99e50b911de07f5b0f9332a3?only path=false&size=50&d=404Marcelo Bezerra(usuário não autenticado)
                      25 de Março de 2013, 12:16

                       

                      Consegui criar a sessão no Windows 64. Basta copiar os arquivos lib3270.dll e pw3270_jni.dll para a pasta C:\Windows\SysWOW64 (ao contrário do que muita gente pensa que seria copiá-los para C:\Windows\System32).
                      Agora estou com um novo problema: temos como saber quando o host responde a uma ação enviada pelo programa? Por exemplo, quando em envio um sendEnterKey eu tenho três altenativas:

                      1. O host não respondeu no tempo determinado (A tela permanece a mesma);
                      2. O host respondeu, mas a tela apresentada não corresponde à tela esperada;
                      3. O host respondeu e a tela apresentada corresponde à tela esperada;

                      Aparentemente o envio de uma ação (EnterKey ou PfKey) não modifica o conteúdo da tela, até que se chame algum método que provoque a sua atualização (queryStringAt(), por exemplo). Se usarmos o método waitForStringAt(), mesmo que o host responda antes do timeout o programa obrigatoriamente aguardará até o término do timeout provocando uma execução bastante lenta da aplicação.

                      Também tentei utilizar o retorno dos métodos, mas aparentemente eles retornam o mesmo valor independentemente de a operação ser bem sucedida ou não.

                      Grato,

                      Marcelo.

                      • 3f09f0772d9354bc3661d73bf02b0f60?only path=false&size=50&d=404Perry Werneck(usuário não autenticado)
                        25 de Março de 2013, 14:17

                         

                        Olá,

                        Assumo que você está usando a versão 4 posto que não há suporte java na versão 5.

                        Sobre suas perguntas:

                        O método isTerminalReady()  deve retornar true quando a tela foi corretamente atualizada pelo host;

                        O método WaitForStringAt() deveria esperar até que o host responda, ocorra timeout *E* a string informada exista na tela;

                        O método waitForTerminalReady(seconds) deve esperar por até "N" segundos até que o host responda;

                        O método getConnectionState() retorna o estado da conexão;

                         

                        • B54069ff99e50b911de07f5b0f9332a3?only path=false&size=50&d=404Marcelo Bezerra(usuário não autenticado)
                          25 de Março de 2013, 15:39

                           

                          Perry,

                          Obrigado pelas respostas (e pela tempestividade delas). Estou usando a versão 4.2 revisão 2174. O método waitForStringAt() está retornando sempre o inteiro -1238, independentemente de *encontrar ou não* a string na tela. Com base nas suas respostas, tenho como identificar quando o host respondeu através do método isTerminalReady(), todavia não consigo saber se a tela apresentada corresponde à esperada já que sempre tenho o mesmo retorno. Você tem alguma sugestão?

                          Grato,

                          Marcelo.

                          • 3f09f0772d9354bc3661d73bf02b0f60?only path=false&size=50&d=404Perry Werneck(usuário não autenticado)
                            25 de Março de 2013, 15:50

                             

                            Olá,

                            1238 é timeout; pode ser que o teste pela string esteja com algum problema (talvez conversão de codepage; a lib antiga não era muito esperta nessa parte); uma possível solução é usar waitForTerminaReady() para esperar que o host responda e depois queryStringAt() para ver se é a tela certa ou mesmo comparar a saída de getScreenContentAt() com uma string pré-definida para testar o resultado.

                             

                            • B54069ff99e50b911de07f5b0f9332a3?only path=false&size=50&d=404Marcelo Bezerra(usuário não autenticado)
                              25 de Março de 2013, 17:14

                               

                              Perry,

                              waitForTerminalReady(seconds) não aguarda o tempo passado como argumento; isTerminalReady() retorna "true" mas a tela está em branco; veja o trecho do código e a saída por ele apresentada:

                                      System.out.println(host.getVersion()+"  "+host.getRevision());
                                      System.out.println();       
                                      System.out.println(host.getScreenContent());
                                      int timeout = 0;
                                      int counter = 0;
                                      System.out.println("host.sendEnterKey() -> "+host.sendEnterKey());   
                                      System.err.println("host.isTerminalReady() -> "+host.isTerminalReady());
                                      while( ! host.isTerminalReady() ){
                                          host.waitForTerminalReady(10);
                                          System.out.println("counter -> "+counter++);
                                      }
                                      System.out.println("host.isTerminalReady() -> "+host.isTerminalReady());
                                      synchronized(this){
                                          Thread.sleep(3000);
                                      }
                                      System.out.println(host.getScreenContent());
                                     
                                      if(host.getScreenContentAt(13, 2, 6).equals("Código")){
                                          System.err.println("Encontrou -> "+host.getScreenContentAt(13, 2, 6));
                                      } else {
                                          System.err.println("Não Encontrou -> "+host.getScreenContentAt(13, 2, 6));
                                      }

                              Produz a saída:

                              4.2  2174

                                                                                                             
                               Terminal .....: T2XARSAZ                                                 MSG10
                               IP da Estação.: 10.45.113.42                                                  
                               Base .........: B2B-BS2X                                                      
                                                                                                             
                                          |||||||||||   ||||   |||||||||||   |||||||||||   |||||||||||       
                                          ||||          ||||   ||||           ||||   ||||   ||||   ||||      
                                         ||||          ||||   ||||           ||||   ||||   ||||   ||||       
                                        |||||||||||   ||||   |||||||||||    ||||||||||    ||||||||||         
                                              ||||   ||||          ||||    ||||   ||||   ||||   ||||         
                                             ||||   ||||          ||||    ||||   ||||   ||||   ||||          
                                     |||||||||||   ||||   |||||||||||   |||||||||||   |||||||||||            
                                                                                                             
                                                   SISTEMA DE INFORMACOES BANCO DO BRASIL                    
                                                                                                             
                                                               Tecle ENTER                                   
                                                                                                             
                                                                                                             
                                                                                                             
                                                               ===> SISBB                                    
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             

                              host.sendEnterKey() -> 0
                              host.isTerminalReady() -> false
                              counter -> 0
                              host.isTerminalReady() -> true
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             

                              Não Encontrou ->      
                              host.waitForStringAt(1, 2, "COEPC001", timeout) -> -1238
                               65220676  78CORREIOma de Informações Banco do Brasil                          
                                T2XARSAZ                                              BBBB                   B
                                                                                    BBBBBBBB               BBB
                                25/03/2013                                        BBBBBBBBBBBB           BBBBB
                                17:00:57                                        BBBBBBBBBBBBBBBB       BBBBBBB
                                                                              BBBBBBBBB   BBBBBBBB   BBBBBBBBB
                                                                            BBBBBBBBB       BBBBBBBB   BBBBBBB
                                                                          BBBBBBBBB           BBBBBBBB   BB  
                               Digite o codigo                          BBBBBBBBB               BBBBBBBB     
                                                                      BBBBBBBBB             BBB   BBBBBBBB   
                                                                    BBBBBBBBBBBBBB        BBBBBBB   BBBBBBBB 
                                                                  BBBBBBBBBBBBBBBBBBB   BBBBBBBBBBB   BBBBBBBB
                               Código de Usuário:                   BBBBBBBBBBBBBBB   BBBBBBBBBBB   BBBBBBBB 
                               Senha            :                     BBBBBBBBBBB   BBBBBBBBBBB   BBBBBBBB   
                               Aplicativo       :                       BBBBBBB   BBBBBBBBBBB   BBBBBBBB     
                               -------------------------------------------------------------------------------
                                                                                                             
                                 

                               
                                                                                                             
                               -------------------------------------------------------------------------------
                                                         F3 Comunicados  F5 Encerra                          

                              host.waitForStringAt(15, 2, "a", timeout) -> -1238
                                                                                                             
                               Terminal .....: T2XARSAZ                                                 MSG10
                               IP da Estação.: 10.45.113.42                                                  
                               Base .........: B2B-BS2X                                                      
                                                                                                             
                                          |||||||||||   ||||   |||||||||||   |||||||||||   |||||||||||       
                                          ||||          ||||   ||||           ||||   ||||   ||||   ||||      
                                         ||||          ||||   ||||           ||||   ||||   ||||   ||||       
                                        |||||||||||   ||||   |||||||||||    ||||||||||    ||||||||||         
                                              ||||   ||||          ||||    ||||   ||||   ||||   ||||         
                                             ||||   ||||          ||||    ||||   ||||   ||||   ||||          
                                     |||||||||||   ||||   |||||||||||   |||||||||||   |||||||||||            
                                                                                                             
                                                   SISTEMA DE INFORMACOES BANCO DO BRASIL                    
                                                                                                             
                                                               Tecle ENTER                                   
                                                                                                             
                                                                                                             
                                                                                                             
                                                               ===> SISBB                                    
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             

                              true
                                                                                                             
                               Terminal .....: T2XARSAZ                                                 MSG05
                               IP da Estação.: 10.45.113.42                                                  
                               Base .........: B2B-BS2X                                                      
                                                                                                             
                                          |||||||||||   ||||   |||||||||||   |||||||||||   |||||||||||       
                                          ||||          ||||   ||||           ||||   ||||   ||||   ||||      
                                         ||||          ||||   ||||           ||||   ||||   ||||   ||||       
                                        |||||||||||   ||||   |||||||||||    ||||||||||    ||||||||||         
                                              ||||   ||||          ||||    ||||   ||||   ||||   ||||         
                                             ||||   ||||          ||||    ||||   ||||   ||||   ||||          
                                     |||||||||||   ||||   |||||||||||   |||||||||||   |||||||||||            
                                                                                                             
                                                   SISTEMA DE INFORMACOES BANCO DO BRASIL                    
                                                                                                             
                                                     Comando invalido. Digite SISBB                          
                                                                                                             
                                                                                                             
                                                                                                             
                                                               ===> SISBB                                    
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             

                              Tempo Decorrido -> 5 segundos
                              host.getConnectionState()....................  0

                              • 3f09f0772d9354bc3661d73bf02b0f60?only path=false&size=50&d=404Perry Werneck(usuário não autenticado)
                                26 de Março de 2013, 7:37

                                 

                                Olá,

                                Pelo que deu p'ra ver:

                                * o thread.sleep não é uma boa idéia já que ele para o loop de comunicação; melhor seria usar host.wait(3);

                                * A chamada host.waitForStringAt(1, 2, "COEPC001", timeout) retornou timeout porque a string COEPC001 não existe na posição 1,2;

                                * A chamada host.waitForStringAt(15, 2, "a", timeout) -> -1238  retornou  timeout também porque não existe a string "A" na posição 15,2; na verdade existe um "a" (minúsculas fazem diferença);

                                No caso do SisBB eu uso (em rexx) um mecanismo um pouco diferente: Fico num loop chamando a função waitForTerminalReady() e, dentro dele, testo por cada uma das telas; algo do tipo.

                                while(host.waitForTerminalReady(60) == 0)
                                { if( host.queryStringAt(1,2,"BB30")) { // E uma tela de logon, atuo de acordo  } else if(host.queryStringAt(1,2,"COEPC001")) { // TELA COEPC001, atuo de acordo  } (...)  else  { popup("Tela desconhecida")  } } 

                                • B54069ff99e50b911de07f5b0f9332a3?only path=false&size=50&d=404Marcelo Bezerra(usuário não autenticado)
                                  26 de Março de 2013, 9:40

                                   

                                  Olá Perry,

                                  As saídas "host.waitForStringAt(1, 2, "COEPC001", timeout) -> -1238" e "host.waitForStringAt(15, 2, "a", timeout) -> -1238"
                                  referem-se a um trecho de código que não incluí aqui e estão fora desse contexto; o que eu quis ilustrar foi
                                  que aparentemente a chamada "host.waitForTerminalReady(10)" dentro do loop while retorna tão logo o
                                  host.isTerminalReady() retorne "true", não necessariamente aguardando os 10 segundos passados como argumento; e que
                                  host.isTerminalReady() retorna "true" mas a tela está em branco (uma string em branco, com 1944 posições (24*80 mais os
                                  caracteres LF)). Vide os comandos e suas respectivas saídas:

                                                    COMANDO                                                                               SAÍDA
                                  1. System.out.println("host.sendEnterKey() -> "+host.sendEnterKey());           host.sendEnterKey() -> 0
                                  2. System.err.println("host.isTerminalReady() -> "+host.isTerminalReady());  host.isTerminalReady() -> false
                                  3. while( ! host.isTerminalReady() ){
                                  4.     host.waitForTerminalReady(10);
                                  5.     System.out.println("counter -> "+counter++);                                        counter -> 0 (só passou uma vez pelo loop)
                                  6.  }
                                  7. System.out.println("host.isTerminalReady() -> "+host.isTerminalReady());   host.isTerminalReady() -> true
                                  8. System.out.println(host.getScreenContent());                                            string em branco com 1944 posições (vide telas acima)    

                                  Na linha 8 acima, entendo que a tela que deveria estar disponível seria a tela de login (que é a proxima tela na
                                  sequencia natural), uma vez que o método isTerminalReady() já retornou "true". Mas o que nós temos é uma tela vazia,
                                  onde se eu for checar se determinada string está na tela o retorno será sempre falso conforme mostrado na saída a seguir:

                                                     COMANDO                                                                                        SAÍDA
                                  if(host.getScreenContentAt(13, 2, 6).equals("Código")){
                                       System.err.println("Encontrou -> "+host.getScreenContentAt(13, 2, 6));
                                  } else {                                                                            
                                       System.err.println("Não Encontrou -> "+host.getScreenContentAt(13, 2, 6));      Não Encontrou ->               
                                  }

                                  A pergunta é: teria como host.isTerminalReady() só retornar "true" quando a tela estiver devidamente atualizada?
                                  ou (segundo me parece) nós temos que invocar algum método que provoque a atualização antes de consultarmos determinada
                                  string na tela?

                                  Grato,

                                  Marcelo.

                                  • 3f09f0772d9354bc3661d73bf02b0f60?only path=false&size=50&d=404Perry Werneck(usuário não autenticado)
                                    26 de Março de 2013, 9:53

                                     

                                    Olá,

                                    A "host.waitForTerminalReady(10)" retorna sempre que o estado do terminal fica "OK" ou ocorre timeout, ou seja, se ela saiu e o retorno de isTerminalReady é true o comportamento está correto. O terminal estar "OK" apenas significa que o host terminou de montar não indica que, obrigatóriamente, existe algo na tela (O estado do terminal pode estár ok porém,  em branco; já ví isso ocorrer durante o processo de logon. É por isso uso um mecanismo um pouco diferente do seu testando cada uma das telas possíveis dentro de um loop maior).

                                    Talvez fosse interessante colocar um método para testar o "kybdlock" (teclado disponível) mas isso envolveria alteração no código.

                                     

                                    • B54069ff99e50b911de07f5b0f9332a3?only path=false&size=50&d=404Marcelo Bezerra(usuário não autenticado)
                                      26 de Março de 2013, 10:39

                                       

                                      Ok Perry,

                                      Esses esclarecimentos ajudam a conhecer melhor o funcionamento da biblioteca; acho que vou utilizar o método host.wait(1) (gostei da dica - era outra dúvida que eu tinha a respeito do Thread.sleep()) em conjunto com o tamanho da string retornada do host.getScreenContent(), dentro de um loop para determinar se a tela apresentada corresponde à tela esperada ou se o sistema não respondeu no tempo esperado.

                                      Saudações e obrigado pela ajuda,

                                      Marcelo.

                                       

                                       

              • 3f09f0772d9354bc3661d73bf02b0f60?only path=false&size=50&d=404Perry Werneck(usuário não autenticado)
                18 de Março de 2013, 15:42

                 

                Apesar de rodar no windows 64 o binário é para 32 bits.

Essa comunidade não possui posts nesse blog