how to specify multiple javafx.graphics dependencies for maven pom.xml file?

Viewed 25

I have made an application that is able to read the weight from a Dymo S100 Scale. My issue is I have created the .jar on a Mac that is intel, however the deployment environment is going to be a mixture of x86 machines that are all Mac OS and a mixture of M1 arm chips. Now if I go with my IDE over to the arm and I build and package it there, it works (I presume because it grabs the correct dependency for the graphics) and that .jar will work for all the arm chips. However I want one .jar to be able to service both machines. I have seen in other posts people adding:

<classifier>mac</classifier>

I have tried this however it did not work... Here is the Main.java file (to be able to package a fat .jar)

package net.webment;

public class Main {
    public static void main(String[] args) {
        App.main(args);
    }
}

Which calls App.java to start the program:

package net.webment;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

/**
 * JavaFX App
 */
public class App extends Application {
    private static int response = 1;

    private static Scene scene;

    @Override
    public void start(Stage stage) throws IOException {
        scene = new Scene(loadFXML("primary"));
        stage.setScene(scene);
        stage.show();
    }

    static void setRoot(String fxml) throws IOException {
        scene.setRoot(loadFXML(fxml));
    }

    private static Parent loadFXML(String fxml) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
        return fxmlLoader.load();
    }

    public static void main(String[] args) {
        launch();
    }


}

which calls PrimaryController.java to open:

package net.webment;

import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ResourceBundle;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class PrimaryController implements Initializable {
    private static int response = 1;
    private static int stable = 0;
    private static double weight = 0;


    @FXML
    private Button btn_Confirm;

    @FXML
    private Label current_Weight_Display;

    @FXML
    private Label current_Weight_Lbl;

    @FXML
    private Label pounds_Lbl;

    @FXML
    private HBox weight_Background;

    public static void setStable(int value) {
        stable = value;
    }

    public void get_Weight() {
            new Thread(() -> {
                try {
                    UsbScale scale = UsbScale.findScale();
                    assert scale != null;
                    scale.open();
                    while (response != 0) {
                        weight = scale.syncSubmit();
                        weight = (double) Math.round(weight * 10d) / 10d;
                        double finalWeight = weight;
                        Platform.runLater(() -> {
                            if (stable == -1) {
                                weight_Background.setStyle("-fx-background-color: red");
                                current_Weight_Display.setTextFill(Color.WHITE);
                                pounds_Lbl.setTextFill(Color.WHITE);
                            } else if (stable == 0) {
                                weight_Background.setStyle("-fx-background-color: white");
                                current_Weight_Display.setTextFill(Color.BLACK);
                                pounds_Lbl.setTextFill(Color.BLACK);
                            } else if (stable == 1) {
                                weight_Background.setStyle("-fx-background-color: green");
                                current_Weight_Display.setTextFill(Color.WHITE);
                                pounds_Lbl.setTextFill(Color.WHITE);
                            }
                            current_Weight_Display.setText(String.valueOf(finalWeight));
                        });
                        //here we want to be updating live a variable on the screen.
                    }
                } catch (NullPointerException e) {
                    create_Error("NullPointerException! " + e.getMessage());
                }

            }).start();

    }

    @FXML
    void on_Action_Confirm(ActionEvent event) {
        if (stable == 1) {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "Are You Sure the Package Weighs: " + weight + " Lbs?", ButtonType.YES, ButtonType.NO);
            alert.showAndWait();
            if (alert.getResult() == ButtonType.YES) {
                create_File(String.valueOf(weight));
                Stage stage = (Stage) btn_Confirm.getScene().getWindow();
                // do what you have to do
                stage.close();
                System.exit(0);
            }
        } else {
            Alert error = new Alert(Alert.AlertType.ERROR, "You Cannot Confirm the Weight While until the Background is Green!");
            error.showAndWait();
        }
    }

    public static void create_File(String Weight) {
        //Use Paths.get in older JVM's
        Path f = Path.of(System.getProperty("user.home"), "Documents", "Weight.txt");
        try {
            Files.writeString(f, Weight, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
            String written = Files.readString(f);
            if (written.equals(Weight)) {
                System.exit(0);
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(0);
        }
    }


    public static void create_Error(String error) {
        //Use Paths.get in older JVM's
        Path f = Path.of(System.getProperty("user.home"), "Documents", "Error.txt");
        try {
            Files.writeString(f, error, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
            String written = Files.readString(f);
            if (written.equals(error)) {
                System.exit(0);
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(0);
        }
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        get_Weight();
    }
}

which calls the UsbScale.java Class:

package net.webment;

import org.usb4java.*;

import javax.usb.*;
import javax.usb.event.UsbPipeDataEvent;
import javax.usb.event.UsbPipeErrorEvent;
import javax.usb.event.UsbPipeListener;
import java.util.List;

public class UsbScale implements UsbPipeListener, AutoCloseable {


    private boolean isOpened = false;
    private final UsbDevice device;
    private UsbInterface iface;
    private UsbPipe pipe;
    private final byte[] data = new byte[6];
    private double finalWeight;
    private Context context;

    public boolean isOpened() {
        return isOpened;
    }

    private UsbScale(UsbDevice device) {
        this.device = device;
    }


    public static UsbScale findScale() {
        UsbServices services;
        UsbHub rootHub = null;
        try {
            services = UsbHostManager.getUsbServices();
            rootHub = services.getRootUsbHub();
        } catch (UsbException e) {
            PrimaryController.create_Error("Error! " + e.getMessage());
        }
        // Dymo S100 Scale:
        assert rootHub != null;
        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);
    }

    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();
            isOpened = true;
        }catch (UsbException e) {
            PrimaryController.create_Error("Error! "+ e.getMessage());
        }


    }

    public void close() {
        if (!isOpened) return;
        try {
            pipe.close();
            iface.release();
            LibUsb.exit(context);
        } catch (UsbException e) {
            PrimaryController.create_Error("Error! "+ e.getMessage());
        }
    }

    public double syncSubmit() {
        try {
            pipe.syncSubmit(data);
        } catch (UsbDisconnectedException disconnectedException) {
            PrimaryController.create_Error("UsbDisconnectedException! "+ disconnectedException.getMessage());
        } catch (UsbException e) {
            PrimaryController.create_Error("Error! "+ e.getMessage());
        }
        return finalWeight;
    }


    @Override
    public void dataEventOccurred(UsbPipeDataEvent upde) {
        //System.out.println(data[1] + ", " + data[2] + ", " + data[3] + ", " + data[4] + ", " + data[5]);
        //if data[1] == 4 value is stable, if data[1] == 3 value is unstable, if data[1] == 5 value is negative, if data[1] == 2 value is 0
        if (data[2] == 12) { //This means it is in imperial Mode
            if (data[1] == 4) {
                PrimaryController.setStable(1);
                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]== 3) {
                PrimaryController.setStable(0);
                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) {
                PrimaryController.setStable(-1);
                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) {
                PrimaryController.setStable(1);
                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]== 3) {
                PrimaryController.setStable(0);
                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) {
                PrimaryController.setStable(-1);
                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) {
        PrimaryController.create_Error("UsbPipeErrorEvent! " + usbPipeErrorEvent.toString());
    }
}

and here is my pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>net.webment</groupId>
    <artifactId>Interface</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.release>11</maven.compiler.release>
        <javafx.version>18.0.2</javafx.version>
        <javafx.plugin.version>0.0.6</javafx.plugin.version>
        <main.class>net.webment.Main</main.class>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.usb4java</groupId>
            <artifactId>usb4java-javax</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>io.github.dsheirer</groupId>
            <artifactId>libusb4java-darwin-aarch64</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>18.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>18.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>18.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.2</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>Dymo_S100</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.6</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running -->
                        <!-- Usage: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>net.webment.Main</mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.2</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>net.webment.Main</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

0 Answers
Related