Đối với công việc hiện tại của tôi, tôi cần cung cấp một chai thực thi có thể nạp các lọ bên trong chính nó và thực hiện một chính thứ hai(). Về cơ bản là bootstrap main() và một application main().
Bước 1. trong "chính-class" manifest bạn đặt lớp bootstrap của bạn
Bước 2. Khi lớp bootstrap của bạn chạy nó unjar là jar riêng của mình và tất cả các lọ bên trong nó vào một thư mục tạm thời. Sử dụng một cái gì đó giống như dòng dưới đây để có được bình của riêng bạn.
Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()
Bước 3. lớp bootstrap của bạn phát hiện hệ điều hành thông qua "os.name" bất động sản và tải các lọ thích hợp từ thư mục tạm với điều này
private static void loadJarIntoClassloader(URL u) throws Exception
{
URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<URLClassLoader> sysclass = URLClassLoader.class;
Method method = sysclass.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(sysLoader, new Object[]{u});
}
Bước 4. Bây giờ bạn sẽ có thể để chạy ứng dụng của bạn bằng cách gọi chính ứng dụng().
LƯU Ý: Bản hack nhỏ này phụ thuộc vào JVM của bạn bằng cách sử dụng URLClassLoader
làm SystemClassLoader của nó, điều này đúng với Sun JVM, chứ không phải cho những người khác.
Bằng cách này bạn chỉ có thể cung cấp một cái bình và nó sẽ tự giải nén và chạy với các lọ chính xác.
Tại sao bạn không phân phối nhiều thực thi cho mỗi nền tảng (a la Eclipse)? –
Vì SWT chỉ mất một phần nhỏ của ứng dụng: Toàn bộ hiện tại là 30MB. Vì vậy, tôi có thể yêu cầu mọi người tải xuống 32MB cho mỗi nền tảng hoặc tải xuống một tệp 40MB (cho sáu nền tảng) duy nhất chạy ở mọi nơi. –
Trong trường hợp nhật thực, chúng tôi có hơn 10 lượt tải xuống, mỗi tệp> 100MB và sự khác biệt duy nhất giữa chúng là bình SWT. Tôi muốn tải xuống một lần hoặc một bản tải xuống chính lớn và một tải xuống nhỏ trên mỗi nền tảng được tải xuống tự động khi tôi chạy ứng dụng lần đầu tiên. –