【问题标题】:Tomcat JMX connection - Authentication failedTomcat JMX 连接 - 身份验证失败
【发布时间】:2011-01-13 12:14:52
【问题描述】:

我在为 JMX 设置 Tomcat 时遇到一些问题。我将以下属性添加到

  CATALINA_OPTS="-Dcom.sun.management.jmxremote.port=18070      -Dcom.sun.management.jmxremote.password.file=$CATALINA_BASE/conf/jmxremote.password      -Dcom.sun
    .management.jmxremote.ssl=false"

并将 jmxremote.password 文件添加到 conf 目录中。我编写了一个客户端工具,连接到在端口 18070 上运行的 JMX 服务器。当我运行客户端程序时,出现以下错误。

    Exception in thread "main" java.lang.SecurityException: Authentication failed! Credentials required
       at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticationFailure(JMXPluggableAuthenticator.java:193)
       at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticate(JMXPluggableAuthenticator.java:145)
       at sun.management.jmxremote.ConnectorBootstrap$AccessFileCheckerAuthenticator.authenticate(ConnectorBootstrap.java:185)
       at javax.management.remote.rmi.RMIServerImpl.doNewClient(RMIServerImpl.java:213)
       at javax.management.remote.rmi.RMIServerImpl.newClient(RMIServerImpl.java:180)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
       at sun.rmi.transport.Transport$1.run(Transport.java:159)
       at java.security.AccessController.doPrivileged(Native Method)
       at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
       at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
       at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
       at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
       at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
       at java.lang.Thread.run(Thread.java:619)
       at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
       at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
       at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
       at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source)
       at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2312)
       at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:277)
       at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:248)
       at com.bt.c21sc.c21tkprobe.accessors.C21TkProbeJmxDAO.connect(Unknown Source)
       at com.bt.c21sc.c21tkprobe.service.C21TkProbeBD.execute(Unknown Source)
       at com.bt.c21sc.c21tkprobe.C21AppserverProbe.main(Unknown Source)

如果我将 CATALINA_OPTS 属性更改为

CATALINA_OPTS="-Dcom.sun.management.jmxremote.port=18070 -Dcom.sun.management.jmxremote.password.file=$CATALINA_BASE/conf/jmxremote.password -Dcom.sun
.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

然后它工作正常。我想我感到困惑的是什么被归类为远程访问。我正在远离 Tomcat 实例运行客户端程序,但 Tomcat 和客户端工具都在同一台机器上(即不同的虚拟机但相同的环境)。如果我从另一台机器远程访问 JMX 服务器,我想我必须配置远程身份验证。

远程访问是指从本地或远程的任何 VM 访问 JMX 服务器吗?

编辑

谢谢。我发现问题在于,即使我在 jmxremort.password 和 jmxremote.access 文件中提供了用户名和密码,我仍然必须从客户端提供用户名和密码。

您是对的,如果在本地运行,我不必提供用户凭据。我已经证明了这一点,因为我可以通过 Jconsole 访问 Tomcat 的 JVM。

我正在以编程方式访问它,所以我必须提供一个如下所示的 URL 服务:jmx:rmi:///jndi/rmi://localhost:9004/jmxrmi

然后我得到如下所示的 jmx 服务器。

url = new JMXServiceURL(urlString);         
Hashtable<String, String[]> env = new Hashtable<String, String[]>();
String[] credentials = new String[] {user,pass};
env.put(JMXConnector.CREDENTIALS, credentials);         
jmxc = JMXConnectorFactory.connect(url,env); 
mbsc = jmxc.getMBeanServerConnection(); 

如果我在本地访问此内容,我将如何处理?我知道它在没有用户凭据的情况下无法在本地工作,因为这就是我发现我需要提供的方式。如果 Jconsole 或 visualvm 可以连接到它,那么必须有一种不同的方法允许检索 Tomcat jmx 服务器而无需提供端口号。

URL 包含一个端口号。如果我以编程方式访问 JMX 服务器,我将如何访问它而无需指定端口号?

顺便说一下,我使用的是 Tomcat 5.5 和 JDK 1.6

谢谢

【问题讨论】:

  • 重复 - 你能压缩这些请求吗...
  • "我发现问题在于,即使我在 jmxremort.password 和 jmxremote.access 文件中提供了用户名和密码,我仍然必须从客户端提供用户名和密码。" - 当然,jmxremote.access 用作密码存储,因此您必须使用您的 JMX 客户端进行身份验证

标签: java tomcat jakarta-ee jmx


【解决方案1】:

远程访问

远程访问是指从另一台机器访问,通过您don't have to setup JMX[注1]的另一台VM本地访问。您可以通过在没有 JMX 的情况下启动 java 应用程序来尝试此操作,然后在同一台机器上启动 VisualVM。启动的应用程序应出现在“本地”下(在 VisualVM 中)。

如例外所述:Authentication failed! Credentials required 你提供了用户名和密码吗? ;) 我猜你做到了...

可能的解决方案

如果你这样做了,那么你应该尝试从 CATALINA_OPTS 中删除 $CATALINA_BASE 并输入一个硬编码值,看看这是否是根本问题。

示例:

CATALINA_OPTS="-Dcom.sun.management.jmxremote.port=18070 -Dcom.sun.management.jmxremote.password.file=/opt/tomcat6/conf/jmxremote.password -Dcom.sun.management.jmxremote.ssl=false"

如果可行,请尝试这样:

CATALINA_OPTS="-Dcom.sun.management.jmxremote.port=18070
-Dcom.sun.management.jmxremote.password.file=`echo $CATALINA_BASE`/conf/jmxremote.password
-Dcom.sun.management.jmxremote.ssl=false"

[注 1]:这里说:“在 Java SE 平台的先前版本中,要允许 JMX 客户端访问本地 Java VM,您必须设置以下系统属性(com.sun.management .jmxremote) 当您启动 Java VM 或 Java 应用程序时。设置此属性注册 Java VM 平台的 MBean 并通过私有接口发布远程方法调用 (RMI) 连接器,以允许 JMX 客户端应用程序监视本地 Java 平台,即, 与 JMX 客户端在同一台机器上运行的 Java VM。在 Java SE 6 平台中,不再需要设置此系统属性。任何在 Java SE 6 平台上启动的应用程序都将支持 Attach API,并且因此将在需要时自动提供给本地监控和管理。”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-12
    • 2023-03-11
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多