2009-04-30 9 views
47

Во время установки с помощью установщика NSIS мне нужно проверить, какая JRE (32 бит против 64 бит) установлена ​​в системе. Я уже знаю, что могу проверить системное свойство «sun.arch.data.model», но это зависит от Sun. Мне интересно, есть ли для этого стандартное решение.Как определить, какой тип JRE установлен - 32 бит против 64 бит

ответ

0

В Linux, my (java) vm сообщает java.vm.name = Java HotSpot (TM) 64-разрядная серверная VM. Javadocs for System заявляют, что System.getProperty всегда будет иметь значение для этого, но молчат на sun.arch.data.model.

К сожалению, они не указывают, что системное свойство будет таким, чтобы некоторые другие JVM могли просто сообщить java.vm.name = Edgar.

Кстати, «установлен в системе», я предполагаю, что вы имеете в виду «текущая работа JVM»?

45

Архитектура JVM в использовании можно получить с помощью свойства «os.arch»:

System.getProperty("os.arch"); 

«ОС» часть, кажется, немного некорректным, или, возможно, оригинальные дизайнеры не ожидали JVMs в работать на архитектурах, для которых они не были написаны. Возвращаемые значения выглядят как inconsistent.

Команда установщика NetBeans: tackling the issue архитектуры JVM и ОС. Цитата:

64 бит: Java и System

Гусеничный как Issue 143434.

В настоящее время мы с помощью x64 бит JVM, чтобы определить, является ли систему (и, таким образом, Platform.getHardwareArch()) является 64-битный или нет. Это определенно неправильно, так как можно запустить 32-битную JVM на 64-битной системе. Мы должны найти решение для проверки подлинности 64-битной ОС в случае работы на 32-разрядной JVM.

  • для Windows, это может быть сделано с помощью WindowsRegistry.IsWow64Process()
  • для Linux - путем проверки 'uname -m/р' == x86_64
  • для Solaris это может быть сделано с помощью, например, «ISAInfo -b»
  • для Mac OSX это не может быть сделано с помощью uname аргументы, вероятно, это может быть решена путем создания 64-разрядного двоичного кода и выполнения на платформе ... (к сожалению, это не работа :( Я создал двоичный только с x86_64 и ppc64 арки и это было успешно выполнено на Tiger ..)
  • для поддержки Generic Unix - это не ясно, как хорошо ... скорее проверка для того же 'uname -m/-p'/'getconf LONG_BIT' и сравнивая его с некоторыми возможными 64-битными значениями (x86_64, x64, amd64, ia64).

Примеры свойств разных виртуальных машинах все работает на 64-битной Ubuntu 8.0.4:

32bit IBM 1,5:

java.vendor=IBM Corporation 
java.vendor.url=http://www.ibm.com/ 
java.version=1.5.0 
java.vm.info=J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20061001 (JIT enabled) 
J9VM - 20060915_08260_lHdSMR 
JIT - 20060908_1811_r8 
GC - 20060906_AA 
java.vm.name=IBM J9 VM 
java.vm.specification.name=Java Virtual Machine Specification 
java.vm.specification.vendor=Sun Microsystems Inc. 
java.vm.specification.version=1.0 
java.vm.vendor=IBM Corporation 
java.vm.version=2.3 
os.arch=x86 
os.name=Linux 
os.version=2.6.24-23-generic 
sun.arch.data.model=32 

64bit ВС 1,6:

java.vendor=Sun Microsystems Inc. 
java.vendor.url=http://java.sun.com/ 
java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport.cgi 
java.version=1.6.0_05 
java.vm.info=mixed mode 
java.vm.name=Java HotSpot(TM) 64-Bit Server VM 
java.vm.specification.name=Java Virtual Machine Specification 
java.vm.specification.vendor=Sun Microsystems Inc. 
java.vm.specification.version=1.0 
java.vm.vendor=Sun Microsystems Inc. 
java.vm.version=10.0-b19 
os.arch=amd64 
os.name=Linux 
os.version=2.6.24-23-generic 
sun.arch.data.model=64 

64bit GNU 1,5:

java.vendor=Free Software Foundation, Inc. 
java.vendor.url=http://gcc.gnu.org/java/ 
java.version=1.5.0 
java.vm.info=GNU libgcj 4.2.4 (Ubuntu 4.2.4-1ubuntu3) 
java.vm.name=GNU libgcj 
java.vm.specification.name=Java(tm) Virtual Machine Specification 
java.vm.specification.vendor=Sun Microsystems Inc. 
java.vm.specification.version=1.0 
java.vm.vendor=Free Software Foundation, Inc. 
java.vm.version=4.2.4 (Ubuntu 4.2.4-1ubuntu3) 
os.arch=x86_64 
os.name=Linux 
os.version=2.6.24-23-generic 

(версия GNU не сообщает о «солнце. arch.data.model ", предположительно другие JVM тоже не являются.)

0

В системе могут быть как 32-битные, так и 64-битные JVM, и множество из них.

Если у вас уже есть dll для каждой поддерживаемой платформы, рассмотрите возможность создания небольшого исполняемого файла, который соединяется и запускается, чтобы вы могли проверить, поддерживает ли платформа данную функцию. Если исполняемые ссылки и запуск, вы можете установить соответствующие общие библиотеки.

-5

Следующий код проверяет поле в любых Тип машины окон исполняемым, чтобы определить, является ли 32 или 64 бит:

public class ExeDetect 
{ 
    public static void main(String[] args) throws Exception { 
    File x64 = new File("C:/Program Files/Java/jre1.6.0_04/bin/java.exe"); 
    File x86 = new File("C:/Program Files (x86)/Java/jre1.6.0/bin/java.exe"); 
    System.out.println(is64Bit(x64)); 
    System.out.println(is64Bit(x86)); 
    } 

    public static boolean is64Bit(File exe) throws IOException { 
    InputStream is = new FileInputStream(exe); 
    int magic = is.read() | is.read() << 8; 
    if(magic != 0x5A4D) 
     throw new IOException("Invalid Exe"); 
    for(int i = 0; i < 58; i++) is.read(); // skip until pe offset 
    int address = is.read() | is.read() << 8 | 
     is.read() << 16 | is.read() << 24; 
    for(int i = 0; i < address - 60; i++) is.read(); // skip until pe header+4 
    int machineType = is.read() | is.read() << 8; 
    return machineType == 0x8664; 
    } 
} 

Обратите внимание, что код был уплотнен для краткости ...

+1

обратите внимание, что код нарушает как только пользователь Безразлично Не используйте ту же самую версию jre ... –

+2

-1 Ужасный метод. Нет перекрестной платформы. Жесткая версия. – Tomas

+1

Это общий метод обнаружения 64-битного исполняемого файла в окнах. Ничего особенного для версии jre. –

2
import sun.misc.*; 

import java.lang.reflect.*; 

public class UnsafeTest { 
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { 
    Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); 
    unsafeField.setAccessible(true); 
    Unsafe unsafe = (Unsafe) unsafeField.get(null); 
    System.out.println(unsafe.addressSize()); 
    } 
} 
6

Я использую NSIS и Launch4j для переноса приложения Java Desktop. Поэтому мне нужно не только обнаружить любую JRE, но и Launch4j найдет ее алгоритм поиска. Единственный подход, который имел смысл - запустить небольшую программу Java в установщике NSIS. Вот Java:

 

    public class DetectJVM { 
     private static final String keys [] = { 
      "sun.arch.data.model", 
      "com.ibm.vm.bitmode", 
      "os.arch", 
     }; 
     public static void main (String [] args) { 
      boolean print = args.length > 0 && "-print".equals(args[0]); 
      for (String key : keys) { 
       String property = System.getProperty(key); 
       if (print) System.out.println(key + "=" + property); 
       if (property != null) { 
        int errCode = (property.indexOf("64") >= 0) ? 64 : 32; 
        if (print) System.out.println("err code=" + errCode); 
        System.exit(errCode); 
       } 
      } 
     } 
    } 

Оберните это Launch4J. Используйте тип заголовка GUI, но также установите значение true. В противном случае код ошибки будет потерян. (Я положил все это в моем Netbeans Ant построить сценарий

Вот соответствующий код NSIS, который использует это:.

 

File ... ; unpack files including detectjvm.exe. 
ClearErrors 
ExecWait '"$INSTDIR\detectjvm.exe"' $0 
IfErrors DetectExecError 
IntCmp $0 0 DetectError DetectError DoneDetect 
DetectExecError: 
    StrCpy $0 "exec error" 
DetectError: 
    MessageBox MB_OK "Could not determine JVM architecture ($0). Assuming 32-bit." 
    Goto NotX64 
DoneDetect: 
IntCmp $0 64 X64 NotX64 NotX64 
X64: 
    File ... 64-bit AMD DLLs. 
    Goto DoneX64 
NotX64: 
    File ... 32-bit x86 DLLs. 
DoneX64: 
Delete $INSTDIR\detectjvm.exe 

Это работало отлично на очень большой выбор машин от WinXP, без SP через Vista, и Win7 со всеми SP, 32- и 64-разрядными.

Обратите внимание, что в моем сценарии NSIS я использую существующий пакет, который проверяет, установлена ​​ли JVM и делает это сначала, поэтому 32-разрядная версия по умолчанию выбор произошел бы только в том случае, если что-то пошло не так с установкой JVM, и в этом случае набор копий DLL, которые вы копируете, не имеет значения.

Надеюсь, это полезно кому-то.

+0

Это очень полезное решение. Проблема, если, что, если 64-битная машина пользователя не установлена ​​с JVM? Затем скрипт сделает неправильное предположение. –

+0

Обратите внимание, что для моего случая мне нужно сделать его в Console с помощью Launch4J. –

3

При написании кода Java, как я могу различать 32- и 64-разрядную операцию?

http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#64bit_detection

Там нет общественного API, который позволяет различать между 32 и 64-разрядном режиме. Подумайте о 64-битной, как о другой платформе в , пишите один раз, идите в любую традицию. Однако, если вы хотите написать код , который является специфичным для платформы (стыдно за вас), системное свойство sun.arch.data.model имеет значение «32», «64» или «неизвестно».

+0

Как сказал Thorbjørn Ravn Andersen в другом сообщении, 32-разрядные JVM отлично работают на 64-битных ОС. Используйте свойство sun.arch.data.model, если вы беспокоитесь о ширине бита JVM, а не о битовой ширине операционной системы (при условии, что вы работаете в JVM Hot Spot ...) – billsimons

+0

Проблема с битом не в том, что самого кода java, но из-за оболочки, которую мы отправляем с нашим программным обеспечением. Предполагая следующее: если клиент пытается установить нашу версию 64Bit SW, но у него только 32Bit Java; он должен быть проинформирован ... – user97629

-1

Если у вас есть путь к .exe, который вы хотите проверить, вы можете использовать this answer. В основном он просто смотрит на заголовки в файле .exe и сообщает вам, является ли это 64 или 32 бит в Windows.

+0

Ответ Питера Смита та же самая логика, но сделана правильно – Massimo

-1
java -version 

Для 64-разрядной версии Java он будет печатать:

java version "1.8.0_92" 
Java(TM) SE Runtime Environment (build 1.8.0_92-b14) 
Java HotSpot(TM) ***64-Bit*** Server VM (build 25.92-b14, mixed mode) 

Для 32 бит это будет просто

java version "1.8.0_92" 
Java(TM) SE Runtime Environment (build 1.8.0_92-b14) 
Java HotSpot(TM) Client VM (build 25.92-b14, mixed mode) 
+0

Вы можете попробовать в командной строке: java -d64 -version Если это не 64-разрядная версия, вы получите сообщение, которое выглядит так: Этот экземпляр Java не поддерживает 64-битную JVM. Установите нужную версию. Обратитесь к вариантам помощи JVM за дополнительной информацией java -help – Massimo