Jconsole Remote Executable Jar File - java

All,
I have a remote server that I recently enabled VNC for using vnc4server and Chicken for mac as the client.
The purpose for doing so was to enable running Java's Jconsole to monitor an executable jar file that is running my server logic.
However, after logging into my server using VNC, I keep getting an error when I try to use Jconsole on vnc.
It states connection failed do you want to try again. Now I am logged in as the same user that started the process.
Is there something I am missing when using jconsole in VNC? Also can I monitor my executable jar file remotely using Jconsole on my local machine?
These are the options I am including to run the jar file: java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9005 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.remote.ssl=false -Djava.rmi.server.hostname=ipaddress -jar path
Thanks
These JVM options fixed things. Fix found here: You need to pass to the VM: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false
https://forums.oracle.com/thread/1177644

This does not seem like an VNC issue- either the ports are not open, they are being blocked b a firewall, or there is some kind of permission/authentication issue with the app itself related to monitoring it.
In order to eliminate VNC as the cause (and use localhost in a local connection on jconsole), do "ssh -X REMOTHOST -n jconsole" and see. This will also eliminate the overhead of running the full X server and VNC.
Also on linux you can find out what process holds a port open by doing:
netstat -ap | grep PORT_NUMBER on the remote host you want to run on.
Colin

Related

Java remote JMX config gets ignored

I'm trying to create the correct remote JMX config for a Java process on:
OpenJDK 8
CentOS 7
The box seems to be provisioned correctly and the process being run ends up with the following vm options (confirmed using a ps -ef command):
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.ssl=true
-Dcom.sun.management.jmxremote.ssl.enabled.protocols=TLSv1.2
-Dcom.sun.management.jmxremote.registry.ssl=true
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.ssl.config.file=/path/to/jmxremote.properties
-Dcom.sun.management.jmxremote.access.file=/path/to/jmxremote.access
-Dcom.sun.management.jmxremote.password.file=/path/to/jmxremote.password
-Dcom.sun.management.jmxremote.port=<<my_port>>
-Dcom.sun.management.jmxremote.rmi.port=<<my_port>>
The problem I'm facing is that after I start the process, no error is thrown, but the port is not open, whereas all the other ports opened by the application are.
Does anyone know why this config would be utterly ignored by the application?

Stackdriver GCE JVM monitoring setup problems

I have a custom instance running on Windows Server 2016 where I need to monitor my Java processes.
I setup Stackdriver, installed the monitoring agent and followed this guide for JVM monitoring https://cloud.google.com/monitoring/agent/plugins/jvm
However no matter what I do I can not see any of my processes when setting up an Alerting policy within Stackdriver's console.
There are 2 steps in the guide I am unsure how to follow:
On your VM instance, download jvm-sun-hotspot.conf from the GitHub configuration repository and place it in the directory
/opt/stackdriver/collectd/etc/collectd.d/
Where exactly do I place the .conf file?
Edit the downloaded configuration file and replace JMX_PORT by the port on which your JVM is configured to allow JMX connections.
How do I get the port?
Sorry if this seems obvious but I'm pretty new to this.
Thanks in advance for your help.
All the steps and instructions on the JVM plugin page have instructions relevant for linux, and windows is not even mentioned there. So it could be quite possible that the JVM plugin is supported only on linux.
Since your code is already running on a JVM, you might want to consider if it is possible to move your application from a Windows VM to a linux VM.
Enabling the JVM monitoring plugin
Java Virtual Machines are monitored via JMX.
On your VM instance, download jvm-sun-hotspot.conf from the GitHub
configuration repository and place it in the directory
/opt/stackdriver/collectd/etc/collectd.d/:
(cd /opt/stackdriver/collectd/etc/collectd.d/ && curl -O https://raw.githubusercontent.com/Stackdriver/stackdriver-agent-service-configs/master/etc/collectd.d/jvm-sun-hotspot.conf)
Edit the downloaded configuration file and replace JMX_PORT by the
port on which your JVM is configured to allow JMX connections.
After adding the configuration file, restart the monitoring agent by
running the following command:
sudo service stackdriver-agent restart
Information on other plugin configuration options can be found at
collectd.org.

How to connect to remote WildFly using JMC?

I have a Linux server where I'm running WildFly 10. I work on a Windows machine and I want to profile the remote application server. I've checked that port 9990 is enabled for access via http by accessing http://<ip>:9990/console and via JMX access from the JConsole client that comes in WildFly. For the latter, I downloaded WildFly to my machine, went to %WILDFLY_PATH%\bin\jconsole.bat, accesed through service:jmx:http-remoting-jmx://<ip>:9990 and used my credentials, it works properly. Now I want to access vía JMC, but I cannot achieve it. I tried the following:
Copied jboss-client.jar libraries from %WILDFLY_PATH%\bin\client to %JDK_HOME%\lib\missioncontrol\dropins and start JMC.
Executed JMC from cmd and added -cp:a <location of jboss-client.jar> param, like this:
jmc.exe -cp:a "C:\Program Files\Java\jdk1.8.0_72\lib\missioncontrol\dropins\jboss-client.jar"
None of these worked.
I tried access with VisualVM and worked using the last approach but replaced jmc.exe by jvisualvm.exe and I connected to the external VM with no issues. I wonder if there's any way to achieve this using JMC.
Since jmc doesn't accept the -cp flag, you have to run like this:
jmc.exe -vmargs -Xbootclasspath/a:<location of jboss-client.jar>
Some more clues might be here: https://community.oracle.com/thread/2592885?tstart=0

How to use VisualVM and JMX?

I have tried every recipe in the book, but things just wont work today...
I am trying to use VisualVM to profile my Java app running in a remote server, so I googled and googled and googled for ways to do this and I end up with this solution:
java -Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9199 \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-jar bin/felix.jar
Running this will get me JMX to run I guess, so I can see him running on 9199:
java 21947 root 9u IPv6 1811434 0t0 TCP *:7192 (LISTEN)
java 26376 root 14u IPv6 1844518 0t0 TCP *:9199 (LISTEN)
Moreover, I can test that the port is visible on the web:
Now, when I try to open the connection in VisualVM in my machine (which can also ping the jmx server) this happens:
I must be so dumb, that everyone in this world was able to put this thing running but me. Damn...
EDIT: I installed wireshark to know what's going on under the hood, so I saw this. As soon as I add a remote IP in VisualVM wireshark starts detecting this repetitive activity:
However, if I try to add a new JMX connection and ask him to connect, wireshark will not grab even one single packet of that connection attempt.
This seems to me that VisualVM is not even trying to connect, despite giving the error message "Cannot connect"...!! What the hell is going on?
Start your service using these options:
-Djava.rmi.server.hostname=193.163.XXX.XXX
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9199
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Then you can use jvisualvm or jconsole with just the "193.163.XXX.XXX:9199" address.
Follow the below steps.
1) Go to remote machine open X11 forwarding,
2) Installed XMING in windows
3) Start visual VM in Remote machine the GUI will come in your windows xming.
4) Instead of IP use localhost and use same port number.
If above steps not working it means something is wrong with configuration.
If above steps working fine then go to iptables and ensure port 9199 open for outer world.
as well start the program with java -Djava.rmi.server.hostname=YOUR_IP
For more details refer this link
Please use the following JVM options :
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=<PORT> -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=<IP>
In the VisualVM use the following to connect:
service:jmx:rmi:///jndi/rmi:/<IP>:<PORT>/jmxrmi
Hopefully this will help.

How do I run my application as superuser from Eclipse?

I'm running in to an error when I try to run my server application from Eclipse. The error is java.net.BindException: Permission denied. I think this is because I am using port 443 to set up an SSL connection. I can get around this problem if I run my code on the command line using java and sudo. Is there a way to set up Eclipse so that when I hit the run button, my application is executed with sudo?
You can follow these steps to compile/debug applications as superuser.
Rename your java-application
sudo mv /usr/lib/jvm/java-6-openjdk/jre/bin/java /usr/lib/jvm/java-6-openjdk/jre/bin/java.ori
Create following script and store it as /usr/lib/jvm/java-6-openjdk/jre/bin/java
#!/bin/bash
# file: /usr/lib/jvm/java-6-openjdk/jre/bin/java
# descr: Starter for jdk. Runs jdk as root when
# cmd-line-arg "--run-as-root" is specified.
#
jre="/usr/lib/jvm/java-6-openjdk/jre/bin/java.ori"
run_as_root=false
args=
# Filter command-line argument
for arg in "$#"
do
case "$arg" in
--run-as-root) run_as_root=true
;;
*) args="$args $arg"
;;
esac
done
# Remove leading whitespaces
args=$(echo $args | sed -e 's/^[ \t]*//')
if $run_as_root
then
echo "WARNING: Running as root!"
gksu "$jre $args"
else
$jre $args
fi
Change the permissions to make it executable
sudo chmod 0755 /usr/lib/jvm/java-6-openjdk/jre/bin/java
Startup eclipse
Go to Window->Preferences->Java->Installed JREs
Duplicate java-6-openjdk to java-6-openjdk-root
Edit JRE and add "--run-as-root" as Default VM Argument
To run projects as root you need to follow these steps:
Go to Project->Properties->Java Build Path
Double-Click the JRE System Library and choose in Alternate JRE "java-6-openjdk-root"
Note: The idea is from http://www.eclipse.org/forums/index.php/mv/msg/87353/724852/#msg_724852
Assuming you are on Linux (*nix),
How about starting your eclipse session via a sudo command?
Such as
sudo ~/eclipse/eclipse
Now whatever you do from eclipse will have the sudo context?
As mentioned in this thread:
In order to open a port below 1024 on Unix/Linux systems you need to be
"root".
I also used the argument -Dorg.eclipse.equinox.http.jetty.port=8080 to change the listen port, but this seems to be ignored (according to the stacktrace)
Please use "-Dorg.osgi.service.http.port=8080".
As mentioned in HTTP Service:
org.osgi.service.http.port - specifies the port number to use for the http serving. The default value for this property is 80 (which requires root permission), as per the OSGi specification.
org.osgi.service.http.port.secure - specifies the port number to use for secure http serving. The default value for this property is 443 (which requires root permission), as per the OSGi specification.
Maybe if you try to modify that last property to a value above 1024 it could work without requiring any special privilege.
Another option would be to use iptables or ipfilter to forward port 80 to a port above 1024.
(Can someone contribute a link to a practical and easy-to-understand explanation ?)
A better answer, perhaps, if this serves your needs AND is possible, could be simple port redirection on your router.
Instead of trying to force your linux/unix to open a reserved port, when you are only developing this now (not installing) and you want to run it in a debugger,
set your router to redirect incoming (external) port 443 to a port that is more convenient for your current needs (say 4443).
I think most routers support this, and if yours doesn't it gives your mum a good christmas or birthday present idea!
I am writing C not Java but this should work in either case.
I use remote debug - define a "remote" connection to LOCALHOST which allows you to specify the user you will connect with, specify ROOT. Then define a Remote Application in debug configuration connection: LOCALHOST. Be sure to check "skip download to target path" at the bottom of the main tab as well as under the connection properties window.
You can use Remote Java Application mechanism for this.
Create Debug configuration for Remote Java Application
section in Run -> Debug configurations...
Set your project name
Choose Connection type as Standard (Socket Attach)
Configure Connection properties parameters for your binding
(for you it will be localhost and 443).
Set breakpoint in your app (e.g. at the beginning of the main method)
Run your app from terminal as superuser with following command: java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=443 MyApp
Hit debug button in Eclipse for early created Remote Java Application
You code should be stopped on breakpoint in Eclipse!
If you use External tools (Run menu/External tools or an icon next to the Run/Debug icons on the toolbar), you can use any scripts or whatever you like. The scripts may give you elevated rights, or whatever.
On the other hand, this way debugging the application can become very hard, as neither the Run nor Debug commands get associated with this External tool configuration. Maybe it is possible to connect the Eclipse debugger of the application, but I don't know, how that is possible.
You may go this way
create a Makefile with javac calls
add the following line:
setcap 'cap_net_admin=+ep' Server
configure sudo to allow your Eclipse user to run setcap.
So you will have a transparent debugging (no sudo wrapper - gdb ok).
Cons: it is a local security breach.
Solution:
put this to /opt/my-stupid-eclipse
#!/bin/sh
setcap 'cap_net_admin=+ep cap_net_raw=+ep' $1
chmod +x this script and whitelist it on sudo config.
username ALL=(ALL) NOPASSWD: /opt/my-stupid-eclipse
Add it to your makefile, specify path to your Server binary.
Now you have pretty strange but secure script, that cannot be changed by other users... and still a little breach for replacing Server binary with any malicious code, that will gain caps, so no filename check/stricts will help.. can $1 be contaminated with bash commands, no? Guess, no.

Categories