Comunicação serial , libLinuxSerialParallel.so ambiente 64 bits [RESOLVIDO]

5 respostas
J

jPessoal

Voltei a estudar java mais um pouquinho, me deparei com o seguinte problema, ao tentar desenvolver uma classe que faz uso da comunicação serial no eclipse.

Usando API javacomm, justamente quando tenta identificar as portas seriais existentes:
Enumeration portas = CommPortIdentifier.getPortIdentifiers();

ocorre o seguinte erro:
Error loading LinuxSerialParallel: java.lang.UnsatisfiedLinkError: /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/libLinuxSerialParallel.so: /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/libLinuxSerialParallel.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch)

Havia compilado antes usando java-6-sun, e deu a mesma mensagem.

Pensei: “Raios, o driver linux que veio com a API javacomm, o libLinuxSerialParallel.so, foi feito para linux sistema 32 bits. Enquanto que o JRE e eclipse que estou usando são 64 bits”.
Fui conferir no site da Oracle, http://www.oracle.com/technetwork/java/index-jsp-141752.html , não há informações sobre as arquiteturas 32 e 64 bits para esse driver.

E ai? É possível converter o driver da API para 64 bits?
Isso tem cura?

Uso linux ubuntu 11.04 natty 64 bits

5 Respostas

E

olá!

vc copiou as bibliotecas (.SO) para as pastas certas?
Se eu não me engano, essas bibliotecas funcionam normalmente no 32 bits e no 64.

No windows, vc tem que colocar as DLL na pasta C:\Windows, porque dava erro quando eu colocava na mesma pasta do JRE, como mandava o tutorial.

J

Pesquisei tanto sobre esse problema, que encontrei mais de uma forma de instalar a javacomm e não sei qual está correta:

Eu criei diretório para receber o driver API javacomm da sun: No meu caso, criei em :
/home/nomedousuario/workspace/API

Baixei API driver da sun em: http://java.sun.com/products/javacomm/ (talvez tenha que se cadastrar no site), e salvei dentro da pasta API:
Na data de hoje, havia o arquivo comm3.0_u1_linux.zip

Descompactei com unzip, que deverá criar uma pasta chamada commapi.

Entrei na pasta API
$ cd /home/nomedousuario/workspace/API/commapi

Copiei os drivers da seguinte maneira:
$ sudo cp /home/nomedousuario/workspace/API/commapi/docs/javax.comm.properties /usr/lib/jvm/java-6-sun/jre/lib
$ sudo cp /home/nomedousuario/workspace/API/commapi/jar/libLinuxSerialParallel.so /usr/lib/

Deu certo também, em uma máquina virtual 32 bits para resolver esse problema, apenas copiando libLinuxSerialParallel.so e o javax.comm.properties em /usr/lib/jvm/java-6-sun/jre/lib/i386/

Verifiquei as máquinas virtuais java no meu computador:
$ sudo update-java-alternatives -l

Me certifiquei que estou realmente usando a máquina virtual da sun:
$ sudo update-alternatives --config java
ou
$ sudo update-java-alternatives -s java-6-sun

Conferi se o diretório está está correto, no meu caso, tenho um link chamado java-6-sun em /usr/lib/jvm/ apontando para a útlima versão de java, que é java-6-sun-1.6.0.24

$ ls -la /usr/lib/jvm/

Verifiquei a versão de seu java
$ java -version
java version “1.6.0_24”
Java™ SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot™ 64-Bit Server VM (build 19.1-b02, mixed mode)

No menu do Eclipse, cliquei em Project, Properties, Java Build Path, Libraries, Add External Jars e especifiquei o caminho /home/nomedousuario/workspace/API/commapi/jar/comm.jar

Eu acredito que os EXPORTS estejam corretos, não sei como fazer isso, acredito que o linux instala o eclipse via pacote tudo direitinho.

J

Essa foi fortíssima:

Acabo de descobrir, quase que por acaso, que o linux disponibiliza para instalação um pacote chamado ia32-java-6-sun, alternativo para ambiente 64bits, sem ter que sair dele.

Instalei essa belezinha de 32 bits em uma máquina de 64 bits:
$ sudo apt-get install ia32-sun-java6-bin

No Eclipse, fui no projeto, menu Run > Run Configurations. Na aba JRE, selecionei Alternate JRE e clique em Installed JREs.
Nesse momento, foi possível adicionar as JREs alternativas, clicando em ADD. No meu caso, adicionei /usr/lib/jvm/ia32-java-6-sun-1.6.0.24

voy a lá, sumiu o erro!

Vou testar mais coisas, tenho que sair agora.
Se tudo der certo, volto para marcar o tópico como resolvido.

J
Acabo de testar mais um pouco o programa que identifica as portas seriais disponíveis:
import java.io.*;
import javax.comm.*;
import java.util.*;

public class PortWriter  
{
    static Enumeration ports;
    static CommPortIdentifier pID;
    static OutputStream outStream;
    static SerialPort serPort;
    static InputStream  is;   
    static PrintStream    os;         
    static int i=0;
    public PortWriter() throws Exception{
        try
        {        
        serPort = (SerialPort)pID.open("/dev/ttyUSB0",2000);
        System.out.println();
        System.out.println();
        //System.out.println("\ngetDataBits"+serPort.getDataBits());
        //System.out.println("\ngetStopBits"+serPort.getStopBits());
        //System.out.println("\ngetParity"+serPort.getParity());
        //System.out.println("\ngetBaudRate"+serPort.getBaudRate());
        serPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
  
		try {
		  is = serPort.getInputStream();
		} catch (IOException e) {
		  System.err.println("Can't open input stream: write-only");
		  is = null;
		}

        os = new PrintStream(serPort.getOutputStream(),true, "US-ASCII");

        
        }
        catch (PortInUseException e)
        {
        System.out.println("PortInUseException : "+e);
        }
        catch (Exception e)
        {
        System.out.println("PortInUseException : "+e);
        }

    }    
    
    public static void main(String[] args) throws Exception{
        ports = CommPortIdentifier.getPortIdentifiers();
        
        while(ports.hasMoreElements())
        {
            pID = (CommPortIdentifier)ports.nextElement();
            System.out.println("Port " + pID.getName());
            
            if (pID.getPortType() == CommPortIdentifier.PORT_SERIAL)
            {
                if (pID.getName().equals("/dev/ttyUSB0"))
                {
                    PortWriter pWriter = new PortWriter();
                    System.out.println("USB found");
                    try {
                    //String sCMGF= "AT+CMGF=1\r\n";
                    //send(sCMGF);
                    //Thread.sleep(1000);
              
                    String sCMGS="AT+CMGS=\"+[telefone removido]\"\r\n";
                    send(sCMGS);
                    Thread.sleep(1000);
                    String smsMessage="hi testing done\032\r\n";
                    send(smsMessage);
                    
                
                    if (is != null) 
                    	is.close();
					if (os != null) 
						os.close();
					if (serPort != null) 
						serPort.close();					
					} 
					catch (IOException e) 					
					{					
					System.out.println("could not write to outputstream:");					
					System.out.println(e.toString());					
					}
                }
            }
        }
        
    }

    public static void send(String cmd) 
    {
    	try 
    	{
    	os.write(cmd.getBytes());
    	} catch (IOException e) 
    	{
           System.out.println("IO Exception : "+e);
    	}
    }
}

Instalando o jre 32 bits denominado i32-java-6-sun em meu linux ubuntu 64 bits, e configurando o projeto para rodar usando essa mesma JRE, resolve o problema.
Desconheço o por quê do driver linux javacomm libLinuxSerialParallel.so não ser compatível com ambiente 64bits.
Parece não haver continuidade no desenvolvimento deste.

J

ATUALIZAÇÃO !!!

A questão acima pode ser melhor resolvida pela seguinte maneira:

Baixe a API versão do RxTX para sistemas linux 64bits, disponível em Cloudhopper( http://www.cloudhopper.com/opensource/rxtx/ )
Descompacte se necessário.

Copie librxtxSerial.so para dentro da pasta: /usr/lib/jvm/java-6-sun/jre/lib/amd64/
Copie a API RXTXcomm.jar para a pasta: /usr/lib/jvm/java-6-sun/jre/lib/ext/
Adicione em sua IDE o jar externo, no meu caso, ficou: /usr/lib/jvm/java-6-sun/jre/lib/ext/RXTXcomm.jar
PS: estou considerando que o link simbólico java-6-sun de seu sistema esteja apontando corretamente para versão atual de sua jvm.

Talvez seja necessário uma limpeza:
a) Apague o arquivo javax.comm.properties da pasta /usr/lib/jvm/java-6-sun/jre/lib
b) Apague o arquivo libLinuxSerialParallel.so da pasta /usr/lib/
c) Uma reinicialização do sistema :evil: pode ser necessária.

Com o descoberto acima, evita-se o uso de jvm ia32-java-6-sun em máquinas atuais de 64Bits. O build path e libraries voltam para o original e a manutenção da felicidade do desenvolvedor.

Criado 8 de junho de 2011
Ultima resposta 11 de out. de 2011
Respostas 5
Participantes 2