Install4j: installer:sys.installationDir inconsistent - java

The install4j variable sys.installationDir on MacOS (not the folder) returns just /Applications.
This makes sense since technically the directory the application was installed in was "/Applications" but I've used this variable inside my VM options to point to certain dependencies. This is causing me to have runtime errors. Is there another variable I should be using for this?
I've looked and I don't see any other options except to verify the platform and include the rest of the path.

You should use the installer variable ${installer:sys.contentDir} for that purpose, it always points at the directory where the distribution tree is installed.

Related

How to access sys.preferredJre from a script in install4j?

My application uses authentication through a LDAP server over SSL. This requires installation of certificates in the bundled JRE's keystore. I use a script to do it through Java code and in the process need to find the location of the installed JRE. This script is executed at the end of the installation.
On Windows, it's relatively simple: I just use context.getInstallationDirectory() and then add jre\lib\security\cacerts.
On Mac OS, however, the JRE is installed in a different location and I would need to use the actual sys.preferredJre or the java.home property. The problem is that I can't access them from the scripts. The context object doesn't seem to have the corresponding methods. System.getProperty("java.home") returns a temporary location where the JRE is probably first unpacked and not the final path.
context.getCompilerVariable("sys.preferredJre") returns null.
As a side note, there doesn't seem to be any logging from inside the scripts. All I get is a brief message about the script succeeding or failing. I had to write to a custom file to get any information.
Can you suggest a way to handle this? Ideally, I would like to do it in OS-independent way and just get the Jre directory.
Thanks in advance
Sasha
After the "Install files" action has run, the sys.preferredJre installer variable is set to the directory where the bundled JRE has been installed. You can get this variable by calling
context.getVariable("sys.preferredJre")
In your question, you use getCompilerVariable, which is not correct because it returns values of compiler variables.

Java Textio file addition [duplicate]

This question already exists:
how to add new class(textio.java) in jdk 12.0.1
Closed 3 years ago.
Where to put the textio.java and its classes. I am using jdk 12.0.1. it is the error cmd is showing on comipiling file that uses textio class.
Please tell me the correct directory where to put textio class file in jdk 12.0.1 folder.
There are numerous ways to add third party libraries to your runtime. Without more information, the lowest energy way you're looking for isn't quite clear.
I believe the CLASSPATH environment variable is what you want. If it's not defined, you may define one by whatever process matches your operating system.
CLASSPATH is one way for your machine to tell your java installation which folders jars and other jvm bytecode are located in so that your java runtime can load them when your program starts. This can be anywhere, but depending on your operating system, there are standard locations that are often good to follow.
In linux/unix/OSX, you may run echo $CLASSPATH, and a non-empty result means that it's set. If it doesn't exist, then you may run this command to create it pointing to the folder you choose. export CLASSPATH=/path/to/jars. Just keep in mind that without some extra steps, this will be reset on next reboot.
If you're using an IDE such as eclipse or idea, then there are project-specific solutions that can be done as configuration options within your IDE, which will keep things you don't want globally available on your machine from being loaded up every time.

Is the CLASSPATH abstracted away in IntelliJ IDEA?

Here are some questions about setting the CLASSPATH in IntelliJ:
Adding Jar files to IntellijIdea classpath
how to add directory to classpath in an application run profile in intellij idea?
Java - setting classpath
Most of the answers involve changing settings in the Project Settings -> Modules -> Sources or -> Dependencies pages. But the word "CLASSPATH" isn't actually on those pages.
For example, the -> Dependencies page lets one explicitly set a place to find other .class files or .jar files. But no "CLASSPATH" anywhere.
Also, setting a location in the -> Sources page seems to indicate what the directory tree for
the .class root should look like, but the actual location is actually set in the Project Settings -> Project -> Project Compiler Output field, again without the word "CLASSPATH".
Is JetBrains trying to hide this word for some reason (eg. it's meant to be a multi-language IDE)? Is there some place to explicitly set the CLASSPATH other than an env variable?
As you say, the CLASSPATH is an environment variable, so it would affect all applications referencing that variable:
The class search path (more commonly known by the shorter name, "class
path") can be set using either the -classpath option when calling a
JDK tool (the preferred method) or by setting the CLASSPATH
environment variable. The -classpath option is preferred because you
can set it individually for each application without affecting other
applications and without other applications modifying its value.
Source: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html
You can also use the -classpath option when running your application, which would not affect other Java applications running on your system.
IntelliJ will construct your classpath to include both your application and any dependencies (whether folders or Jars etc.) and passes that to the JVM when you run your application. The IntelliJ GUI does refer to your explicit "Dependencies" and let you edit them. Your application build path would need to contain those dependencies and all of your application code, so it makes sense to include that implicitly.
If you were to use a lot of libraries, your classpath could become very long - having to maintain the list of locations in the class search path manually would be time consuming and (human) error prone - a typo on a folder name and it won't compile / run - so it assumes the task for you.
You'll probably find your IDE passes a number of other arguments to the JVM on your behalf (heap size, GC, JMX extensions and so on) - but that's part of what your IDE is for. Sure, we could invoke things like version control ourselves from the command-line, but why forgo the help? Your IDE isn't trying to "hide" anything from you, it's (hopefully) providing a more intuitive interface for many common development tasks.
CLASSPATH happens to be the name of the environment variable used automatically by Java.
It's generally considered a better option to use the -cp argument to explicitly set the classpath rather than fighting with CLASSPATH conflicts since it's process-wide.
It's not trying to "hide" it at all; there's just no reason to use it.

Program uses outdated (not current) env variable value

I've got a C++ program that internally uses java (via my C++ dll that wrapps the WebLogic jsmc.dll that internally uses jvm.dll).
When I set CLASSPATH before running my program, all JAR libraries are found and the program works properly.
When I do not set the CLASSPATH before running my program, the JARs are not found, which of course is expected.
Now, when I set the CLASSPATH before running my program, but clear this CLASSPATH environment variable inside the program code before loading my dll that uses java, a strange thing happens: all JARs are still found and the program works as if everything was OK. I have verified by several ways that the CLASSPATH is really deleted from the env variables (e.g. by using ProcessExplorer or by printing its value).
QUESTION:
Can you explain this behaviour to me? I'm not wondering why java ignores the CLASSPATH I set, but how is it possible that java sees the old CLASSPATH value, not the current one? I emphasize that it isn't possible for java to store the old CLASSPATH value somehow because java was not loaded at the the time the old value was available.
How can I make the java to respect the changes in the process env variables?
DETAILS:
The problem above is just a simplification I've made to explore my real problem. I'm trying to set the CLASSPATH from within the program and avoid to have it set externally. But the java uses the externally set CLASSPATH, not the one I set inside the program.
I read and set the env variables values using the Windows API (GetEnvironmentVariableA, SetEnvironmentVariableA). I have verified that the program process environment variables really change after setting them this way. I even printed the CLASSPATH value from the dll that uses java, before calling any java method. I checked using the ProcessMonitor that jvm.dll is really loaded after the CLASSPATH is deleted. I also tried to exclude the possibility that the CLASSPATH is read from the parent process. Now I'm pretty sure that at the time jvm.dll is being loaded, the CLASSPATH is already deleted from the process environment.
I have tried both a Visual C++ 2010 testing program and the HP LoadRunner C-compiler (mmdrv.exe) vuser script, with the same result. LoadRunner is the main reason why I need to solve this problem.
The problem was caused by that the C-runtime somehow caches the environment variables. While I was trying to modify the CLASSPATH using the system function SetEnvironmentVariableA(), jmsc.dll read CLASSPATH from the C-runtime cache. The C-runtime tries to synchronize its cache with the real values in the process environment, but evidently not very successfully. It was necessary for me to replace the system call to SetEnvironmentVariableA() with the call to _putenv() from the C-runtime in order to change the CLASSPATH.
But there was another problem. There were various versions of C-runtime used by my code, each having its own environment cache. My VC code was linked against msvcr100.dll, while jmsc.dll (that instantiates the Java VM) uses msvcrt.dll. The solution was to link my code to msvcrt.dll too, so that my code sets CLASSPATH using _putenv() from the same C-runtime that jmsc.dll reads.
Thanks to Harry Johnston for the crucial hint, and Peter Cetinski for valuable information.
You should not rely upon the CLASSPATH environment variable when invoking a new JVM process from C++. The JNI interface provides a mechanism to specify the classpath of the JVM upon startup.
See http://java.sun.com/docs/books/jni/html/invoke.html#28719

How should I bundle Java with my Windows application?

I have a Windows application based on Java, that I should like to install with Java bundled. The installation framework is NSIS. The application executable should be guaranteed to invoke the bundled Java, so there's no clash with other Javas installed in the system.
What's the best way to achieve my goal? I haven't tried to solve this kind of problem before, and have little experience with Java, so I don't know which solutions are out there. I think I'd prefer Java to be embedded in the application's executable, if feasible, otherwise I guess Java could be installed along with it (with the executable pointing to said Java).
Edit:
This project already generates an executable (.exe), via NSIS. The executable will by default use the system Java, but apparently it'll prefer a JRE in the same directory (i.e. bundled) if present.
Edit 2:
The scenario that made me want to bundle Java with this application was that I received an executable for it built with 32-bit Java, which failed (silently) on my system which has 64-bit Java.
Are you absolutely sure you don't want to use the computer JRE? In most cases it's preferable.
You can see here (and the included link) some examples with installers that check JRE number and install it (globally) if necessary.
If you really prefer to include your own JRE in the installer and always use it - what prevents you from doing it? It's just a matter of your main program point having some way of konwing the JRE location and forcing to use it. That depends on how you pack/invoke your Java program. Normally, it would be feasible, perhaps with a simple .bat file - perhaps to be created at installation time.
The solution we used(A few years ago, but still I think the best way).
Find a program which can generate an exe file from a jar file(Google is your friend, I can't remember the name). Note that this .exe file will still need a jre. It is just a smart way to make an exe which contain your .jar file, and which start the java process automatic. (This also allows you to set a custom icon on your .exe file).
The java sdk which you use to develop/compile your java application, also contains a folder called jre, which contain a copy of the jre.
Include this folder with the installer, so the jre folder is located in the same folder as the .exe file. Then the .exe file will use the included jre, and the jre will not be installed on the computer, so you prevent any problems.
Well one extremely simple solution that works actually quite nice if you don't have to get an executable, is just using a simple Windows Batch file that starts the jar and having a shortcut to it so you get your preferred icon on it. For the average user there's no real difference - after all the default is to suppress known extensions on Windows (horrible default but well) - and for people who do know what an exe is, the solution should be quite apparent anyways.
That way you can also easily start the included java or better yet offer both versions and just change a variable in an ini file, which really is much nicer - nobody wants or needs X different JRE versions that are outdated and are nothing more than security problems. Still can't harm to offer a version that includes the JRE for people without a java install to make it as simple as possible for them.
One example for this behavior would be weka..
launch4j seems to offer to bundle an embedded JRE.

Categories

Resources