How java finds native libraries? [duplicate] - java

I would like to know when do we need to place a file under
C:\Windows\System32 or C:\Windows\SysWOW64, on a 64-bits windows system.
I had two DLL's, one for 32-bit, one for 64-bit.
Logically, I thought I'd place the 32-bit DLL under C:\Windows\System32, and the 64-bit DLL under C:\Windows\SysWOW64.
To my surprise, it's the other way around! The 32-bit one goes into C:\Windows\SysWOW64, and the 64-bit DLL goes into C:\Windows\System32.
Very confusing stuff. What's the reason behind this?

I believe the intent was to rename System32, but so many applications hard-coded for that path, that it wasn't feasible to remove it.
SysWoW64 wasn't intended for the dlls of 64-bit systems, it's actually something like "Windows on Windows64", meaning the bits you need to run 32bit apps on a 64bit windows.
This article explains a bit:
Windows x64 has a directory System32 that contains 64-bit DLLs (sic!).
Thus native processes with a bitness of 64 find “their” DLLs where
they expect them: in the System32 folder. A second directory,
SysWOW64, contains the 32-bit DLLs. The file system redirector does
the magic of hiding the real System32 directory for 32-bit processes
and showing SysWOW64 under the name of System32.
If you're talking about an installer, you really should not hard-code the path to the system folder. Instead, let Windows take care of it for you based on whether or not your installer is running on the emulation layer.

I should add: You should not be putting your dll's into \system32\ anyway! Modify your code, modify your installer... find a home for your bits that is NOT anywhere under c:\windows\
For example, your installer puts your dlls into:
\program files\<your app dir>\
or
\program files\common files\<your app name>\
(Note: The way you actually do this is to use the environment var: %ProgramFiles% or
%ProgramFiles(x86)% to find where Program Files is.... you do not assume it is c:\program files\ ....)
and then sets a registry tag :
HKLM\software\<your app name>
-- dllLocation
The code that uses your dlls reads the registry, then dynamically links to the dlls in that location.
The above is the smart way to go.
You do not ever install your dlls, or third party dlls into \system32\ or \syswow64. If you have to statically load, you put your dlls in your exe dir (where they will be found). If you cannot predict the exe dir (e.g. some other exe is going to call your dll), you may have to put your dll dir into the search path (avoid this if at all poss!)
system32 and syswow64 are for Windows provided files... not for anyone elses files. The only reason folks got into the bad habit of putting stuff there is because it is always in the search path, and many apps/modules use static linking. (So, if you really get down to it, the real sin is static linking -- this is a sin in native code and managed code -- always always always dynamically link!)

Ran into the same issue and researched this for a few minutes.
I was taught to use Windows 3.1 and DOS, remember those days? Shortly after I worked with Macintosh computers strictly for some time, then began to sway back to Windows after buying a x64-bit machine.
There are actual reasons behind these changes (some would say historical significance), that are necessary for programmers to continue their work.
Most of the changes are mentioned above:
Program Files vs Program Files (x86)
In the beginning the 16/86bit files were written on, '86' Intel processors.
System32 really means System64 (on 64-bit Windows)
When developers first started working with Windows7, there were several compatibility issues where other applications where stored.
SysWOW64 really means SysWOW32
Essentially, in plain english, it means 'Windows on Windows within a 64-bit machine'. Each folder is indicating where the DLLs are located for applications it they wish to use them.
Here are two links with all the basic info you need:
MSDN File System Redirector
SysWow64 Explained
Hope this clears things up!

System32 is where Windows historically placed all 32bit DLLs, and System was for the 16bit DLLs. When microsoft created the 64 bit OS, everyone I know of expected the files to reside under System64, but Microsoft decided it made more sense to put 64bit files under System32. The only reasoning I have been able to find, is that they wanted everything that was 32bit to work in a 64bit Windows w/o having to change anything in the programs -- just recompile, and it's done. The way they solved this, so that 32bit applications could still run, was to create a 32bit windows subsystem called Windows32 On Windows64. As such, the acronym SysWOW64 was created for the System directory of the 32bit subsystem. The Sys is short for System, and WOW64 is short for Windows32OnWindows64.
Since windows 16 is already segregated from Windows 32, there was no need for a Windows 16 On Windows 64 equivalence. Within the 32bit subsystem, when a program goes to use files from the system32 directory, they actually get the files from the SysWOW64 directory. But the process is flawed.
It's a horrible design. And in my experience, I had to do a lot more changes for writing 64bit applications, that simply changing the System32 directory to read System64 would have been a very small change, and one that pre-compiler directives are intended to handle.

Other folks have already done a good job of explaining this ridiculus conundrum ... and I think Chris Hoffman did an even better job here: https://www.howtogeek.com/326509/whats-the-difference-between-the-system32-and-syswow64-folders-in-windows/
My two thoughts:
We all make stupid short-sighted mistakes in life. When Microsoft named their (at the time) Win32 DLL directory "System32", it made sense at the time ... they just didn't take into consideration what would happen if/when a 64-bit (or 128-bit) version of their OS got developed later - and the massive backward compatibility issue such a directory name would cause. Hindsight is always 20-20, so I can't really blame them (too much) for such a mistake. ...HOWEVER... When Microsoft did later develop their 64-bit operating system, even with the benefit of hindsight, why oh why would they make not only the exact same short-sighted mistake AGAIN but make it even worse by PURPOSEFULLY giving it such a misleading name?!? Shame on them!!! Why not AT LEAST actually name the directory "SysWin32OnWin64" to avoid confusion?!? And what happens when they eventually produce a 128-bit OS ... then where are they going to put their 32-bit, 64-bit, and 128-bit DLLs?!?
All of this logic still seems completely flawed to me. On 32-bit versions of Windows, System32 contains 32-bit DLLs; on 64-bit versions of Windows, System32 contains 64-bit DLLs ... so that developers wouldn't have to make code changes, correct? The problem with this logic is that those developers are either now making 64-bit apps needing 64-bit DLLs or they're making 32-bit apps needing 32-bit DLLs ... either way, aren't they still screwed? I mean, if they're still making a 32-bit app, for it to now run on a 64-bit Windows, they'll now need to make a code change to find/reference the same ol' 32-bit DLL they used before (now located in SysWOW64). Or, if they're working on a 64-bit app, they're going to need to re-write their old app for the new OS anyway ... so a recompile/rebuild was going to be needed anyway!!!
Microsoft just hurts me sometimes.

Related

Recompile jpicusb.dll into a 64bit .dll

Background: I need to communicate my computer (Win7 64bit) to a PIC18F4550 using the USB port. I found the jpicusb library for Java, but it is compiled to work in 32bit OS. When I attemp to use it on my computer it does not recognize the jpicusb.dll file (which is needed). Some other posts on the internet say that happens because the .dll is built for 32bits OS.
Question: The files in the link contain the sources of the .class, .dll (I think?) and examples of how to use the .class. How can I compile the .dll source into a 64bit version .dll?
I would prefer not to use a VM to run a 32bit OS.
If you know how to communicate PIC to a PC in C or Java please tell me how to.
I've tried adding -m64 -march=x86-64 to the gcc command with no results
Some say the code makes it compile for 32bit but I don't know how that is possible.
I know libusb also does the work but I haven't tried it out (I wanted to completely discard jpicusb)

Exporting as stand alone application

I exported Processing application as a standalone application with embedded Java, but the exe does not work in computers where Java/Processing is not installed. Even if the Windows 64 bits works with Java embedded, the 32 bits does not work with Java embedded or not. The computers that do not have Java already installed open the Windows 64 bits exe but not the Windows 32 exe (with java embedded in its exporting process). Here's the post in Processing forum: https://forum.processing.org/two/discussion/25373/no-export#latest
Can it be resolved? Thanks.
You can only include the Java version for the type of machine you're running on.
If you're on a 64-bit Windows machine, then you can only include Java in the 64-bit Windows application. If you're on a 32-bit Linux machine, then you can only include Java in the 32-bit Linux application.
If you really want to include Java for a bunch of different machines, then your best bet is to find each type of machine and do the export from them. Find a 32-bit Windows machine and do the export there, then find a 64-bit Linux machine and do the export there, etc.
You might be able to hack something together by downloading the JRE for each type of machine and manually including it, but that might get pretty tricky. Note that this is not as simple as just copying a folder into your application directory. You're going to have to change the run script file as well.
Shameless self-promotion: I've written a tutorial on exporting applications from Processing available here.

Eclipse fails to start, gives - Failed to load the JNI shared Library

I faced this issue many a times while working with a new setup or after a Java upgrade. Logical solution for this? Except replacing jvm.dll file?
Never realized, but the solution is quite easy. As per my understanding:
Observations:
If you are using a 64bit Windows system, then you would notice that there are two Program Files folder in your C:/ Drive.
That means, Program Files, which contains 64-bit programs and applications, and. Program Files (x86), which contains 32-bit programs and applications.
Now if you are using a 64bit system, then it is easy and recommended that you use softwares as well of 64bit. So your Path in System variables should contain the path details of your Java 64bit.
Now coming back to the original problem, here if we are on 64Bit Microsoft Windows system and wish to use 64bit Software (Eclipse for example), then let us set the Path for the 64bit Java.
Then make a simple test on command prompt.
-cmd
-java -version
Shows the 64bit Java VM is set to path.
Now Open your Eclipse and it do not show the Error.
Always remember that we should use:
64 bit OS
64 bit Java (with Path set for 64 bit Java)
64 bit Eclipse.

Make jar run in 32bit jre

How can I specify that in order to run a certain java application that I created you need to have 32 bit JRE installed on your system? Further how can I specify that the java application is to use the 32 bit JRE and not the 64 bit JRE if they are both installed?
Background:
I have created an application that uses a 3rd party 32 bit only library. The application can not run in a 64 bit JRE.
I am going to be distributing this application to a lot of computers in my company, so I need to be able to in code or in the export process, specify the required JRE.
I am using eclipse, Kepler to develop and build the java application.
The idea of java is always compile once and run everywhere, regardless of OS, cpu architecture etc, so you might be heading the wrong direction here.
But nevertheless here are some system properties you might / not find helpful. I've listed the property key and value I have when I check it (I run Oracle JDK on Win7 64)
java.vm.name: Java HotSpot(TM) 64-Bit Server VM
sun.arch.data.model: 64
sun.cpu.isalist: amd64
To use any of those just do
String vmname = System.getProperty("java.vm.name");
You can't do it directly in Java, since you're in a running JVM at that point. My solution was to write a dos batch script to set the JAVA_HOME and add %JAVA_HOME%\bin at the front of the PATH. For example, I have sethome.bat which contains
#echo off
set "JAVA_HOME=c:\Program Files (x86)\Java\jre6"
set "PATH=%JAVA_HOME%\bin;%PATH%"
Then I use
call "%SERVICE_HOME%\sethome"
"%JAVA_HOME%\bin\java" -version
echo If this does not look correct press CTRL-C to cancel otherwise
pause
You cannot generally make sure what program runs your jar. I can pass the jar to acroread, or zip or whatever, and you can't do anything about it.
So, I'd just try to load the library, and do a proper error/exception handling. Who knows? Maybe your client has meanwhile replaced that library with a 64bit version, without you knowing about it? SO, this: loading, and if it won't aborting with a graceful eror message is the only sensible thing.

Is there an easy way to build a 64-bit JD2XX DLL?

For accessing FTDI USB boards from Java applications, I'm using the JD2XX driver wrapper (JD2XX.dll). It works very fine on 32-bit systems, but when it is loaded from a 64-bit JVM, it says it is impossible for a 64-bit JVM to load a 32-bit DLL. Very understandable. To get past this little problem, I install a 32-bit JVM on the 64-bit systems and it runs fine. Very simple solution, which can become very complicated to explain to a customer, though!
For this reason, I would like to create or otherwise obtain a 64-bit version of this JD2XX.dll file. I would like to know if someone ever did this successfully, or how I could proceed. I thought there should be a reference to the 32-bit dll in the ftdi-win32 project I could change for a 64-bit dll reference before recompiling everything on a 64-bit system, but I didn't find.
I would greatly appreciate any help about this. I don't feel like I'd find a way around this problem on my own anytime soon. The files I describe can be found in the most recent of these packages.
Thank you very much,
MJ
I finally managed to generate that 64-bit DLL file. ... :)
Here is how I obtained it:
Downloaded the JD2XX package (the most recent is actually dated 20071214).
Downloaded mingw-w64 (personal build sezero) and decompressed it in C:\ (giving C:\mingw64).
Brought some modifications to the JD2XX package.
Adjusted Makefile.conf
Corrected MINGW and JDK paths according to my system.
Selected ftdi-win32 and amd64
Renamed the already generated 32-bit JD2XX.dll file so that make stops telling there is nothing to be done.
Renamed ftdi-win32/libftd2xx.a which is 32-bit... Replaced it by a copy of ftdi-win32/amd64/ftd2xx64.lib (renamed as libftd2xx.a, of course).
Called C:\mingw64\bin\mingw32-make.exe from the main directory of the JD2XX package. This created a new JD2XX.DLL file which allows me to communicate with FTDI devices on my 64-bit computer without having to use a 32-bit JVM.
The generated file for download if anyone needs it.
The "generated file for download" didn't work for me, so I followed the instructions and made it myself, which works:
http://dev.geogebra.org/download/lib/ftdi/JD2XX_64_2.08.17.dll
It also looks like you should be able to build a 64-bit dll on a 32-bit system (or even on linux) by downloading the correct version of mingw-w64:
https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/
Also, some of the links are out of date. These are current:
d2xx.svn.sourceforge.net/viewvc/d2xx/trunk/
www.ftdichip.com/Drivers/D2XX.htm

Categories