求解。java程序运行后有个警告。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求解。java程序运行后有个警告。相关的知识,希望对你有一定的参考价值。

import java.lang.reflect.*;
//impot java.lang.*;
class ClassText

public static void main(String[] args)


if(args.length!=1)

return;

try

Class c=Class.forName(args[0]);
Constructor[] cons=c.getDeclaredConstructors();

Class[] params=cons[0].getParameterTypes();
Object[] paramValues=new Object[params.length];
for(int i=0;i<params.length;i++)

if(params[i].isPrimitive())

paramValues[i]=new Integer(i+3);


Object o=cons[0].newInstance(paramValues);
Method[] ms=c.getDeclaredMethods();
ms[0].invoke(o,null);

catch(Exception e)

e.printStackTrace();




class Point

static

System.out.println("loading point");

int x,y;
void output()

System.out.println("x="+x+","+"y="+y);


class Lain

static

System.out.println("loading lain");


运行了之后。。。。。。。。。。。。。。。。。。。。。。。

G:\java>javac ClassText.java
ClassText.java:85: 警告:最后一个参数使用了不准确的变量类型的 varargs 方法的非
arargs 调用;
对于 varargs 调用,应使用 java.lang.Object
对于非 varargs 调用,应使用 java.lang.Object[],这样也可以抑制此警告
ms[0].invoke(o,null);
^
1 警告

参考技术A ms[0].invoke(o, new Object[0]); 参考技术B 同意楼上观点。

在运行时提升 Java 应用程序

【中文标题】在运行时提升 Java 应用程序【英文标题】:Elevate Java application while running 【发布时间】:2015-07-16 22:48:02 【问题描述】:

我的软件出现了一个令人讨厌的问题。我正在制作一个与另一个现有软件(游戏)交互的程序。用户报告说他以管理员权限运行游戏,在这种情况下,我的程序停止为他工作。

调查显示,有些人确实需要在管理员帐户下运行游戏,而有些人则不需要。如果我的程序能够检测到这一点并在游戏在管理员帐户下运行时警告用户,那就太好了:

如果用户单击“提升”,我想要求 Windows 提升运行我的 jar 文件的 java.exe 并调用典型的 UAC 对话框。

显然,这次的问题不是关于 java 更新程序,而是关于 JRE

我的问题是:这可能吗? windows 可以提升我的java.exe 实例的权限吗? java有没有办法做到这一点?或者我可以使用命令行命令吗?

我想避免重新启动程序(尽管这可能没什么大不了的)。

编辑: 如果您查看 cmets,您会发现无法避免重新启动应用程序 - 进程只能启动提升,而不能变得提升。不幸的是,这有点改变了问题。基本上,现在听起来更像是:“如何使用管理员权限重新启动我的应用程序?”。当然,除非有两个 java.exe 共享一个罐子这样的技巧......

【问题讨论】:

我不会投票决定将其作为重复项关闭,因为它仍然是一个很好的问题并且措辞略有不同,但有几个问题是这样的:***.com/questions/4662574/…、***.com/questions/1076794/uac-and-java。 实际上还有很多其他问题可以解决这个问题,我还在阅读另一个问题。多谢两位! :) 目前,我至少在重新启动变体中工作,而且一点也不简单。你能做的最好的就是generate a vbs script and run it... @SergeyTachenov 那里的答案暗示了我直到现在才知道的东西——你不能提升运行过程。所以我想需要重启。 我在这里之前问过这个问题->[***.com/questions/13290101/…],你可以做的是启动你的java应用程序,然后检查它是否有权限,如果没有,然后重新启动自己询问正确的权限(但需要重新启动) 您可以制作一个启动器来检查游戏的权限。然后 Launcher 使用 ProcessBuilder 和适当的标志 example 以相同的权限调用您的 java 应用程序 【参考方案1】:

正如 cmets 中所指出的,遗憾的是 Java(或任何其他进程)在运行时无法提升。虽然在 JWM 的情况下,理论上可以将整个程序上下文从普通用户 java.exe 移动到提升的用户,但我认为这是不可能的。我希望有一天有人会来告诉我我错了。

令人惊讶的是,即使 restart 到位,这也是一项棘手的任务,我花了一段时间才弄清楚。

非java部分

首先,我们如何准确地运行从命令行提升的程序? There's an answer 你可以看到它并不简单。但是我们可以把它分解成这个 VBS 脚本:

Set UAC = CreateObject("Shell.Application") 
UAC.ShellExecute "program name", "command line parameters", "working directory", "runas", 1 

很快,事实证明我们won't have any success running java.exe from VBS script。最后,我决定运行一个帮助批处理文件。最后,here(最后一个链接中问题的答案)我们有完整的两个脚本集,它们真正运行给定的.jar 文件提升。这是改进的版本,可以通过拖放 Jar 文件来进行快速测试:

' Require first command line parameter
if WScript.Arguments.Count = 0 then
  MsgBox("Jar file name required.")
  WScript.Quit 1
end if

' Get the script location, the directorry where it's running
Set objShell = CreateObject("Wscript.Shell")

strPath = Wscript.ScriptFullName

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.GetFile(strPath)
strFolder = objFSO.GetParentFolderName(objFile) 
'MsgBox(strFolder)

' Create the object that serves as runnable something
Set UAC = CreateObject("Shell.Application") 
' Args:
'   path to executable to run
'   command line parameters - first parameter of this file, which is the jar file name
'   working directory (this doesn't work but I use it nevertheless)
'   runas command which invokes elevation
'   0 means do not show the window. Normally, you show the window, but not this console window
'     which just blinks and disappears anyway
UAC.ShellExecute "run-normally.bat", WScript.Arguments(0), strFolder, "runas", 0 

WScript.Quit 0

Java 部分

Java 部分更直接。我们需要做的是打开新进程并在其中执行准备好的脚本。

   /**
    * Start this very jar file elevated on Windows. It is strongly recommended to close any existing IO
    * before calling this method and avoid writing anything more to files. The new instance of this same
    * program will be started and simultaneous write/write or read/write would cause errors.
    * @throws FileNotFoundException if the helper vbs script was not found
    * @throws IOException if there was another failure inboking VBS script
    */
   public void StartWithAdminRights() throws FileNotFoundException, IOException 
     //The path to the helper script. This scripts takes 1 argument which is a Jar file full path
     File runAsAdmin = new File("run-as-admin.vbs");;
     //Our 
     String jarPath;

     //System.out.println("Current relative path is: " + s);

     try 
       jarPath = "\""+new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getAbsolutePath()+"\"";
      catch (URISyntaxException ex) 
       throw new FileNotFoundException("Could not fetch the path to the current jar file. Got this URISyntax exception:"+ex);
     
     //If the jar path was created but doesn't contain .jar, we're (most likely) not running from jar
     //typically this happens when running the program from IDE
     //These 4 lines just serve as a fallback in testing, should be deleted in production
     //code and replaced with another FileNotFoundException
     if(!jarPath.contains(".jar")) 
       Path currentRelativePath = Paths.get("");
       jarPath = "\""+currentRelativePath.toAbsolutePath().toString()+"\\AutoClient.jar\"";
     
     //Now we check if the path to vbs script exists, if it does we execute it
     if(runAsAdmin.exists()) 
       String command = "cscript \""+runAsAdmin.getAbsolutePath()+"\" "+jarPath;
       System.out.println("Executing '"+command+"'");
       //Note that .exec is asynchronous
       //After it starts, you must terminate your program ASAP, or you'll have 2 instances running
       Runtime.getRuntime().exec(command);

     
     else
       throw new FileNotFoundException("The VBSScript used for elevation not found at "+runAsAdmin.getAbsolutePath());
   

【讨论】:

run-normally.bat在哪里? @CardinalSystem 我不知道,我已经有一段时间没有发布这个了。但是run-normally.bat 只包含类似java application-jar-path 或任何运行JAR 文件的命令。【参考方案2】:

这是我的版本。它创建一个 VBScript 脚本,然后执行它。这仅在正在运行的程序位于 jar 文件中时才有效,因此您必须以管理员身份运行 IDE 才能实际测试您的程序。

public static void relaunchAsAdmin() throws IOException 
    relaunchAsAdmin(ThisClass.class); //Change ThisClass to the class that this method is in


public static void relaunchAsAdmin(Class<?> clazz) throws IOException 
    if(isCurrentProcessElevated()) 
        return;
    
    final String dir = System.getProperty("java.io.tmpdir");
    final File script = new File(dir, "relaunchAsAdmin" + System.nanoTime() +
            ".vbs");
    try 
        script.createNewFile();
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(script));
        osw.append("Set s=CreateObject(\"Shell.Application\")" + ln + "s.ShellExecute \"" +
                System.getProperty("java.home") + "\\bin\\java.exe" + "\",\"-jar \"\"" +
                new File(clazz.getProtectionDomain().getCodeSource(
                ).getLocation().toURI()).getAbsolutePath() + "\"\"\",,\"runas\",0" +
                        ln + "x=createObject(\"scripting.fileSystemObject\").deleteFile(" +
                        "WScript.scriptfullname)");
        osw.close();
        if(System.getenv("processor_architecture").equals("x86")) 
            Runtime.getRuntime().exec("C:\\Windows\\System32\\wscript.exe \"" +
                    script.getAbsolutePath() + "\"");
         else 
            Runtime.getRuntime().exec("C:\\Windows\\SysWoW64\\wscript.exe \"" +
                    script.getAbsolutePath() + "\"");
        
     catch(URISyntaxException e) 
        e.printStackTrace();
    
    Runtime.getRuntime().exit(0);

请注意,它有点乱。我以前一直在使用这种方法,所以它已经被换行到 100 个字符(除了我为这个答案写的评论)。

isCurrentProcessElevated()

方法必须以一种或另一种方式实现。你可以尝试使用JNI,也可以使用纯Java的方法,比如写入Program Files或System32目录,看看是否失败。

显然,此解决方案仅适用于 Windows。我从来不需要在 Linux 或 Mac 系统上升级(主要是因为我没有任何 Mac 系统,而且我不使用 Linux - 我只是玩弄它)。

【讨论】:

只是说,这基本上是重新启动你的Java应用程序。在运行时提升进程是不可能的。如果您想在重新启动后恢复当前状态,您可以创建一个临时文件并检查当前进程是否已提升。【参考方案3】:

如果仍然感兴趣:在 Windows 7 中,我的 JavaElevator 可以工作。在 Java 应用程序的 main 方法中使用时,它会提升正在运行的 Java 进程。只需添加-elevate作为最后一个程序参数,并在main方法中使用电梯。

电梯类:

package test;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.platform.win32.ShellAPI;
import com.sun.jna.platform.win32.WinDef;

/**
 * Elevates a Java process to administrator rights if requested.
 */
public class JavaElevator 
    /** The program argument indicating the need of being elevated */
    private static final String ELEVATE_ARG = "-elevate";

    /**
     * If requested, elevates the Java process started with the given arguments to administrator level.
     * 
     * @param args The Java program arguments
     * @return The cleaned program arguments
     */
    public static String[] elevate(String[] args) 
        String[] result = args;

        // Check for elevation marker.  
        boolean elevate = false;
        if (args.length > 0) 
            elevate = args[args.length - 1].equals(ELEVATE_ARG);
        
        if (elevate) 
            // Get the command and remove the elevation marker.
            String command = System.getProperty("sun.java.command");
            command = command.replace(ELEVATE_ARG, "");

            // Get class path and default java home.
            String classPath = System.getProperty("java.class.path");
            String javaHome = System.getProperty("java.home");
            String vm = javaHome + "\\bin\\java.exe";

            // Check for alternate VM for elevation. Full path to the VM may be passed with: -Delevation.vm=...
            if (System.getProperties().contains("elevation.vm")) 
                vm = System.getProperty("elevation.vm");
            
            String parameters = "-cp " + classPath;
            parameters += " " + command;
                Shell32.INSTANCE.ShellExecute(null, "runas", vm, parameters, null, 0);

            int lastError = Kernel32.INSTANCE.GetLastError();
            if (lastError != 0) 
                String errorMessage = Kernel32Util.formatMessageFromLastErrorCode(lastError);
                errorMessage += "\n  vm: " + vm;
                errorMessage += "\n  parameters: " + parameters;
                throw new IllegalStateException("Error performing elevation: " + lastError + ": " + errorMessage);
            
            System.exit(0);
        
        return result;
    

在Java应用的main方法中的使用:

public static void main(String[] args) 
    String[] args1 = JavaElevator.elevate(args);
    if (args1.length > 0) 
       // Continue as intended.
       ... 

我知道,这是一个非常基本的实现 - 足以应付我的一个日常问题:从 Eclipse 启动一个提升的进程。但也许它会为某人指明方向......

【讨论】:

谢谢,帮了大忙。不要忘记将类路径放在引号内,以防它包含任何空格...

以上是关于求解。java程序运行后有个警告。的主要内容,如果未能解决你的问题,请参考以下文章

求解JAVA编程题:编写一个应用程序,创建三个线程分别显示各自的运行时间

我正在捣腾hadoop,用java编写了一个程序,想要连接到hdfs上,运行后显示如下,这是啥问题呢?求解!

java运行python程序,.readLine()读出的内容为null, proc.waitFor();返回值为1,求解

java中如何计算一个程序运行所需的最少时间,最多时间和平均时间?

为啥VB环境下调试正常,生成EXE后运行则发生错误?

java程序中很多警告,如何修改掉?