You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:15:45