如何为Java程序设置进程名称?

63

如果一个Java程序被启动,它将在系统进程监视器中显示名称为 java。很多Java程序很难区分。因此,如果有一种方法可以设置在进程监视器中显示的名称,那就太好了。我知道在不同的操作系统上可能会有不同的方式。

一个简单的方法是,如果Java解释器支持一个开关来设置名称,就像这样:

java -processname MyProgram -jar MyProgram

但我找不到这样的开关,所以它可能不存在。用Java编写一个API来设置进程名称也可以。

那么,你有什么建议吗?

8个回答

52

我不知道这是否可行,但您可以使用随JDK一起提供的命令行工具“jps”。它类似于*nix中的ps,但仅显示Java程序。 jps -v会显示您传递给Java的所有参数。

此外,我看到有人通过将未使用的-Dmyprocessname添加到args中来附加一个“进程名称”到他们的Java进程中。


虽然不完全是我所问的答案,但却正好解决了我的问题。谢谢!:-) - Mnementh
由于缺乏setproctitle,这是一个聪明的解决方案。赞。 - synthesizerpatel
1
我也在寻找类似的选项。但是这个答案对我来说不太清楚。有人能解释一下如何设置进程名称吗?我看到有一个叫做“-D<name>=value”的选项。我们需要使用这个选项吗?谢谢。 - Naresh
3
支持-D的想法,没有比这更快更简单的了。 - jsh
似乎无法在Windows中使其工作。正确的命令是什么? - Yster

25

就像@omerkudat所说的:

jps -v

打印出所有Java进程的{进程ID,参数列表}。 如果参数列表不足以识别您需要的应用程序, 尝试在运行它们时添加一些虚拟参数:

java -Dname=myApp -cp  myApp.jar some.client.main.MainFrame
这将会打印出类似于:
7780 MainFrame -Dname=myApp

你可以使用进程ID来终止/监视它。


2
我更喜欢使用 jps -l,因为它显示了应用程序的完整包名称。 - smac89

15
你可以使用一个LD_PRELOAD shim来实现这一点: https://github.com/airlift/procname 当进程启动时,该shim仅调用Linux特定的prctl():
static void __attribute__ ((constructor)) procname_init()
{
   prctl(PR_SET_NAME, "myname");
}

此调用必须在主线程上进行,因此无法从Java甚至使用JVMTI代理执行此操作,因为这些操作发生在不同的线程上。


1
这个方法非常有效,比大多数方法都更简单。 - D2TheC
如果这段代码是在MIT、Apache或其他类似的许可协议下授权的,我会考虑使用它。 - Travis Spencer
7
这段代码非常简单(它只调用了一个函数),甚至似乎没有版权可言。请视为公共领域。如果需要,我可以添加一个许可证文件。 - David Phillips

5

5
当我第一次阅读这篇文章时,改变进程名称的想法让我觉得不可能。然而,根据太阳论坛上这个古老的帖子,你可以使用JVM可执行文件周围的C++包装器来实现这一点。
坦率地说,我想知道你的真正问题是什么,因为我猜想有比尝试更改进程名称更标准的解决方案。

4
如果您必须关闭您的应用程序,并且有几个正在运行的Java应用程序,这可能会有点不确定。 - Lloyd
2
没错,omerkudat提到的jps命令解决了问题,而无需重新命名进程。 - Mnementh
3
创建一个小的本地JNI包装器来启动应用程序也很容易。对于我们中的那些进行Windows部署的人,它允许自动配置JVM、自定义图标等等...这真的不难做到。 - Kevin Day
像往常一样,旧链接已被删除。 - pdem
2
@pdem请看这个问题: https://dev59.com/Y1wX5IYBdhLWcg3w8TXM#33186764 要点是使用launch4j。我的回答只是一个链接,对此我深感抱歉。当时不成熟,也不知道更好的方式。 - Tim Bender

3
主要有两种方法:一种是像上面已经描述的那样,使用Launch4j、WinRun4J等工具创建本地Windows启动器。
另一种更好的方法是使用Apache Procrun将Java应用程序包装为Windows服务。在安装服务过程中,我们可以给进程一个有意义的名称,例如OurApp.exe。
我们需要做的就是将prunsrv.exe重命名为OurApp.exe,并在我们的install|start|stop|uninstall服务脚本中替换每个出现的prunsrv.exe为MyApp.exe。
详情请参见使用Apache Procrun在Windows中重命名Java程序的进程名称

Launch4J无法解决这个问题。他们禁用了重命名进程的功能。此外,它也不能处理多进程应用程序,例如运行javaw和browsercore时。 - gunslingor

2
如果你想使用不同的进程名称,你需要创建自己的二进制文件来启动你的Java应用程序,比如使用像JSmooth这样的工具。请参考这个问题中的讨论来创建这样的二进制文件。

1

这是因为Java应用程序实际上并不是可执行的,它们是由Java虚拟机运行的,这就是为什么Java出现在进程监视器中,它是您应用程序的主机。

然而像LimeWire这样的东西确实可以,但我认为这更多是由于GCJ - http://gcc.gnu.org/java/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接