Skip to content

Commit 544e25b

Browse files
committed
New JMX applications added immediately, their connection resolved lazily (still experimental), dynamic updating JMX application descriptors, heartbeat fixes
1 parent fcd52a8 commit 544e25b

File tree

8 files changed

+248
-101
lines changed

8 files changed

+248
-101
lines changed

visualvm/application/src/org/graalvm/visualvm/application/Application.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,18 @@ public abstract class Application extends StatefulDataSource {
6666
* @param id unique identificator of the application.
6767
*/
6868
public Application(Host host, String id) {
69+
this(host, id, STATE_AVAILABLE);
70+
}
71+
72+
/**
73+
* Creates new instance of Application defined by a Host and unique identificator.
74+
*
75+
* @param host Host on which the application is running.
76+
* @param id unique identificator of the application.
77+
* @param state initial state of the application.
78+
*/
79+
protected Application(Host host, String id, int state) {
80+
super(state);
6981
if (host == null) throw new IllegalArgumentException("Host cannot be null"); // NOI18N
7082
if (id == null) throw new IllegalArgumentException("Application id cannot be null"); // NOI18N
7183
this.host = host;

visualvm/application/src/org/graalvm/visualvm/application/ApplicationDescriptor.java

Lines changed: 79 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@
3434
import java.beans.PropertyChangeEvent;
3535
import java.beans.PropertyChangeListener;
3636
import java.beans.PropertyChangeSupport;
37+
import org.graalvm.visualvm.core.datasupport.Stateful;
38+
import org.graalvm.visualvm.core.datasupport.Utils;
3739

3840
/**
3941
* DataSourceDescriptor for Application.
4042
*
4143
* @author Jiri Sedlacek
4244
*/
43-
public class ApplicationDescriptor extends DataSourceDescriptor<Application> {
45+
public class ApplicationDescriptor extends DataSourceDescriptor<Application> implements PropertyChangeListener {
4446

4547
private static final String DISPLAY_NAME_PROPERTY = "-Dvisualvm.display.name="; // NOI18N
4648

@@ -49,6 +51,9 @@ public class ApplicationDescriptor extends DataSourceDescriptor<Application> {
4951

5052

5153
private String name;
54+
55+
private ApplicationType type;
56+
5257

5358
/**
5459
* Creates new instance of Application Descriptor.
@@ -73,38 +78,13 @@ protected ApplicationDescriptor(Application application, int preferredPosition)
7378
preferredPosition);
7479
}
7580

76-
private ApplicationDescriptor(final Application application, final ApplicationType type,
77-
int preferredPosition) {
78-
super(application, resolveApplicationName(application, type), type.getDescription(),
79-
type.getIcon(), preferredPosition, EXPAND_ON_EACH_FIRST_CHILD);
81+
protected ApplicationDescriptor(final Application application, final ApplicationType type, int preferredPosition) {
82+
super(application, resolveApplicationName(application, type), resolveApplicationDescription(application, type),
83+
resolveApplicationIcon(application, type), preferredPosition, EXPAND_ON_EACH_FIRST_CHILD);
84+
8085
name = super.getName();
81-
type.addPropertyChangeListener(new PropertyChangeListener() {
82-
public void propertyChange(PropertyChangeEvent evt) {
83-
String propertyName = evt.getPropertyName();
84-
if (ApplicationType.PROPERTY_NAME.equals(propertyName)) {
85-
// Name already customized by the user, do not change it
86-
if (resolveName(application, null) != null) return;
87-
88-
if (supportsRename()) {
89-
// Descriptor supports renaming, use setName(), sync name
90-
setName((String)evt.getNewValue());
91-
name = ApplicationDescriptor.super.getName();
92-
} else {
93-
// Descriptor doesn't support renaming, set name for overriden getName()
94-
String oldName = name;
95-
name = formatName(createGenericName(application, type.getName()));
96-
PropertyChangeSupport pcs = ApplicationDescriptor.this.getChangeSupport();
97-
pcs.firePropertyChange(PROPERTY_NAME, oldName, name);
98-
}
99-
} else if (ApplicationType.PROPERTY_ICON.equals(propertyName)) {
100-
setIcon((Image)evt.getNewValue());
101-
} else if (ApplicationType.PROPERTY_DESCRIPTION.equals(propertyName)) {
102-
setDescription((String)evt.getNewValue());
103-
} else if (ApplicationType.PROPERTY_VERSION.equals(propertyName)) {
104-
// Not supported by ApplicationDescriptor
105-
}
106-
}
107-
});
86+
87+
setApplicationType(type);
10888
}
10989

11090
public String getName() {
@@ -115,6 +95,50 @@ public String getName() {
11595
public boolean providesProperties() {
11696
return true;
11797
}
98+
99+
100+
protected void setApplicationType(ApplicationType type) {
101+
if (this.type != null) this.type.removePropertyChangeListener(this);
102+
103+
this.type = type;
104+
105+
this.type.addPropertyChangeListener(this);
106+
}
107+
108+
protected ApplicationType getApplicationType() {
109+
return type;
110+
}
111+
112+
113+
@Override
114+
public void propertyChange(PropertyChangeEvent evt) {
115+
String propertyName = evt.getPropertyName();
116+
if (ApplicationType.PROPERTY_NAME.equals(propertyName)) {
117+
Application application = getDataSource();
118+
119+
// Name already customized by the user, do not change it
120+
if (resolveName(application, null) != null) return;
121+
122+
if (supportsRename()) {
123+
// Descriptor supports renaming, use setName(), sync name
124+
setName((String)evt.getNewValue());
125+
name = ApplicationDescriptor.super.getName();
126+
} else {
127+
// Descriptor doesn't support renaming, set name for overriden getName()
128+
String oldName = name;
129+
name = formatName(createGenericName(application, type.getName()));
130+
PropertyChangeSupport pcs = ApplicationDescriptor.this.getChangeSupport();
131+
pcs.firePropertyChange(PROPERTY_NAME, oldName, name);
132+
}
133+
} else if (ApplicationType.PROPERTY_ICON.equals(propertyName)) {
134+
setIcon((Image)evt.getNewValue());
135+
} else if (ApplicationType.PROPERTY_DESCRIPTION.equals(propertyName)) {
136+
setDescription((String)evt.getNewValue());
137+
} else if (ApplicationType.PROPERTY_VERSION.equals(propertyName)) {
138+
// Not supported by ApplicationDescriptor
139+
}
140+
}
141+
118142

119143
/**
120144
* Returns Application name if available in Snapshot Storage as PROPERTY_NAME
@@ -140,9 +164,9 @@ protected static String resolveApplicationName(Application application, Applicat
140164
return createGenericName(application, type.getName());
141165
}
142166

143-
private static String resolveCustomName(Application application) {
144-
Jvm jvm = JvmFactory.getJVMFor(application);
145-
if (jvm.isBasicInfoSupported()) {
167+
protected static String resolveCustomName(Application application) {
168+
Jvm jvm = application.getState() == Stateful.STATE_AVAILABLE ? JvmFactory.getJVMFor(application) : null;
169+
if (jvm != null && jvm.isBasicInfoSupported()) {
146170
String args = jvm.getJvmArgs();
147171
int propIndex = args.indexOf(DISPLAY_NAME_PROPERTY);
148172

@@ -171,11 +195,29 @@ protected String formatName(String namePattern) {
171195
return formatted;
172196
}
173197

174-
private static String createGenericName(Application application, String nameBase) {
198+
protected static String createGenericName(Application application, String nameBase) {
175199
int pid = application.getPid();
176200
String id = Application.CURRENT_APPLICATION.getPid() == pid ||
177-
pid == Application.UNKNOWN_PID ? "" : " (pid " + pid + ")"; // NOI18N
201+
pid == Application.UNKNOWN_PID ? "" : PID_PARAM; // NOI18N
178202
return nameBase + id;
179203
}
180204

205+
206+
protected static String resolveApplicationDescription(Application application, ApplicationType type) {
207+
String persistedDescription = application.getStorage().getCustomProperty(PROPERTY_DESCRIPTION);
208+
if (persistedDescription != null) return persistedDescription;
209+
210+
return type.getDescription();
211+
}
212+
213+
protected static Image resolveApplicationIcon(Application application, ApplicationType type) {
214+
String persistedIconString = application.getStorage().getCustomProperty(PROPERTY_ICON);
215+
if (persistedIconString != null) {
216+
Image persistedIcon = Utils.stringToImage(persistedIconString);
217+
if (persistedIcon != null) return persistedIcon;
218+
}
219+
220+
return type.getIcon();
221+
}
222+
181223
}

visualvm/application/src/org/graalvm/visualvm/application/type/DefaultApplicationType.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.graalvm.visualvm.application.jvm.Jvm;
3030
import org.graalvm.visualvm.application.jvm.JvmFactory;
3131
import java.awt.Image;
32+
import org.graalvm.visualvm.core.datasupport.Stateful;
3233
import org.openide.util.ImageUtilities;
3334
import org.openide.util.NbBundle;
3435

@@ -41,12 +42,13 @@
4142
*
4243
* @author Tomas Hurka
4344
* @author Luis-Miguel Alventosa
45+
* @author Jiri Sedlacek
4446
*/
45-
public class DefaultApplicationType extends ApplicationType {
47+
public class DefaultApplicationType extends ApplicationType {
4648
String name;
4749
Application application;
4850

49-
DefaultApplicationType(Application app) {
51+
protected DefaultApplicationType(Application app) {
5052
application = app;
5153
}
5254

@@ -58,11 +60,14 @@ public class DefaultApplicationType extends ApplicationType {
5860
*/
5961
public String getName() {
6062
if (name == null) {
61-
Jvm jvm = JvmFactory.getJVMFor(application);
6263
String mainClassName = null;
63-
if (jvm.isBasicInfoSupported()) {
64-
mainClassName = jvm.getMainClass();
64+
if (Stateful.STATE_AVAILABLE == application.getState()) {
65+
Jvm jvm = JvmFactory.getJVMFor(application);
66+
if (jvm.isBasicInfoSupported()) {
67+
mainClassName = jvm.getMainClass();
68+
}
6569
}
70+
6671
if (mainClassName != null && mainClassName.length() > 0) {
6772
name = mainClassName;
6873
} else {

visualvm/core/src/org/graalvm/visualvm/core/datasource/StatefulDataSource.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,17 @@
3333
*/
3434
public abstract class StatefulDataSource extends DataSource implements Stateful {
3535

36-
private int state = STATE_AVAILABLE;
36+
private int state = STATE_UNKNOWN;
3737
private int modCount;
3838
private final Object stateLock = new Object();
39+
40+
protected StatefulDataSource() {
41+
this(STATE_AVAILABLE);
42+
}
43+
44+
protected StatefulDataSource(int state) {
45+
this.state = state;
46+
}
3947

4048
public final int getState() {
4149
synchronized (stateLock) {

visualvm/core/src/org/graalvm/visualvm/core/datasource/descriptor/DataSourceDescriptor.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,20 @@ public boolean supportsRename() {
155155
* @param newName DataSource name.
156156
*/
157157
public void setName(String newName) {
158+
setNameImpl(newName, PROPERTY_NAME);
159+
}
160+
161+
protected void setImplicitName(String newName, String propertyName) {
162+
setNameImpl(newName, propertyName);
163+
}
164+
165+
private void setNameImpl(String newName, String propertyName) {
158166
if (!supportsRename()) throw new UnsupportedOperationException("Rename not supported for this descriptor"); // NOI18N
159167
if (newName == null) throw new IllegalArgumentException("Name cannot be null"); // NOI18N
160168
String oldName = name;
161169
name = formatName(newName);
162-
getDataSource().getStorage().setCustomProperties(new String[] { PROPERTY_NAME }, new String[] { newName });
163-
getChangeSupport().firePropertyChange(PROPERTY_NAME, oldName, name);
170+
if (propertyName != null) getDataSource().getStorage().setCustomProperty(propertyName, newName);
171+
getChangeSupport().firePropertyChange(PROPERTY_NAME, oldName, getName());
164172
}
165173

166174
/**
@@ -309,20 +317,20 @@ protected void setDescription(String newDescription) {
309317
if (description == null && newDescription == null) return;
310318
String oldDescription = description;
311319
description = newDescription;
312-
getChangeSupport().firePropertyChange(PROPERTY_DESCRIPTION, oldDescription, newDescription);
320+
getChangeSupport().firePropertyChange(PROPERTY_DESCRIPTION, oldDescription, getDescription());
313321
}
314322

315323
protected void setIcon(Image newIcon) {
316324
if (icon == null && newIcon == null) return;
317325
Image oldIcon = icon;
318326
icon = newIcon;
319-
getChangeSupport().firePropertyChange(PROPERTY_ICON, oldIcon, newIcon);
327+
getChangeSupport().firePropertyChange(PROPERTY_ICON, oldIcon, getIcon());
320328
}
321329

322330
protected void setPreferredPosition(int newPosition) {
323331
int oldPosition = preferredPosition;
324332
preferredPosition = newPosition;
325-
getChangeSupport().firePropertyChange(PROPERTY_PREFERRED_POSITION, oldPosition, newPosition);
333+
getChangeSupport().firePropertyChange(PROPERTY_PREFERRED_POSITION, oldPosition, getPreferredPosition());
326334
}
327335

328336
/**
@@ -336,13 +344,13 @@ protected void setPreferredPosition(int newPosition) {
336344
protected void setChildrenComparator(Comparator<DataSource> newComparator) {
337345
Comparator<DataSource> oldComparator = childrenComparator;
338346
childrenComparator = newComparator;
339-
getChangeSupport().firePropertyChange(PROPERTY_CHILDREN_COMPARATOR, oldComparator, newComparator);
347+
getChangeSupport().firePropertyChange(PROPERTY_CHILDREN_COMPARATOR, oldComparator, getChildrenComparator());
340348
}
341349

342350
protected void getAutoExpansionPolicy(int newPolicy) {
343351
int oldPolicy = autoExpansionPolicy;
344352
autoExpansionPolicy = newPolicy;
345-
getChangeSupport().firePropertyChange(PROPERTY_EXPANSION_POLICY, oldPolicy, newPolicy);
353+
getChangeSupport().firePropertyChange(PROPERTY_EXPANSION_POLICY, oldPolicy, getAutoExpansionPolicy());
346354
}
347355

348356
protected final PropertyChangeSupport getChangeSupport() {

visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxApplication.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public final class JmxApplication extends Application {
6060
// Note: storage may be null, in this case the JmxApplication isn't persistent
6161
// and creates a temporary storage just like any other regular Application
6262
public JmxApplication(Host host, JMXServiceURL url, EnvironmentProvider envProvider, Storage storage) {
63-
super(host, createId(url, envProvider, storage));
63+
super(host, createId(url, envProvider, storage), STATE_UNAVAILABLE);
6464
this.url = url;
6565
this.envProvider = envProvider;
6666
this.storage = storage;
@@ -76,7 +76,7 @@ public EnvironmentProvider getEnvironmentProvider() {
7676
}
7777

7878
public int getPid() {
79-
if (pid == UNKNOWN_PID) {
79+
if (pid == UNKNOWN_PID && getState() == Stateful.STATE_AVAILABLE) {
8080
JmxModel jmxModel = JmxModelFactory.getJmxModelFor(this);
8181
if (jmxModel != null && jmxModel.getConnectionState() == ConnectionState.CONNECTED) {
8282
JvmMXBeans mxbeans = JvmMXBeansFactory.getJvmMXBeans(jmxModel);

0 commit comments

Comments
 (0)