我们有一个主要的(程序),它分析特定的CLP但不保存任何地方他们。 然后,我有我自己的插件代码,需要访问原来的CLP(这样我就可以传输更多参数)它。然而,我无法改变主()

我看到有显然是一个方式C#要做到这一点,我正在寻找在Linux上的等效Java解决方案。

更新:显然,我所知道的是如何的main()的作品。不幸的是,我不能改变现有的应用程序或调用它(除的CLP)的方式。我只能通过沙盒插件代码的访问。我的问题是,是否有一种方式来获得该JVM用调用命令行(而不是用-D环境变量)。

有帮助吗?

解决方案

除了在某些方面做的主要我认为你将是唯一的选择将下降到操作系统层面和执行某些命令,得到的参数。

在Linux的运行中的进程的CMD线参数存储在的的/ proc / PID / CMDLINE

因此,要获得他们,你必须找到进程ID。在这里看到:

Java程序怎样才能得到它自己的进程ID?

然后,使用这种开放的的/ proc / PID / CMDLINE 并解析它。该文件,并在C的示例的格式是在这里:

HTTP ://www.unix.com/unix-advanced-expert-users/86740-retrieving-command-line-arguments-particular-pid.html

这可能是最好的包装在一个shell脚本,这两个调用你从Java调用。

请注意,这将是非常不便携,是有点哈克。但是,如果需要,必须...

其他提示

一旦你认识到Java的主要方法是另一种静态方法,它采用一个字符串数组作为参数的解决方案是容易的。

创建一个存储的CLP一个新的类,然后调用老班。之后,你可以使用新类来访问你的CLP:

import NotToBeChangedMainClass;

public MyMainClass {
  public static final String[] ARGUMENTS;
  public static void main(String ... args) {
    ARGUMENTS = args;
    NotToBeChangedMainClass.main(args);
  }

}

最后,改变任何外部呼叫者(例如任何批处理文件)使用MyMainClass代替NotToBeChangedMainClass。如果使用的是可运行的罐子或类似的东西,这需要改变相应的配置文件。

创建自己的主类。保存的参数。调用老main

这可能是更容易使用在命令行上System.getProperty-Dkey=value(前主类名或-jar)。

如果你没有选择任何你绝对要与他们的确切名称保留所有现有的类名(的为您的评论以我以前的答案所述),那么你有去使用AspectJ。

让我们考虑一下,我们有这个类:

public class UnmodifyableClassWithMain {
  public static void main(String[] args) {
    System.out.println("In main");
    new ClassUsingArgumentRegistry();
  }
}

首先,你需要的东西,保持命令行参数。我将使用一个简单的类具有静态字段为简单起见:

public class ArgumentRegistry {
  public static String[] ARGS;
}

然后,需要定义,它可以拦截到主呼叫和存储参数的一个方面。

public aspect StoreArgumentsOfMain {

  /**
   * This pointcut intercepts all calls to methods called main with a string array as
   * argument.
   */
  pointcut mainMethod(String[] arguments): execution(void main(String[])) && args(arguments);

  /**
   * Before the original main method gets called, store the arguments in the registry.
   */
  before(String[] arguments): mainMethod(arguments) {
    System.out.println("Storing arguments");
    ArgumentRegistry.ARGS = arguments;
  }

}

有关尝试出来,我还创建了一个ClassUsingArgumentRegistry:

public class ClassUsingArgumentRegistry {

  public ClassUsingArgumentRegistry() {
    System.out.println("Arguments: " + java.util.Arrays.toString(ArgumentRegistry.ARGS));
  }

}

就是这样。如果启用AspectJ的编译时编织和使用的“java UnmodifyableClassWithMain富酒吧巴兹”运行的结果,我得到follwing输出:

Storing arguments
In main
Arguments: [foo, bar, baz]

请注意,此解决方案是非常有限的像Linux截断它保存命令行。作为Java命令行往往具有非常长的类路径,这是一个非常实际的问题。

下面是实现由Pablojim给出的答案Java代码。

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test {
  public static List<String> getLinuxCmdline(int maxBytesToRead) throws IOException {
    List<String> result = new ArrayList<>();
    String pid = new File("/proc/self").getCanonicalFile().getName();
    File cmdlineFile = new File("/proc/" + pid + "/cmdline");
    final int growBy = 1024;
    try (FileInputStream is = new FileInputStream(cmdlineFile);) {
      byte[] data = new byte[Math.min(growBy, maxBytesToRead)];
      int totalRead = 0; 
      while (totalRead < maxBytesToRead) {
        int read = is.read(data, totalRead, data.length - totalRead);
        if (read > 0) {
          totalRead += read;
          if (data.length == totalRead) {
            data = Arrays.copyOf(data, Math.min(data.length + growBy, maxBytesToRead));
          }
        } else {
          break;
        }
      }
      int start = 0;
      int scan = 0;
      while (scan < totalRead) {
        if (data[scan] == 0) {
          result.add(new String(Arrays.copyOfRange(data, start, scan)));
          start = scan + 1;
        }
        scan++;
      }
      if (scan - start > 0) result.add(new String(Arrays.copyOfRange(data, start, scan)));        }
    return result;
  }

  public static void main(String[] args) throws IOException {
    System.out.println(getLinuxCmdline(Integer.MAX_VALUE));
  }
}

在Eclipse中的参数“富巴”运行这给了这对我来说:

[/usr/lib/jvm/java-8-oracle/bin/java, -Dfile.encoding=UTF-8, -classpath, /home/mab/workspace/test/bin, test.Test, foo, bar]
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top