运行Dymo秤读取Jar文件无法重复写入,疑为资源未释放
Dymo S100秤读取应用连续运行异常排查求助
我开发了一款从Dymo S100秤读取重量的应用,读取到的重量会写入Weight.txt文件,另一应用读取该文件后会将其删除。当连续多次运行该Jar文件时,程序无法获取重量,且无报错或异常抛出,必须等待约5分钟才能恢复正常运行。我怀疑是程序退出时Writer或对象句柄未被释放,推测需等JVM完全关闭后才能正常运行,希望能得到排查方向的指引。
相关代码
Init.java
package Model; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; public class Init { //Vendor ID = 0x0922 //Product ID = 0x8009 public static void main(String[] args) { try { UsbScale scale = UsbScale.findScale(); assert scale != null; scale.open(); double weight = 0; try { while (weight == 0) { weight = scale.syncSubmit(); } } finally { scale.close(); } weight = (double)Math.round(weight * 10d) / 10d; try { String home = System.getProperty("user.home"); File f = new File(home + File.separator + "Documents" + File.separator + "Weight.txt"); BufferedWriter out = new BufferedWriter(new FileWriter(f)); try { out.write(String.valueOf(weight)); } finally { out.close(); } } catch (IOException e) { System.out.println("An error occurred."); e.printStackTrace(); } } catch (Exception e) { try { String home = System.getProperty("user.home"); File f = new File(home + File.separator + "Documents" + File.separator + "Weight.txt"); BufferedWriter out = new BufferedWriter(new FileWriter(f)); try { out.write("Error! " + e.getMessage()); } finally { out.close(); } } catch (IOException exception) { System.out.println("An error occurred."); exception.printStackTrace(); } } } }
UsbScale.java
package Model; import org.usb4java.*; import javax.usb.*; import javax.usb.event.UsbPipeDataEvent; import javax.usb.event.UsbPipeErrorEvent; import javax.usb.event.UsbPipeListener; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; public class UsbScale implements UsbPipeListener { private final UsbDevice device; private UsbInterface iface; private UsbPipe pipe; private final byte[] data = new byte[6]; private double finalWeight; private Context context; private UsbScale(UsbDevice device) { this.device = device; } public static UsbScale findScale() { try { UsbServices services = UsbHostManager.getUsbServices(); UsbHub rootHub = services.getRootUsbHub(); // Dymo S100 Scale: UsbDevice device = findDevice(rootHub, (short) 0x0922, (short) 0x8009); // // Dymo M25 Scale: // if (device == null) { // device = findDevice(rootHub, (short) 0x0922, (short) 0x8004); // } if (device == null) { return null; } return new UsbScale(device); } catch (Exception e) { try { String home = System.getProperty("user.home"); File f = new File(home + File.separator + "Documents" + File.separator + "Weight.txt"); BufferedWriter out = new BufferedWriter(new FileWriter(f)); try { out.write("Error! " + e.getMessage()); } finally { out.close(); } } catch (IOException exception) { System.out.println("An error occurred."); exception.printStackTrace(); } return null; } } private static UsbDevice findDevice(UsbHub hub, short vendorId, short productId) { for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices()) { UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor(); if (desc.idVendor() == vendorId && desc.idProduct() == productId) { return device; } if (device.isUsbHub()) { device = findDevice((UsbHub) device, vendorId, productId); if (device != null) { return device; } } } return null; } public Device findDevice(short vendorId, short productId) { int result = LibUsb.init(context); if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to initialize libusb.", result); // Read the USB device list DeviceList list = new DeviceList(); result = LibUsb.getDeviceList(context, list); if (result < 0) throw new LibUsbException("Unable to get device list", result); try { // Iterate over all devices and scan for the right one for (Device device: list) { DeviceDescriptor descriptor = new DeviceDescriptor(); result = LibUsb.getDeviceDescriptor(device, descriptor); if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to read device descriptor", result); if (descriptor.idVendor() == vendorId && descriptor.idProduct() == productId) { return device; } } } finally { // Ensure the allocated device list is freed LibUsb.freeDeviceList(list, true); } // Device not found return null; } public void open() { try { context = new Context(); UsbConfiguration configuration = device.getActiveUsbConfiguration(); iface = configuration.getUsbInterface((byte) 0); // this allows us to steal the lock from the kernel DeviceHandle handle = new DeviceHandle(); int result = LibUsb.open( findDevice((short) 0x0922, (short) 0x8009), handle); if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to open USB device", result); result = LibUsb.setConfiguration(handle, 0); if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to set Configuration", result); iface.claim(usbInterface -> true); final List<UsbEndpoint> endpoints = iface.getUsbEndpoints(); pipe = endpoints.get(0).getUsbPipe(); // there is only 1 endpoint pipe.addUsbPipeListener(this); pipe.open(); } catch (Exception e) { try { String home = System.getProperty("user.home"); File f = new File(home + File.separator + "Documents" + File.separator + "Weight.txt"); BufferedWriter out = new BufferedWriter(new FileWriter(f)); try { out.write("Error! " + e.getMessage()); } finally { out.close(); } } catch (IOException exception) { System.out.println("An error occurred."); exception.printStackTrace(); } } } public double syncSubmit() { try { pipe.syncSubmit(data); return finalWeight; } catch (Exception e) { try { String home = System.getProperty("user.home"); File f = new File(home + File.separator + "Documents" + File.separator + "Weight.txt"); BufferedWriter out = new BufferedWriter(new FileWriter(f)); try { out.write("Error! " + e.getMessage()); } finally { out.close(); } } catch (IOException exception) { System.out.println("An error occurred."); exception.printStackTrace(); } return finalWeight; } } public void close() throws UsbException { try { pipe.close(); iface.release(); LibUsb.exit(context); } catch (Exception e) { try { String home = System.getProperty("user.home"); File f = new File(home + File.separator + "Documents" + File.separator + "Weight.txt"); BufferedWriter out = new BufferedWriter(new FileWriter(f)); try { out.write("Error! " + e.getMessage()); } finally { out.close(); } } catch (IOException exception) { System.out.println("An error occurred."); exception.printStackTrace(); } } } @Override public void dataEventOccurred(UsbPipeDataEvent upde) { if (data[2] == 12) { //This means it is in imperial Mode if (data[1] == 4) { int weight = (data[4] & 0xFF) + (data[5] << 8); int scalingFactor = data[3]; finalWeight = scaleWeight(weight, scalingFactor); //final weight, applies to both metric and imperial }else if (data[1] == 5) { int weight = (data[4] & 0xFF) + (data[5] << 8); int scalingFactor = data[3]; finalWeight = scaleWeight(weight, scalingFactor)*(-1); //final weight, applies to both metric and imperial } else if (data[1] == 2) { finalWeight = 0; } } else { //This would mean it is in metric if (data[1] == 4) { int weight = (data[4] & 0xFF) + (data[5] << 8); int scalingFactor = data[3]; finalWeight = (scaleWeight(weight, scalingFactor)*2.20462); //final weight, applies to both metric and imperial } else if (data[1] == 5) { int weight = (data[4] & 0xFF) + (data[5] << 8); int scalingFactor = data[3]; finalWeight = (scaleWeight(weight, scalingFactor)*2.20462)*(-1); //final weight, applies to both metric and imperial } else if (data[1] == 2) { finalWeight = 0; } } } private double scaleWeight(int weight, int scalingFactor) { return weight * Math.pow(10, scalingFactor); } @Override public void errorEventOccurred(UsbPipeErrorEvent usbPipeErrorEvent) { Logger.getLogger(UsbScale.class.getName()).log(Level.SEVERE, "Scale Error", usbPipeErrorEvent); try { String home = System.getProperty("user.home"); File f = new File(home + File.separator + "Documents" + File.separator + "Weight.txt"); BufferedWriter out = new BufferedWriter(new FileWriter(f)); try { out.write("Error! " + usbPipeErrorEvent); } finally { out.close(); System.exit(0); } } catch (IOException exception) { System.out.println("An error occurred."); exception.printStackTrace(); } } }
感谢各位提供排查方向!
内容的提问来源于stack exchange,提问作者Collin Short
相关产品推荐
相关产品推荐

