developersu / ns-usbloader

Awoo Installer and GoldLeaf uploader of the NSPs (and other files), RCM payload injector, application for split/merge files.
GNU General Public License v3.0
1.81k stars 123 forks source link

macOS arm64 support? #91

Open lihaochen910 opened 3 years ago

lihaochen910 commented 3 years ago
kanbaru@MacBook-Air ~ % java -version
openjdk version "16" 2020-11-11
OpenJDK Runtime Environment Microsoft (build 16+10-20201111)
OpenJDK 64-Bit Server VM Microsoft (build 16+10-20201111, mixed mode)
kanbaru@MacBook-Air ~ % lipo -archs /usr/bin/java
x86_64 arm64e
kanbaru@MacBook-Air ~ % java -jar ~/Downloads/ns-usbloader-5.0.jar 
Loading library prism_es2 from resource failed: java.lang.UnsatisfiedLinkError: /Users/Kanbaru/.openjfx/cache/11/libprism_es2.dylib: dlopen(/Users/Kanbaru/.openjfx/cache/11/libprism_es2.dylib, 1): no suitable image found.  Did find:
    /Users/Kanbaru/.openjfx/cache/11/libprism_es2.dylib: mach-o, but wrong architecture
    /Users/Kanbaru/.openjfx/cache/11/libprism_es2.dylib: mach-o, but wrong architecture
java.lang.UnsatisfiedLinkError: /Users/Kanbaru/.openjfx/cache/11/libprism_es2.dylib: dlopen(/Users/Kanbaru/.openjfx/cache/11/libprism_es2.dylib, 1): no suitable image found.  Did find:
    /Users/Kanbaru/.openjfx/cache/11/libprism_es2.dylib: mach-o, but wrong architecture
    /Users/Kanbaru/.openjfx/cache/11/libprism_es2.dylib: mach-o, but wrong architecture
    at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
    at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:383)
    at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:227)
    at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:169)
    at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2407)
    at java.base/java.lang.Runtime.load0(Runtime.java:747)
    at java.base/java.lang.System.load(System.java:1857)
    at com.sun.glass.utils.NativeLibLoader.installLibraryFromResource(NativeLibLoader.java:205)
    at com.sun.glass.utils.NativeLibLoader.loadLibraryFromResource(NativeLibLoader.java:185)
    at com.sun.glass.utils.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:157)
    at com.sun.glass.utils.NativeLibLoader.loadLibrary(NativeLibLoader.java:52)
    at com.sun.prism.es2.ES2Pipeline.lambda$static$0(ES2Pipeline.java:68)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:312)
    at com.sun.prism.es2.ES2Pipeline.<clinit>(ES2Pipeline.java:50)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:377)
    at com.sun.prism.GraphicsPipeline.createPipeline(GraphicsPipeline.java:187)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:91)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
    at java.base/java.lang.Thread.run(Thread.java:832)
Loading library prism_sw from resource failed: java.lang.UnsatisfiedLinkError: /Users/Kanbaru/.openjfx/cache/11/libprism_sw.dylib: dlopen(/Users/Kanbaru/.openjfx/cache/11/libprism_sw.dylib, 1): no suitable image found.  Did find:
    /Users/Kanbaru/.openjfx/cache/11/libprism_sw.dylib: mach-o, but wrong architecture
    /Users/Kanbaru/.openjfx/cache/11/libprism_sw.dylib: mach-o, but wrong architecture
java.lang.UnsatisfiedLinkError: /Users/Kanbaru/.openjfx/cache/11/libprism_sw.dylib: dlopen(/Users/Kanbaru/.openjfx/cache/11/libprism_sw.dylib, 1): no suitable image found.  Did find:
    /Users/Kanbaru/.openjfx/cache/11/libprism_sw.dylib: mach-o, but wrong architecture
    /Users/Kanbaru/.openjfx/cache/11/libprism_sw.dylib: mach-o, but wrong architecture
    at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
    at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:383)
    at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:227)
    at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:169)
    at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2407)
    at java.base/java.lang.Runtime.load0(Runtime.java:747)
    at java.base/java.lang.System.load(System.java:1857)
    at com.sun.glass.utils.NativeLibLoader.installLibraryFromResource(NativeLibLoader.java:205)
    at com.sun.glass.utils.NativeLibLoader.loadLibraryFromResource(NativeLibLoader.java:185)
    at com.sun.glass.utils.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:157)
    at com.sun.glass.utils.NativeLibLoader.loadLibrary(NativeLibLoader.java:52)
    at com.sun.prism.sw.SWPipeline.lambda$static$0(SWPipeline.java:42)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:312)
    at com.sun.prism.sw.SWPipeline.<clinit>(SWPipeline.java:41)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:377)
    at com.sun.prism.GraphicsPipeline.createPipeline(GraphicsPipeline.java:187)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:91)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
    at java.base/java.lang.Thread.run(Thread.java:832)
Graphics Device initialization failed for :  es2, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
    at com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
    at com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:222)
    at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:260)
    at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
    at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
    at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:94)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
    ... 1 more
Exception in thread "main" java.lang.RuntimeException: No toolkit found
    at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:272)
    at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
    at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
    at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:832)
StarHack commented 1 year ago

The solution to this is quite simple - just build it yourself.

Preparations

Build steps

From a terminal window, run the following commands:

git clone https://github.com/developersu/ns-usbloader.git
cd ns-usbloader
mvn compile package

Afterwards, the current version (ns-usbloader-6.2-20221204.jar as of now) will be located in the target directory. Run it via: ns-usbloader-6.2-20221204.jar

Download

ns-usbloader-6.2 (arm64): ns-usbloader-6.2-20221204.195540.jar.zip

built using openjdk 11.0.17 2022-10-18 LTS Corretto

tuxfamily commented 1 year ago

ns-usbloader-7.0 (arm64): ns-usbloader-7.0-20230209.220242.jar.zip

built using openjdk 19.0.2 2023-01-17

developersu commented 1 year ago

It's kinda fixed. At least in latest version you can just use -m1.jar file.

Now to people, who are interested and want to understand JavaFX world. There is an 'official' way to build it https://github.com/openjfx/javafx-maven-plugin/issues/112 . JavaFX developers proposes to remove every from the code and use their plugin. There is a configuration should be set in their plugin, where we have to declare main class. Main class should have public static void main... AND extend Application. Therefore, it should be the same class that we define in manifest. It makes sense, but I was not able to run application (packed to fat-jar) in situation when main(...) class and Application class were the same class. Now it's two different classes because it simply works! Anyway, in case we use plugin then all classifiers have to be removed (otherwise it's not working at all). For JFX I'm using 'scope-compile'. This means that either every-possible-classifier of the JFX library would be added inside fat-jar OR most likely only building-target-classifier would be added. In older releases I've set both classifiers for 'mac' and 'mac-aarch64' and it didn't work. As I understand, once executed, application tried to pick amd64 instead of aarch64 if it were compiled on Linux host. Or during compilation there were a 'overlap competition' between mac-amd64 and mac-aarch64 libraries. It was not happening in case application had built on mac m1 host.. because.. aarch64 libraries came first? IDK

Workaround is:

  1. Do not use JavaFX plugin
  2. Create one build for amd64 macOS (mac classifier) and another one for aarch64 (mac-aarch64)

Correct solution: Find a way to create universal fat-jar But(t) in the same time it should be able to be wrapped into exe via launch4j (or anything similar). Because in some setups with java9 modules it simply didn't start. Because modules had to be set via keys transferred to application during startup (--module-path, --module) and this makes no sense for desktop user-friendly application.

Dear reader, if you know how to do it right, please let me know =)

alexnovelli commented 1 year ago

I have just downloaded 7.0 M1 version but I'm having the same issue I had before. Awoo is connect to USB but the files sent by NS USBLoader does not appear in Awoo. I'm using Java 19.0.2 for M1. I'm noob with Java. Somebody knows how to log the error?

java 19.0.2 2023-01-17
Java(TM) SE Runtime Environment (build 19.0.2+7-44)
Java HotSpot(TM) 64-Bit Server VM (build 19.0.2+7-44, mixed mode, sharing)
developersu commented 1 year ago

@alexnovelli Hi, please try this one. (It's the same build but with libusb4java.dylib compiled by me. Small chance, but maybe issue is in there.)

Once something failed, click on the last tab on the left-hand side panel. Errors should appear appear in there. Also you can start application from terminal (command line), e.g. java -jar Downloads\ns-usbloader-v7.0-m1.jar. There are usually more information appears. So, just copy-paste what you see and that's will be the start.

UPD: I guess it's because I placed library into the wrong place. In debug it may say where it's suppose to be. In terminal.

alexnovelli commented 1 year ago

Does't work...

The errors opening through Terminal:

After open app:

Feb 13, 2023 4:08:02 PM com.sun.javafx.application.PlatformImpl startup
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @1e643faf'

After tried to send through USB:

Exception in thread "Thread-8" java.lang.UnsatisfiedLinkError: /private/var/folders/q3/xjhmwqw50xx0g9sjvl270pbw0000gn/T/usb4java1183910442990153560.tmp/libusb4java.dylib: dlopen(/private/var/folders/q3/xjhmwqw50xx0g9sjvl270pbw0000gn/T/usb4java1183910442990153560.tmp/libusb4java.dylib, 0x0001): Library not loaded: /opt/homebrew/opt/libusb/lib/libusb-1.0.0.dylib
  Referenced from: <E33442D9-6956-3C6B-BB9F-A7F650A16BEE> /private/var/folders/q3/xjhmwqw50xx0g9sjvl270pbw0000gn/T/usb4java1183910442990153560.tmp/libusb4java.dylib
  Reason: tried: '/opt/homebrew/opt/libusb/lib/libusb-1.0.0.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/opt/libusb/lib/libusb-1.0.0.dylib' (no such file), '/opt/homebrew/opt/libusb/lib/libusb-1.0.0.dylib' (no such file), '/usr/local/lib/libusb-1.0.0.dylib' (no such file), '/usr/lib/libusb-1.0.0.dylib' (no such file, not in dyld cache)
    at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
    at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)
    at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2498)
    at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2694)
    at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2627)
    at java.base/java.lang.Runtime.load0(Runtime.java:768)
    at java.base/java.lang.System.load(System.java:1837)
    at org.usb4java.Loader.load(Loader.java:323)
    at org.usb4java.LibUsb.<clinit>(LibUsb.java:690)
    at nsusbloader.com.usb.UsbConnect.createContextAndInitLibUSB(UsbConnect.java:115)
    at nsusbloader.com.usb.UsbConnect.connectHomebrewMode(UsbConnect.java:82)
    at nsusbloader.com.usb.UsbCommunications.run(UsbCommunications.java:54)
    at java.base/java.lang.Thread.run(Thread.java:829)
developersu commented 1 year ago

@alexnovelli Thank you, it helps! Could you please check this one? I'm interested if there are still errors after you try to send through USB.

If it still doesn't work, install libusb manually via brew install libusb. It's workaround and I'm trying to avoid it..

alexnovelli commented 1 year ago

Works with brew install! Thank you so much @developersu

developersu commented 1 year ago

Well.. yeah.. you're welcome 🥲

xnico77x commented 1 year ago

Hey guys how do install it ? I have installed Zulu but what's the next step ?

StarHack commented 1 year ago

Could you please check this one? I'm interested if there are still errors after you try to send through USB.

@developersu This won't work because the libusb4java.dylib in your jar contains the following LC_LOAD_DYLIB command:

Load command  12
          cmd LC_LOAD_DYLIB
      cmdsize 72
         name /opt/homebrew/opt/libusb/lib/libusb-1.0.0.dylib (offset 24)
   time stamp 2 Thu Jan  1 01:00:02 1970
      current version 4.0.0
compatibility version 4.0.0

Also known as dynamic linking, people are required to have this library in place. If you want people to be able to run this without installing libusb first, you need to build a static version of the library:

brew install automake

git clone https://github.com/usb4java/libusb4java.git
cd dists/darwin/
./build

This will give us a statically linked libusb4java.dylib in target/build/darwin-arm64/root/lib/. Ship this with your jar file and it should work properly.

developersu commented 1 year ago

@StarHack I'm afraid it doesn't work because usb4java seeks for this lib in the wrong place, and since I don't have time to test this (and mac) now it will remain the same for some time. Shipping folder with library placed inside along with the JAR doesn't look like a good solution. Also you can search for a correct place where dylib should be placed at inside the JAR and let us know :) Tip: information here is a good starting point, but seems incorrect in lib location assumptions http://usb4java.org/nativelibs.html.

StarHack commented 1 year ago

@developersu Yes, and that's because it's a dynamically linked version of the library. Once you create a static build as described above this won't happen as it won't have to seek for this library at all since it will be included in usb4java. In fact I was not talking about shipping the entire folder, I was talking about shipping a different build of usb4java only. I attached static builds for darwin (x86_64 and arm64).

usb4java-darwin-static.zip

developersu commented 1 year ago

@StarHack dylib is an extension for dynamically linked library.. you've attached dylibs in your zip.. Anyway, could you please create jar file that incorporates libraries you created? Because I guess it could be shipped inside jar as it's done, for example, with OpenJFX.

putnam commented 1 year ago

@developersu the dylib file is itself a dynamic library, but the libusb library (which it wraps) is built statically and then linked into the libusb4java library (and thus included in it). So you have a dynamic library that has linked in a static library, and otherwise dynamically links to all the other stuff it needs.

You can confirm that libusb is baked into the libusb4java dylib file by running nm and see all the symbols for libusb in there.

Since it's already built-in to the usb4java library there's no need to worry about where libusb files live on disk at all.

developersu commented 1 year ago

@putnam dylib compiled for apple silicone is not built in to the usb4java library (used, and available in maven central, including latest versions) and that's why it doesn't work and people installs libusb via brew.

If you know how to make it work please do and let me know. In result it should be fat jar, not multiple files.

I think that the best solution is to place pre-compiled libusb (libusb4java.dylib or whatever else) inside jar. If you think that it should be static lib, I'm fine with it. Shared goes too. Now I don't see the way of how it's could be done, but my assumption is that I'm placing my pre-compiled dylib into the wrong place. Another approach to solve this is not to use usb4java from maven central and build it by ourselves.

Also I highly appreciate your advices and support and I'm happy that you [personally and all the] people are trying to help solving this. Just in some situation I don't understand what I suppose to do.. like with that zip dylib pack 🙃

juzser commented 1 year ago

Hi, Do you guys know why I connect my NS to my Mac Apple Silicone via type C - C, for a moment, the awoo and ns-usbloader detect correctly, but 2 -3 seconds later, my M1 detects NS as power adapter and then NS shown as USB disconnected. NS-usbloader show the error unnamed module.

skoshy commented 7 months ago

I am receiving the same error @juzser , NS USB Loader 7.1 connects briefly and then disconnects 2-3 seconds later. Anyone know what could be happening?

cc @putnam , I saw you were facing the same issue, did you solve it?

EDIT: Only way I could get around it was using a USB-A -> USB-C cable

juzser commented 7 months ago

@skoshy I guess it's because of C hub on Mac, not because of this plugin itself. So I guess there is no solution for this. Maybe the C on Mac detects NS as power supply, not as device.