=head1 java-lib.pl Functions for managing Oracle JDK installations. foreign_require("tomcat", "tomcat-lib.pl"); @sites = tomcat::list_tomcat_websites() =cut BEGIN { push(@INC, ".."); }; use warnings; use WebminCore; foreign_require('software', 'software-lib.pl'); sub search_pkg{ my $pattern = $_[0]; my @avail = (); if (defined(&software::update_system_search)) { # Call the search function @avail = &software::update_system_search($pattern); } else { # Scan through list manually @avail = &software::update_system_available(); @avail = grep { $_->{'name'} =~ /\Q$pattern\E/i } @avail; } return sort @avail; } sub get_openjdk_patterns(){ my %osinfo = &detect_operating_system(); my %rv; if( ($osinfo{'real_os_type'} =~ /centos/i) or #CentOS ($osinfo{'real_os_type'} =~ /fedora/i) or #Fedora ($osinfo{'real_os_type'} =~ /scientific/i) ){ $rv{'search'} = 'openjdk'; $rv{'version'} = '^java-([0-9\.]+)-openjdk$'; }elsif( $osinfo{'os_type'} =~ /debian/i){ #ubuntu $rv{'search'} = 'openjdk-[0-9]+-jdk$'; $rv{'version'} = 'openjdk-([0-9]+)-jdk'; } return %rv; } sub get_openjdk_versions(){ my $cache_file = "$module_config_directory/openjdk_version_cache"; my %openjdk_versions; if(-f $cache_file){ read_file_cached($cache_file, \%openjdk_versions); if($openjdk_versions{'updated'} >= (time() - 86400)){ #if last update was less than a day ago delete $openjdk_versions{'updated'}; #remove the cache mtime key return %openjdk_versions; } } my %patterns = get_openjdk_patterns(); my @avail = search_pkg($patterns{'search'}); foreach $a (@avail) { if($a->{'name'} =~ /$patterns{'version'}/){ $openjdk_versions{$1} = $a->{'name'}; } } #cache the results $openjdk_versions{'updated'} = time(); &write_file($cache_file, \%openjdk_versions); delete $openjdk_versions{'updated'}; #remove the cache mtime key return %openjdk_versions; } sub get_latest_jdk_version(){ my %java_tar_gz; my $cache_file = "$module_config_directory/oracle_version_cache"; if(-f $cache_file){ read_file_cached($cache_file, \%java_tar_gz); if($java_tar_gz{'updated'} >= (time() - 86400)){ #if last update was less than a day ago delete $java_tar_gz{'updated'}; #remove the cache mtime key return %java_tar_gz; } } # my $error; # my $url = 'https://www.oracle.com/java/technologies/downloads/'; # $tmpfile = &transname("javase.html"); # &error_setup(&text('install_err3', $url)); # &http_download("www.oracle.com", 443, "/java/technologies/downloads/", $tmpfile, \$error, # undef, 1, undef, 0, 0, 1); # open($fh, '<', $tmpfile) or die "open:$!"; # while(my $line = <$fh>){ # #https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz # if($line =~ /(https:\/\/download.oracle.com\/java\/([0-9]+)\/latest\/jdk-[0-9]+_linux-x64_bin.tar.gz)/){ # #if($line =~ /"filepath":"(https:\/\/download.oracle.com\/otn-pub\/java\/jdk\/([a-z0-9-\.+]+)\/[a-z0-9]+\/jdk-[a-z0-9-\.]+_linux-x64_bin.tar.gz)/){ # $java_tar_gz{$2} = $1; # #last; # } # } # close $fh; #cache the results $java_tar_gz{'updated'} = time(); &write_file($cache_file, \%java_tar_gz); delete $java_tar_gz{'updated'}; #remove the cache mtime key return %java_tar_gz; } sub get_installed_jdk_versions(){ my @jdks = get_installed_oracle_jdk_versions(); push(@jdks, get_installed_openjdk_versions()); return @jdks; } sub get_installed_openjdk_versions{ my @pkgs = (); my %patterns = get_openjdk_patterns(); my $cmd_out=''; my $cmd_err=''; if(has_command('rpm')){ local $out = &execute_command("rpm -qa --queryformat \"%{NAME}\n\" \"*$patterns['search']*\"", undef, \$cmd_out, \$cmd_err, 0, 0); my @lines = split /\n/, $cmd_out; foreach my $line (@lines){ if($line =~ /^(java-[0-9\.]+-openjdk).*/i){ #package pgdg96-centos is not installed push(@pkgs, $1); } } }elsif(has_command('dpkg')){ local $out = &execute_command("dpkg -l \"*openjdk*\"", undef, \$cmd_out, \$cmd_err, 0, 0); my %all_pkgs; my @lines = split /\n/, $cmd_out; foreach my $line (@lines){ if($line =~ /^(..)\s+(openjdk-[0-9\.]*)-.*:.*/i){ my $pkg = $2; if($1 =~ /[uirph]i/){ $all_pkgs{$pkg} = 1; } } } @pkgs = keys %all_pkgs; }else{ my @dirs; opendir(DIR, '/usr/java/') or return @dirs; @dirs = grep { /^jdk-[0-9\.]+/ && -d "/usr/java/$_" } readdir(DIR); closedir(DIR); } return sort @pkgs; } sub get_installed_oracle_jdk_versions{ my @dirs; opendir(DIR, '/usr/java/') or return @dirs; @dirs = grep { /^jdk[0-9\.\-_]+/ && -d "/usr/java/$_" } readdir(DIR); closedir(DIR); return sort @dirs; } sub is_default_jdk{ my $jdk_dir = $_[0]; my %os_env; if(-f '/etc/profile.d/jdk.sh'){ read_env_file('/etc/profile.d/jdk.sh', \%os_env); }elsif(-f '/etc/environment'){ read_env_file('/etc/environment', \%os_env); } if($os_env{'JAVA_HOME'} eq $jdk_dir){ return 1; }else{ return 0; } } sub get_java_version(){ local %version; local $out = &backquote_command('java \-version 2>&1'); #Oracle Java <= 8 if ($out =~ /Java\(TM\)\sSE\sRuntime\sEnvironment\s\(build\s([0-9]\.([0-9]+)\.[0-9]_([0-9]+)\-([a-z0-9]+))\)/) { $version{'full'} = $1; $version{'major'} = $2; $version{'release'} = $3; $version{'build'} = $4; $version{'vendor'} = 'oracle'; #Oracle Java >=12 - Java(TM) SE Runtime Environment (build 12.0.1+12) }elsif ($out =~ /Java\(TM\)\sSE\sRuntime\sEnvironment\s\(build\s((\d+)\.\d+\.\d+\+(\d+))\)/) { $version{'full'} = $1; $version{'major'} = $2; $version{'release'} = 0; $version{'build'} = $3; $version{'vendor'} = 'oracle'; # OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-2ubuntu218.04) # OpenJDK Runtime Environment (build 1.8.0_252-8u252-b09-1~18.04-b09) }elsif ($out =~ /Runtime\sEnvironment\s\(build\s((\d+)\.(\d+)\.\d+[\+_](\d+))/) { if($2 eq '1'){ #1.8.x $version{'major'} = $3; $version{'release'} = $4; $version{'build'} = $5; }else{ #11.0.x $version{'major'} = $2; $version{'release'} = $3; $version{'build'} = $4; } $version{'full'} = $1; $version{'vendor'} = 'openjdk'; }else { $version{'major'} = 0; $version{'full'} = $out; $version{'release'} = 0; $version{'build'} = 0; } return %version; } sub get_java_home(){ my $java_path = &resolve_links('/usr/bin/java'); $java_path =~ s/\/bin\/java//; return $java_path; } sub set_default_java{ my $jdk_dir = $_[0]; my $alt_cmd = ""; if(has_command('alternatives')){ #CentOS $alt_cmd = 'alternatives'; }elsif(has_command('update-alternatives')){ #ubuntu $alt_cmd = 'update-alternatives'; }else{ print "Warning: No alternatives command found
"; } if($alt_cmd ne ""){ print "Updating Java using $alt_cmd
"; my @jdk_progs = ('java', 'jar', 'javac'); foreach my $prog (@jdk_progs){ $cmd_out=''; $cmd_err=''; local $out = &execute_command("$alt_cmd --install /usr/bin/$prog $prog $jdk_dir/bin/$prog 1", undef, \$cmd_out, \$cmd_err, 0, 0); $out.= &execute_command("$alt_cmd --set $prog $jdk_dir/bin/$prog", undef, \$cmd_out, \$cmd_err, 0, 0); if($cmd_err){ $cmd_err = s/\n/
/g; &error("Error: $alt_cmd: $cmd_err"); }else{ $cmd_out = s/\n/
/g; print &html_escape($cmd_out); } } } print "
Setting Java environment variables...
"; my %os_env; $os_env{'J2SDKDIR'} = $jdk_dir; $os_env{'JAVA_HOME'} = $jdk_dir; $os_env{'DERBY_HOME'}= "$jdk_dir/db"; $os_env{'J2REDIR'} = "$jdk_dir/jre"; if(-e '/etc/profile.d/'){ $os_env{'PATH'} = "\$PATH:$jdk_dir/bin:$jdk_dir/db/bin:$jdk_dir/jre/bin"; write_env_file('/etc/profile.d/jdk.sh', \%os_env, 1); }elsif(-e '/etc/environment'){ read_env_file('/etc/environment', \%os_env); $os_env{'PATH'} = "$os_env{'PATH'}:$jdk_dir/bin:$jdk_dir/db/bin:$jdk_dir/jre/bin"; write_env_file('/etc/environment', \%os_env, 0); } } sub unset_default_java{ my $jdk_dir = $_[0]; print "Removing Java environment variables ...
"; if(-f '/etc/profile.d/jdk.sh'){ unlink_file('/etc/profile.d/jdk.sh'); }elsif(-f '/etc/environment'){ my %os_env; read_env_file('/etc/environment', \%os_env); delete $os_env{'J2SDKDIR'}; delete $os_env{'JAVA_HOME'}; delete $os_env{'DERBY_HOME'}; delete $os_env{'J2REDIR'}; write_env_file('/etc/environment', \%os_env, 0); } my $alt_cmd = ""; if(has_command('alternatives')){ #CentOS $alt_cmd = 'alternatives'; }elsif(has_command('update-alternatives')){ #ubuntu $alt_cmd = 'update-alternatives'; }else{ print "Warning: No alternatives command found
"; } if($alt_cmd ne ""){ print "Removing Java using $alt_cmd
"; my @jdk_progs = ('java', 'jar', 'javac'); foreach my $prog (@jdk_progs){ $cmd_out=''; $cmd_err=''; local $out = &execute_command("$alt_cmd --remove $prog $jdk_dir/bin/$prog", undef, \$cmd_out, \$cmd_err, 0, 0); if($cmd_err){ &error("Error: $alt_cmd: $cmd_err"); }else{ $cmd_out = s/\r\n/
/g; print &html_escape($cmd_out); } } } } sub get_jdk_dir_by_name{ my $jdk_name = $_[0]; my $jdk_dir = ''; if($jdk_name =~ /.*openjdk.*/){ my $jdk_ver = (split /-/, $jdk_name)[1]; #get version from name my @known_dirs = ('java-'.$jdk_ver.'-openjdk', 'java-'.$jdk_ver.'-openjdk-amd64', 'jre-'.$jdk_ver.'-openjdk'); foreach $jvm_name (@known_dirs){ if(-d '/usr/lib/jvm/'.$jvm_name){ $jdk_dir = '/usr/lib/jvm/'.$jvm_name; last; } } }else{ $jdk_dir = '/usr/java/'.$jdk_name; } return $jdk_dir; } 1;