I'm trying to install the most current platform (x64 or x86) appropriate Java Runtime Environment via Inno Setup (along with another application). I've found some script examples for how to detect the version and install if correct and adapted them to my needs but I keep running into this:
Unable to open file "path\to\JREInstall.exe":
CreateProcess failed: Code 5:
Access Is Denied
This is the code strictly responsible for installing the JRE:
[Setup]
AppName="JRE Setup"
AppVersion=0.1
DefaultDirName="JRE Setup"
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Files]
Source: "jre-8u11-windows-x64.exe"; DestDir: "{tmp}\JREInstall.exe"; \
Check: IsWin64 AND InstallJava();
Source: "jre-8u11-windows-i586.exe"; DestDir: "{tmp}\JREInstall.exe"; \
Check: (NOT IsWin64) AND InstallJava();
[Run]
Filename: "{tmp}\JREInstall.exe"; Parameters: "/s"; \
Flags: nowait postinstall runhidden runascurrentuser; Check: InstallJava()
[Code]
procedure DecodeVersion(verstr: String; var verint: array of Integer);
var
i,p: Integer; s: string;
begin
{ initialize array }
verint := [0,0,0,0];
i := 0;
while ((Length(verstr) > 0) and (i < 4)) do
begin
p := pos ('.', verstr);
if p > 0 then
begin
if p = 1 then s:= '0' else s:= Copy (verstr, 1, p - 1);
verint[i] := StrToInt(s);
i := i + 1;
verstr := Copy (verstr, p+1, Length(verstr));
end
else
begin
verint[i] := StrToInt (verstr);
verstr := '';
end;
end;
end;
function CompareVersion (ver1, ver2: String) : Integer;
var
verint1, verint2: array of Integer;
i: integer;
begin
SetArrayLength (verint1, 4);
DecodeVersion (ver1, verint1);
SetArrayLength (verint2, 4);
DecodeVersion (ver2, verint2);
Result := 0; i := 0;
while ((Result = 0) and ( i < 4 )) do
begin
if verint1[i] > verint2[i] then
Result := 1
else
if verint1[i] < verint2[i] then
Result := -1
else
Result := 0;
i := i + 1;
end;
end;
function InstallJava() : Boolean;
var
ErrCode: Integer;
JVer: String;
InstallJ: Boolean;
begin
RegQueryStringValue(
HKLM, 'SOFTWARE\JavaSoft\Java Runtime Environment', 'CurrentVersion', JVer);
InstallJ := true;
if Length( JVer ) > 0 then
begin
if CompareVersion(JVer, '1.8') >= 0 then
begin
InstallJ := false;
end;
end;
Result := InstallJ;
end;
In the full setup script the same message continues to come up.
How can I get the JRE Setup to run from this scripted setup file?
I was able to figure out the issue:
Evidently I was mistaken in my use of these lines:
Source: "jre-8u11-windows-x64.exe"; DestDir: "{tmp}\JREInstall.exe"; Check: IsWin64 AND InstallJava();
Source: "jre-8u11-windows-i586.exe"; DestDir: "{tmp}\JREInstall.exe"; Check: (NOT IsWin64) AND InstallJava();
and they should have been in place like so:
Source: "jre-8u11-windows-x64.exe"; DestDir: "{tmp}"; DestName: "JREInstall.exe"; Check: IsWin64 AND InstallJava();
Source: "jre-8u11-windows-i586.exe"; DestDir: "{tmp}"; DestName: "JREInstall.exe"; Check: (NOT IsWin64) AND InstallJava();
That seems to have solved the problem.
Also this line I was mistaken in:
Filename: "{tmp}\JREInstall.exe"; Parameters: "/s"; Flags: nowait postinstall runhidden runascurrentuser; Check: InstallJava()
It should have been:
Filename: "{tmp}\JREInstall.exe"; Parameters: "/s"; Flags: nowait runhidden runascurrentuser; Check: InstallJava()
This is the best solution my limited experience with this particular tool is able to come up with. I will look into the PrepareToInstall option when I have a chance but this works for now.
According to the initial question, "How do I install a JRE from an Inno script?", and taking as a starting solution the best proposed one, I propose a solution that I think works more coherently.
I understand that the user wants to install a JRE for their application if the target computer does not have installed a Java runtime environment or its version is lower than the required one. Ok, what I propose is to use the AfterInstall parameter and reorder a bit the distribution files in a different way.
We will first sort the files in the [Files] section in another way, putting first the redist install files.
Source: "redist\jre-8u121-windows-i586.exe"; DestDir: "{tmp}"; DestName: "JREInstaller.exe";\
Flags: deleteafterinstall; AfterInstall: RunJavaInstaller(); \
Check: (NOT IsWin64) AND InstallJava();
Source: "redist\jre-8u121-windows-x64.exe"; DestDir: "{tmp}"; DestName: "JREInstaller.exe"; \
Flags: deleteafterinstall; AfterInstall: RunJavaInstaller(); \
Check: IsWin64 AND InstallJava();
Source: "Myprog.exe"; DestDir: "{app}"; Flags: ignoreversion
The next step we must do is to modify the section [Run] as follows.
[Run]
Filename: "{app}\{#MyAppExeName}"; \
Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
Flags: nowait postinstall skipifsilent
And last but not least, we implemented in the [Code] section the RunJavaInstaller() procedure as follows:
[Code]
procedure RunJavaInstaller();
var
StatusText: string;
ResultCode: Integer;
Path, Parameters: string;
begin
Path := '{tmp}\JREInstaller.exe';
{ http://docs.oracle.com/javase/8/docs/technotes/guides/install/config.html#table_config_file_options }
Parameters := '/s INSTALL_SILENT=Enable REBOOT=Disable SPONSORS=Disable REMOVEOUTOFDATEJRES=1';
StatusText:= WizardForm.StatusLabel.Caption;
WizardForm.StatusLabel.Caption:='Installing the java runtime environment. Wait a moment ...';
WizardForm.ProgressGauge.Style := npbstMarquee;
try
if not Exec(ExpandConstant(Path), Parameters, '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
begin
{ we inform the user we couldn't install the JRE }
MsgBox('Java runtime environment install failed with error ' + IntToStr(ResultCode) +
'. Try installing it manually and try again to install MyProg.', mbError, MB_OK);
end;
finally
WizardForm.StatusLabel.Caption := StatusText;
WizardForm.ProgressGauge.Style := npbstNormal;
end;
end;
You may need to replace the Enabled value with 1 and the Disabled value with 0 if the Java runtime installer is not working properly. I have not experienced any problem doing it this way. Anyways, in the code you have a comment with the Oracle link if you want to take a look.
Finally, since unfortunately we can not receive the installation progress status of the JRE in any way, we show a message and a progress bar so that the user does not have the feeling that the installer has hung.
To do this, we save the state before, execute Exec with the flag ewWaitUntilTerminated, to wait for that installation to finish before continuing with ours, and we restore the previous state once the function execution has finished.
Related
This question already has answers here:
Environment variable not recognized [not available] for [Run] programs in Inno Setup
(3 answers)
Closed 4 days ago.
I'm trying to make a setup for a little app written in Java. I need to create a Environment Variable (in this case YCS_JAVA) that points to a .dll from jdk-17. I've tried everything that I've found online and nothing works (error: Failed to find JAVA VM).
It's an exe made with WinRun4J with a JAR inside. The solution with CMD works but doesn't work as it should. I have another txt file which i read with the jar but the CMD doesn't find it xD The function SetEnvironmentVariable doesn't do anything. The function SetEnvPath creates the Variable but still doesn't work with error "Failed to find Java VM". But if i try to run it manually it works... (with just a double click)
;[Registry]
;Root: HKCU; Subkey: "Environment"; ValueType: string; ValueName: "YCS_JAVA"; ValueData: "C:\Program Files\Java\jdk-17\bin\server\jvm.dll"
;Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; ValueName: "YCS_JAVA"; ValueData: "C:\Program Files\Java\jdk-17\bin\server\jvm.dll"; AfterInstall: RefreshEnvironment;
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; BeforeInstall: SetEnvPath; Flags: postinstall;
[Code]
#ifdef UNICODE
#define AW "W"
#else
#define AW "A"
#endif
function SetEnvironmentVariable(lpName: string; lpValue: string): BOOL;
external 'SetEnvironmentVariable{#AW}#kernel32.dll stdcall';
procedure SetEnvPath;
begin
if not SetEnvironmentVariable('YCS_JAVA', 'C:\Program Files\Java\jdk-17\bin\server\jvm.dll') then
MsgBox(SysErrorMessage(DLLGetLastError), mbError, MB_OK);
end;
[Code]
const
SMTO_ABORTIFHUNG = 2;
WM_WININICHANGE = $001A;
WM_SETTINGCHANGE = WM_WININICHANGE;
type
WPARAM = UINT_PTR;
LPARAM = INT_PTR;
LRESULT = INT_PTR;
function SendTextMessageTimeout(hWnd: HWND; Msg: UINT;
wParam: WPARAM; lParam: PAnsiChar; fuFlags: UINT;
uTimeout: UINT; out lpdwResult: DWORD): LRESULT;
external 'SendMessageTimeoutA#user32.dll stdcall';
procedure RefreshEnvironment;
var
S: AnsiString;
MsgResult: DWORD;
begin
S := 'Environment';
SendTextMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
PAnsiChar(S), SMTO_ABORTIFHUNG, 5000, MsgResult);
end;
This is because (I think) the setup execution frame isn't aware of the new Environment Variable. I've tried with [Registry] and with [Code] but I can't make it work. The SetEnvPath function doesn't even create the ENV Variable, idk why. Please help :'(
FINALLY a fix that works:
Filename: "{cmd}"; Parameters: "/C setx YCS_JAVA ""C:\Program Files\Java\jdk-17\bin\server\jvm.dll"" && set YCS_JAVA=C:\Program Files\Java\jdk-17\bin\server\jvm.dll && START """" ""{app}\{#MyAppExeName}"" & EXIT 1"; \
Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: postinstall runhidden
I've used setx to save the Env Variable and set for the terminal to know about the new Env Variable and now it finally works!
EDIT: The exe wasn't able to see other files in the folder that was installed so I've found another way:
Filename: "{cmd}"; Parameters: "/C setx YCS_JAVA ""C:\Program Files\Java\jdk-17\bin\server\jvm.dll"" && set YCS_JAVA=C:\Program Files\Java\jdk-17\bin\server\jvm.dll && cd {app} & START """" ""{#MyAppExeName}"""; \
Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: postinstall runhidden
I have next procedure to rename file on google drive, using REST with Google api. It's working with Delphi xe7.
Unfortunately with RAD 10 this procedure raise an exeption:
Java.net.ProtocolException unknown method 'Patch'... . I've read that it's because of java libraries. I changed paths
Tools-options-sdk manager - java to XE 7 java libraries, but it's useless.
Don't want to play Russian Roulette with random changing/updating setting, can someone tell me, what i should exactly update/change in RAD settings.
Thank you.
procedure ServerPatchDriveFile;
var
Folder : TJSONObject ;
FolderDest, itemmm : TJSONObject ;
parents: TJSONArray ;
begin
form2.RESTResponseDataSetAdapter1.AutoUpdate := false;
form2.RESTRequest1.Params.Clear;
form2.RESTRequest1.ClearBody;
form2.RESTClient1.AutoCreateParams:=false;
form2.RESTClient1.Accept:= '';
form2.RESTClient1.ContentType:= '';
form2.RESTRequest1.Method:= rmPATCH;
Form2.RESTClient1.BaseURL:='https://www.googleapis.com/drive/v2/files/{FileId}';
form2.RESTRequest1.Resource := '';
form2.RESTRequest1.Params.AddUrlSegment('fileId', UntitledId);
Parents:= TJSONArray.Create;
itemmm := TJSONObject.Create;
itemmm.AddPair(TJSONPair.Create('id', form2.EditIdFOlder.Text));
Parents.AddElement((itemmm));
Folder:= TJSONObject.create;
Folder.AddPair(TJSONPair.Create('title', 'Myfile'));
Folder.AddPair(TJSONPair.Create('parents', Parents));
form2.RESTRequest1.AddBody(Folder);
try
form2.RESTRequest1.Execute;
except
on e: Exception do
begin
ShowMessage(e.Message);//Show Exception
end;
end;
Folder.free;
Application.ProcessMessages;
end;
I am trying to run a program which takes a large amount of memory using the sbt "run" command and I seem to be running into the problem that the jvm seems to be getting a second -Xmx parameter from somewhere that overrides mine.
I am running the program via "sbt run".
Looking at the processes I can find the following:
/usr/bin/java -XX:MaxPermSize=256M -Xmx32G -Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m -jar /usr/local/Cellar/sbt/0.13.6/libexec/sbt-launch.jar run
My sbt file is as follows:
lazy val commonSettings = Seq(
organization := "edu.university",
version := "0.1.0",
scalaVersion := "2.10.2",
name := "Example",
javaOptions += "-Xmx32G"
)
If you would like to test it this is a piece of code I created that just fills memory.
package edu.university
import java.lang.Thread
import scala.collection.mutable.ArrayBuffer
object Main {
val arraySize = 10000
val nmws = 160000000 // no OOM
// val nmws = 180000000 // OOM
val r = scala.util.Random
def main(args: Array[String]): Unit = {
println("hi")
val ab = new ArrayBuffer[Memwaster](nmws)
ab.transform { a => new Memwaster(r.nextInt) }
println("done")
Thread.sleep(20000)
}
}
class Memwaster(foo: Int)
Running with the larger nmws value will use a little over 1G of memory then throw an out of memory error.
Turns out one solution is to set the -mem option in sbtopts. I found my sbtopts at /usr/local/etc/sbtopts (under OSx Yosemete). For 32G I set it to "-mem 32000". If this is a bad solution please post another answer I am happy to hear input here.
Sorta figured this out through the following documentation:
https://opensource.ncsa.illinois.edu/confluence/display/DFDL/Configure+SBT
Does this seem like a bug that the javaOptions value in my build.sbt doesn't override this? Or is this the desired behavior for some reason?
I have installed JRI to run with NetBeans 7.4 using 32-bit R 3.0.2 and Java jdk1.7.0_45, on Windows 7.
I am using the following Java code
REXP load=re.eval("source('C:\\\\SearchPath\\\\gammaDistAnova.r')");
String errStr=load.asString();
REXP stats=re.eval("gammaDistAnova.getStats(ref, target)");
to call the following R script.
gammaDistAnova.getStats<-function(ref, target){
library("MASS") # Library containing fitdistr
library("mgcv")
library("stats")
# Get mean and SD of reference
gr=fitdistr(ref+0.00001,"gamma") # Ref is a vector of (reference) values. The 0.00001 is to prevent errors due to zero values
meanRef<-gr[1]$estimate['shape']/gr[1]$estimate['rate'] # Mean of ref vector
SDref<-sqrt(gr[1]$estimate['shape']/(gr[1]$estimate['rate']^2)) # SD of ref vector
# Get mean and SD of target
gt=fitdistr(target+0.00001,"gamma") # target is a vector of (target) values. The 0.00001 is to prevent errors due to zero values
meanTarget<-gt[1]$estimate['shape']/gt[1]$estimate['rate'] # Mean of target vector
SDTarget<-sqrt(gt[1]$estimate['shape']/(gt[1]$estimate['rate']^2)) # SD of target vector
# Analysis of variance between the distributions
n=300
x=rgamma(n, shape=gr[1]$estimate['shape'], scale=1/gr[1]$estimate['rate'])
y=rgamma(n, shape=gt[1]$estimate['shape'], scale=1/gt[1]$estimate['rate'])
random1 <- sample(c("level1","level2","level3"), n, replace=TRUE)
debug=list(random1 = ~1)
# glmm1 <- gamm(y ~ x, random=list(random1 = ~1))
# anova(glmm1$gam)
out=list("refMean"=meanRef, "refSD"=SDref, "targetMean"=meanTarget, "targetSD"=SDTarget, "lx"=length(x), "ly"=length(y))
out
}
Everything runs fine (everything returned in the list seems valid and what I would expect) until I uncomment
glmm1 <- gamm(y ~ x, random=list(random1 = ~1))
in which case the function returns null, indicating a failure.
While the function fails with JRI, it runs without any problems on RStudio Version 0.98.501.
Edit:
I tried
glmm1 <- gamm(y ~ x, random=list(random1 = ~1))
errStr=geterrmessage()
errStr
but
re.eval("gammaDistAnova.getStats(ref, target)");
still returned null
You should check in your "lib" directory in ....\R\win-library\3.0.2
and check if you can obrerve the mgcv package, if not, downloaded it again into your R used version
One option is that you downloaded this library into an earlier version of R.
My customer wants to be able to call a jar file from Oracle PL/SQL.
Java 1.6, Oracle 11g R2
How do I do this?
I did a bit of research into loadjava (the program that loads classes into Oracle).
Sounded like a pain in the butt.
So I opted to run my jar outside Oracle but called from Oracle DBMS_SCHEDULER by PL/SQL.
Here's how:
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'testjar',
program_type => 'EXECUTABLE',
program_action => 'C:\MYSTUFF\testjar.bat',
enabled => TRUE,
comments => 'test testjar'
);
END;
/
begin
dbms_scheduler.create_job
(job_name => 'testjar_job',
program_name=> 'testjar',
enabled=>true,
auto_drop=>false,
comments=>'Only run immediately by dbms_scheduler.run_job');
end;
/
begin
dbms_scheduler.run_job('testjar_job',TRUE);
end;
/
After playing around I found out that the schema JAR_NAME.jar///ClassName.methodName(.... works.
So for example:
Function do()
return String
AS
LANGUAGE java
NAME 'my_jar.jar///MyClass.myMethod() return oracle.sql.String';
Note that it seems like some jar name files does not work. For example I had problems with a "-" in jar.