Home » Eclipse Projects » Virgo » Weird ClassNotFoundException
Weird ClassNotFoundException [message #871448] |
Sun, 13 May 2012 20:08 |
Eduardo Frazão Messages: 123 Registered: January 2012 |
Senior Member |
|
|
Hi all.
Im working on a project that work with USB HID Devices.
I've found a Java library, that wraps some Native libs on Windows, Linux and MAC.
This library works fine. With a normal java flat class path I'vre wrote some code that runs ok.
After tests, I decide to work with OSGi on this project, So I wrap this Native library on a Bundle..
Here is the manifest:
Manifest-Version: 1.0
Bundle-Version: 1.0.0
Bundle-Name: Java JNI USB HID API
Bundle-ManifestVersion: 2
Bundle-Vendor: Wrapped by Autmix
Bundle-SymbolicName: br.com.autmix.javahidapi
Export-Package: com.codeminders.hidapi;version="1.0.0"
Bundle-NativeCode: libs/native/linux_x64/libhidapi.so;
processor=x86_64;osname=Linux,
libs/native/linux_x86/libhidapi.so;processor=x86;osname=Linux,
libs/native/win_x86/libhidapi.dll;processor=x86;
osname=WindowsXP;osname=WindowsVista;
osname=Windows7;osname=WindowsServer2008
Again, the library os working fine. The native librarys is loading normally on Virgo Kernel 3.0.3. I can read and write data on the USB Device.
To do that I have a class that open a Thread, and this thread read values from device, and send it to listeners.
Is possible that any time, the USB Device goes away from the USB Bus, and the HID protocol sends a notification when it occours.
In this moment, I have a Class Not Found exception of a class that I've imported the package. Only in this moment. And I have not so mutch information on stack trace to debug:
This is the Class:
package br.com.autmix.bridgeusb;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.codeminders.hidapi.HIDDevice;
import com.codeminders.hidapi.HIDDeviceInfo;
import br.com.autmix.bridgeusb.AutmixHidManager.ChangeEventType;
import br.com.autmix.bridgeusb.AutmixHidManager.DeviceListChangeEvent;
import br.com.autmix.comunicador.api.Bridge;
import br.com.autmix.comunicador.api.BridgeBusType;
import br.com.autmix.comunicador.api.DeviceChangeEventType;
public class BridgeUSB extends Bridge {
private HIDDevice device;
private Integer productId;
private Integer vendorId;
private boolean threadLoopControll = false;
// Cache de buffers
private Map<Integer, int[]> bufferCache = new HashMap<Integer, int[]>();
private AutmixHidManager.DeviceListChangeListener localAnonymousHidListener;
public BridgeUSB(Integer vendorId, Integer productId) throws IOException {
super();
this.productId = productId;
this.vendorId = vendorId;
AutmixHidManager.getInstance();
device = AutmixHidManager.openById(vendorId, productId, null);
if(device == null) {
AutmixHidManager.getInstance().release();
throw new IOException(String.format("Impossivel abrir dispositivo {VendorID: %d, ProductID: %d}", vendorId, productId));
}
device.enableBlocking();
startListen();
openUSBDaemon();
}
/**
* Se registra como ouvinte no Manager HID, para receber eventos sobre a bridge controlada por esta instancia.
*/
private void startListen() {
AutmixHidManager.getInstance().addListener(localAnonymousHidListener = new AutmixHidManager.DeviceListChangeListener() {
@Override
public void deviceListChanged(DeviceListChangeEvent event) {
if((event.getDeviceInfo().getProduct_id() == productId && event.getDeviceInfo().getVendor_id() == vendorId)) {
if(event.getEnventType() == ChangeEventType.DEVICE_REMOVED) {
threadLoopControll = false;
try {
device.close();
} catch (Exception e) {
e.printStackTrace();
}
device = null;
Logger.getLogger(BridgeUSB.class.getName())
.log(Level.INFO, String.format("BridgeUSB associada [p_id: %d / v_id: %d] foi removida do barramento.", productId, vendorId));
notifyListeners(DeviceChangeEventType.DEVICE_REMOVED, BridgeUSB.this);
}
else if(event.getEnventType() == ChangeEventType.DEVICE_ADDED) {
Logger.getLogger(BridgeUSB.class.getName())
.log(Level.INFO, String.format("BridgeUSB associada [p_id: %d / v_id: %d] foi reconectada ao barramento.", productId, vendorId));
try {
HIDDeviceInfo deviceInfo = event.getDeviceInfo();
device = deviceInfo.open();
device.enableBlocking();
openUSBDaemon();
notifyListeners(DeviceChangeEventType.DEVICE_ADDED, BridgeUSB.this);
} catch (Exception e) {
Logger.getLogger(BridgeUSB.class.getName()).log(Level.SEVERE, "Impossivel abrir comunicacao com dispositivo apos reconexao.");
}
}
}
}
});
}
@Override
public BridgeBusType getBusType() {
return BridgeBusType.USB;
}
@Override
/**
* {@inheritDoc}
*/
public void requestRefresh() {
// TODO Verificar como funcionara este recurso na bridgeUSB
}
@Override
/**
* {@inheritDoc}
*/
public Map<Integer, Integer> getValue(Integer index, Integer... posicoes) {
synchronized (bufferCache) {
if(bufferCache.get(index) != null) {
HashMap<Integer, Integer> mapa = new HashMap<Integer, Integer>();
for(Integer posicao : posicoes) {
mapa.put(posicao, bufferCache.get(index)[posicao]);
}
return mapa;
}
return null;
}
}
@Override
/**
* {@inheritDoc}
*/
public void setValue(Integer index, Map<Integer, Integer> posicoesValores) throws IOException {
synchronized (bufferCache) {
if(device == null) {
throw new IOException("O dispositivo USB ainda nao esta pronto.");
}
byte[] buffer = new byte[64];
buffer[0] = (byte) (int) index;
Iterator<Integer> iter = posicoesValores.keySet().iterator();
while(iter.hasNext()) {
int posicao = iter.next();
if(posicao == 0) {
throw new IllegalArgumentException("Nao e permitido associar valores a posicao [0], pois ela define o tipo do buffer");
}
int valor = posicoesValores.get(posicao);
buffer[posicao] = (byte) valor;
}
device.writeTimeout(buffer, 5000);
}
}
@Override
/**
* {@inheritDoc}
*/
public synchronized void release() {
threadLoopControll = false;
removeAllListeners();
try {
if(device != null) {
try {
device.disableBlocking();
}
finally {
device.close();
AutmixHidManager.getInstance().removeListener(localAnonymousHidListener);
AutmixHidManager.releaseInstance();
}
}
} catch (Exception e) {
Logger.getLogger(BridgeUSB.class.getName()).log(Level.SEVERE, "Erro ao tentar liberar recursos da bridge.", e);
}
}
/**
* Recebe um buffer vindo do dispositivo USB, e notifica os interessados sobre valores alterados.
* @param index Indice de leitura do buffer. Determina a classe de dispositivos
* @param buffer Buffer com valores de leitura
*/
private void bufferReceived(Integer index, byte[] buffer) {
Map<Integer, Integer> mapa = new HashMap<Integer, Integer>();
if(bufferCache.get(index) != null) {
int[] cacheBuffer = bufferCache.get(index);
for(int i = 1; i < buffer.length; i++) {
int valorCache = (int) cacheBuffer[i];
int valor = (int) buffer[i];
if(valor<0) {valor+=256;}
if( valor != valorCache ) {
mapa.put(i, valor);
}
// Atualizando buffer
cacheBuffer[i] = buffer[i];
}
}
else {
int[] newBuffer = new int[64];
for(int i = 1; i<buffer.length; i++) {
int valor = (int) buffer[i];
if(valor<0) {
valor += 256;
}
mapa.put(i, valor);
// Atualizando buffer
newBuffer[i] = (int) buffer[i];
}
bufferCache.put(index, newBuffer);
}
if(!mapa.isEmpty()) {
notifyValueChangeListeners(index, mapa);
}
}
/**
* Abre a thread de leitura do dispositivo.<br />
* O Controle da thread e extremamente simples.<br />
* Note que a leitura do dispotivio realiza lock na thread.<br />
* E necessario fechar o dispositivo, e entao anular o controle da thread para encerra-la
*/
private void openUSBDaemon() {
threadLoopControll = true;
Thread readThread = new Thread(new Runnable() {
@Override
public void run() {
while(threadLoopControll) {
if(device != null) {
try {
byte[] buffer = new byte[64];
device.readTimeout(buffer, 5000);
if(!Arrays.equals(buffer, new byte[64])) {
synchronized (bufferCache) {
bufferReceived((int) buffer[0], buffer);
}
}
} catch (Exception e) {
Logger.getLogger(BridgeUSB.class.getName()).log(Level.SEVERE, "Erro ao ler dados do dispositivo.", e);
try {
Thread.sleep(1000L);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
Logger.getLogger(BridgeUSB.class.getName()).log(Level.INFO, "Encerrando thread de leitura de dispositivo.");
}
});
readThread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
Logger.getLogger(BridgeUSB.class.getName()).log(Level.INFO, "Startando thread de leitura de dispositivo.");
readThread.start();
}
}
And this is the error:
[2012-05-13 16:39:54.322] ERROR Thread-32 System.err Exception in thread "Thread-32" java.lang.NoClassDefFoundError: com/codeminders/hidapi/HIDDeviceInfo
[2012-05-13 16:39:54.322] ERROR Thread-32 System.err Caused by: java.lang.ClassNotFoundException: com.codeminders.hidapi.HIDDeviceInfo
[2012-05-13 16:39:54.323] ERROR Thread-32 System.err at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
[2012-05-13 16:39:54.323] ERROR Thread-32 System.err at java.security.AccessController.doPrivileged(Native Method)
[2012-05-13 16:39:54.323] ERROR Thread-32 System.err at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
[2012-05-13 16:39:54.323] ERROR Thread-32 System.err at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
[2012-05-13 16:39:54.323] ERROR Thread-32 System.err at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
[2012-05-13 16:39:54.323] ERROR Thread-32 System.err at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
How can I debug that: It is the Full stack trace.
Thanks all!
|
|
| | |
Goto Forum:
Current Time: Fri Apr 19 15:40:57 GMT 2024
Powered by FUDForum. Page generated in 0.01449 seconds
|