Merge pull request #4032 from apache/delivery
Sync delivery to release140 for 14-rc2
diff --git a/ide/libs.truffleapi/nbproject/project.xml b/ide/libs.truffleapi/nbproject/project.xml
index 75db006..7fa76b7 100644
--- a/ide/libs.truffleapi/nbproject/project.xml
+++ b/ide/libs.truffleapi/nbproject/project.xml
@@ -38,6 +38,7 @@
<package>com.oracle.truffle.api</package>
<package>com.oracle.truffle.api.debug</package>
<package>com.oracle.truffle.api.dsl</package>
+ <package>com.oracle.truffle.api.exception</package>
<package>com.oracle.truffle.api.frame</package>
<package>com.oracle.truffle.api.instrumentation</package>
<package>com.oracle.truffle.api.interop</package>
diff --git a/ide/lsp.client/src/org/netbeans/modules/lsp/client/Utils.java b/ide/lsp.client/src/org/netbeans/modules/lsp/client/Utils.java
index 9301f0a..f1de037 100644
--- a/ide/lsp.client/src/org/netbeans/modules/lsp/client/Utils.java
+++ b/ide/lsp.client/src/org/netbeans/modules/lsp/client/Utils.java
@@ -195,7 +195,9 @@
if (cmd.isLeft()) {
command = cmd.getLeft();
} else {
- Utils.applyWorkspaceEdit(cmd.getRight().getEdit());
+ if(cmd.getRight().getEdit() != null) {
+ Utils.applyWorkspaceEdit(cmd.getRight().getEdit());
+ }
command = cmd.getRight().getCommand();
}
if (command != null) {
diff --git a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LanguageClientImpl.java b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LanguageClientImpl.java
index 0fada4a..80c53ce 100644
--- a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LanguageClientImpl.java
+++ b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LanguageClientImpl.java
@@ -20,7 +20,6 @@
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
-import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -30,16 +29,14 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import javax.swing.SwingUtilities;
-import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
-import javax.swing.text.StyledDocument;
import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
import org.eclipse.lsp4j.ApplyWorkspaceEditResponse;
import org.eclipse.lsp4j.CodeAction;
@@ -51,21 +48,20 @@
import org.eclipse.lsp4j.ConfigurationParams;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
-import org.eclipse.lsp4j.ExecuteCommandParams;
import org.eclipse.lsp4j.MessageActionItem;
import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.lsp4j.MessageType;
import org.eclipse.lsp4j.ProgressParams;
import org.eclipse.lsp4j.PublishDiagnosticsParams;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.ShowMessageRequestParams;
import org.eclipse.lsp4j.TextDocumentIdentifier;
-import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.WorkDoneProgressBegin;
import org.eclipse.lsp4j.WorkDoneProgressCreateParams;
import org.eclipse.lsp4j.WorkDoneProgressEnd;
import org.eclipse.lsp4j.WorkDoneProgressNotification;
import org.eclipse.lsp4j.WorkDoneProgressReport;
-import org.eclipse.lsp4j.WorkspaceEdit;
+import org.eclipse.lsp4j.jsonrpc.Endpoint;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.lsp4j.services.LanguageClient;
import org.netbeans.api.progress.*;
@@ -78,19 +74,20 @@
import org.netbeans.spi.editor.hints.HintsController;
import org.netbeans.spi.editor.hints.LazyFixList;
import org.netbeans.spi.editor.hints.Severity;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.NotifyDescriptor.QuickPick.Item;
import org.openide.cookies.EditorCookie;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.URLMapper;
-import org.openide.text.NbDocument;
import org.openide.util.Exceptions;
-import org.openide.util.NbBundle.Messages;
import org.openide.util.RequestProcessor;
/**
*
* @author lahvac
*/
-public class LanguageClientImpl implements LanguageClient {
+public class LanguageClientImpl implements LanguageClient, Endpoint {
private static final Logger LOG = Logger.getLogger(LanguageClientImpl.class.getName());
private static final RequestProcessor WORKER = new RequestProcessor(LanguageClientImpl.class.getName(), 1, false, false);
@@ -192,18 +189,86 @@
@Override
public void showMessage(MessageParams arg0) {
- System.err.println("showMessage: " + arg0);
+ int messageType;
+
+ switch (Optional.ofNullable(arg0.getType()).orElse(MessageType.Log)) {
+ default:
+ case Log:
+ case Info:
+ messageType = NotifyDescriptor.INFORMATION_MESSAGE;
+ break;
+ case Warning:
+ messageType = NotifyDescriptor.WARNING_MESSAGE;
+ break;
+ case Error:
+ messageType = NotifyDescriptor.ERROR_MESSAGE;
+ break;
+ }
+
+ NotifyDescriptor nd = new NotifyDescriptor.Message(
+ arg0.getMessage(),
+ messageType
+ );
+
+ DialogDisplayer.getDefault().notifyLater(nd);
}
@Override
public CompletableFuture<MessageActionItem> showMessageRequest(ShowMessageRequestParams arg0) {
- System.err.println("showMessageRequest");
- return null; //???
+ int messageType;
+
+ switch (Optional.ofNullable(arg0.getType()).orElse(MessageType.Log)) {
+ default:
+ case Log:
+ case Info:
+ messageType = NotifyDescriptor.INFORMATION_MESSAGE;
+ break;
+ case Warning:
+ messageType = NotifyDescriptor.WARNING_MESSAGE;
+ break;
+ case Error:
+ messageType = NotifyDescriptor.ERROR_MESSAGE;
+ break;
+ }
+
+ NotifyDescriptor.QuickPick nd = new NotifyDescriptor.QuickPick(
+ arg0.getMessage(),
+ "Please select",
+ arg0.getActions().stream()
+ .map(mai -> new Item(mai.getTitle(), mai.getTitle()))
+ .collect(Collectors.toList())
+ ,
+ false
+ );
+
+ nd.setMessageType(messageType);
+
+ return DialogDisplayer.getDefault()
+ .notifyFuture(nd)
+ .thenApply(nd2 -> {
+ return new MessageActionItem(
+ nd2.getItems().stream()
+ .filter(i -> i.isSelected())
+ .findFirst()
+ .map(i -> i.getLabel())
+ .orElse(""));
+ });
}
@Override
public void logMessage(MessageParams arg0) {
- System.err.println("logMessage: " + arg0);
+ switch (Optional.ofNullable(arg0.getType()).orElse(MessageType.Log)) {
+ case Log:
+ case Info:
+ LOG.info(arg0.getMessage());
+ break;
+ case Warning:
+ LOG.warning(arg0.getMessage());
+ break;
+ case Error:
+ LOG.severe(arg0.getMessage());
+ break;
+ }
}
@Override
@@ -219,6 +284,15 @@
return result;
}
+ public CompletableFuture<?> request(String method, Object parameter) {
+ LOG.log(Level.WARNING, "Received unhandled request: {0}: {1}", new Object[] {method, parameter});
+ return CompletableFuture.completedFuture(null);
+ }
+
+ public void notify(String method, Object parameter) {
+ LOG.log(Level.WARNING, "Received unhandled notification: {0}: {1}", new Object[] {method, parameter});
+ }
+
private final class DiagnosticFixList implements LazyFixList {
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
diff --git a/java/java.lsp.server/nbcode/nbproject/platform.properties b/java/java.lsp.server/nbcode/nbproject/platform.properties
index 608720b..d48788b 100644
--- a/java/java.lsp.server/nbcode/nbproject/platform.properties
+++ b/java/java.lsp.server/nbcode/nbproject/platform.properties
@@ -30,7 +30,6 @@
disabled.modules=\
bcpg,\
com.googlecode.javaewah.JavaEWAH,\
- libs.c.kohlschutter.junixsocket,\
org.apache.commons.lang,\
org.apache.ws.commons.util,\
org.apache.xmlrpc,\
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/Utils.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/Utils.java
index a3561e6..0b1afcc 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/Utils.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/Utils.java
@@ -32,6 +32,7 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Locale;
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
@@ -337,4 +338,45 @@
return encoded.substring(2, encoded.length() - 2);
}
+ /**
+ * Simple conversion from HTML to plaintext. Removes all html tags incl. attributes,
+ * replaces BR, P and HR tags with newlines.
+ * @param s html text
+ * @return plaintext
+ */
+ public static String html2plain(String s) {
+ boolean inTag = false;
+ int tagStart = -1;
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ if (inTag) {
+ boolean alpha = Character.isAlphabetic(ch);
+ if (tagStart > 0 && !alpha) {
+ String t = s.substring(tagStart, i).toLowerCase(Locale.ENGLISH);
+ switch (t) {
+ case "br": case "p": case "hr": // NOI1N
+ sb.append("\n");
+ break;
+ }
+ // prevent entering tagstart state again
+ tagStart = -2;
+ }
+ if (ch == '>') { // NOI18N
+ inTag = false;
+ } else if (tagStart == -1 && alpha) {
+ tagStart = i;
+ }
+ } else {
+ if (ch == '<') { // NOI18N
+ tagStart = -1;
+ inTag = true;
+ continue;
+ }
+ sb.append(ch);
+ }
+ }
+ return sb.toString();
+ }
+
}
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/project/ProjectAlertPresenter.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/project/ProjectAlertPresenter.java
index 0482e7c..035d796 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/project/ProjectAlertPresenter.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/project/ProjectAlertPresenter.java
@@ -39,6 +39,7 @@
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectInformation;
import org.netbeans.api.project.ProjectUtils;
+import org.netbeans.modules.java.lsp.server.Utils;
import org.netbeans.spi.project.ui.ProjectProblemsProvider;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
@@ -489,7 +490,7 @@
// hack: the LSP protocol does not support title. Until fixed, or implemented through a custom message,
// embed the title into description:
String title = Bundle.ProjectProblem_Title(projectName, p.getDisplayName());
- NotifyDescriptor msg = new NotifyDescriptor(title + ": " + p.getDescription(), title, NotifyDescriptor.DEFAULT_OPTION, type, new Object[]{NotifyDescriptor.OK_OPTION}, null);
+ NotifyDescriptor msg = new NotifyDescriptor(title + ": " + Utils.html2plain(p.getDescription()), title, NotifyDescriptor.DEFAULT_OPTION, type, new Object[]{NotifyDescriptor.OK_OPTION}, null);
// Note: the number of 'fatal' dialogs displayed at the same time is limited by the RP throughput. Dialog API does not support CompletableFuture<> interface
// so threads may dangle.
@@ -647,7 +648,7 @@
}
String title = Bundle.ProjectProblems_Fixable_Title(projectName, ref.problem.getDisplayName());
- String msg = ref.problem.getDescription();
+ String msg = Utils.html2plain(ref.problem.getDescription());
if (probs.size() > 1) {
msg = Bundle.ProjectProblems_Additional(probs.size() - 1, msg);
}
@@ -739,7 +740,7 @@
}, RESOLVE_RP).thenApply(r -> {
if (r.isResolved()) {
if (r.getMessage() != null) {
- StatusDisplayer.getDefault().setStatusText(r.getMessage());
+ StatusDisplayer.getDefault().setStatusText(Utils.html2plain(r.getMessage()));
}
return ctx.autoResolve ? r : null;
}
@@ -764,18 +765,19 @@
});
return f;
}
-
+
private NotifyDescriptor createNotifyDescriptor(ProjectProblemsProvider.ProjectProblem pp, ProjectProblemsProvider.Result r, int probs) {
String title;
String msg;
int type;
+ String plainMessage = Utils.html2plain(r.getMessage());
if (r.getStatus() == ProjectProblemsProvider.Status.UNRESOLVED) {
title = Bundle.ProjectProblems_Resolved_Error(projectName);
- msg = Bundle.ProjectProblems_Resolved_ErrorMessage1(pp.getDisplayName(), r.getMessage());
+ msg = Bundle.ProjectProblems_Resolved_ErrorMessage1(pp.getDisplayName(), plainMessage);
type = NotifyDescriptor.ERROR_MESSAGE;
} else {
title = Bundle.ProjectProblems_Resolved_Warning(projectName);
- msg = Bundle.ProjectProblems_Resolved_WarningMessage1(pp.getDisplayName(), r.getMessage());
+ msg = Bundle.ProjectProblems_Resolved_WarningMessage1(pp.getDisplayName(), plainMessage);
type = NotifyDescriptor.WARNING_MESSAGE;
}
if (probs > 0) {
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java b/java/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java
index d35cf64..a019f79 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java
@@ -690,6 +690,11 @@
//likely a duplicate of another class, don't touch:
return null;
}
+ if (isOtherClass(csym)) {
+ // Something went somewhere the csym.type is Type.Unknown,
+ // do not go any further
+ return null;
+ }
currentClass = csym;
Type.ClassType ct = (Type.ClassType) csym.type;
if (csym == syms.objectType.tsym) {
@@ -1049,9 +1054,14 @@
}
return isErroneousClass(((JCClassDecl) tree).sym);
}
+
private boolean isErroneousClass(Element el) {
return el instanceof ClassSymbol && (((ClassSymbol) el).asType() == null || ((ClassSymbol) el).asType().getKind() == TypeKind.ERROR);
}
+ private boolean isOtherClass(Element el) {
+ return el instanceof ClassSymbol && (((ClassSymbol) el).asType() == null || ((ClassSymbol) el).asType().getKind() == TypeKind.OTHER);
+ }
+
public static Function<Diagnostic<?>, String> DIAGNOSTIC_TO_TEXT = d -> d.getMessage(null);
}
diff --git a/java/java.sourceui/src/org/netbeans/api/java/source/ui/ElementJavadoc.java b/java/java.sourceui/src/org/netbeans/api/java/source/ui/ElementJavadoc.java
index 1e844f3..1a1b252 100644
--- a/java/java.sourceui/src/org/netbeans/api/java/source/ui/ElementJavadoc.java
+++ b/java/java.sourceui/src/org/netbeans/api/java/source/ui/ElementJavadoc.java
@@ -394,7 +394,8 @@
this.fileObject = compilationInfo.getFileObject();
this.handle = element == null ? null : ElementHandle.create(element);
this.cancel = cancel;
- this.packageName = compilationInfo.getCompilationUnit().getPackageName().toString();
+ this.packageName = compilationInfo.getCompilationUnit().getPackageName() != null ? compilationInfo.getCompilationUnit().getPackageName().toString()
+ : "";
this.imports = compilationInfo.getCompilationUnit().getImports();
this.className = compilationInfo.getCompilationUnit().getSourceFile().getName().replaceFirst("[.][^.]+$", "");
diff --git a/java/libs.nbjavacapi/manifest.mf b/java/libs.nbjavacapi/manifest.mf
index b89c4e5..b43812f 100644
--- a/java/libs.nbjavacapi/manifest.mf
+++ b/java/libs.nbjavacapi/manifest.mf
@@ -2,7 +2,7 @@
AutoUpdate-Show-In-Client: true
OpenIDE-Module: org.netbeans.libs.nbjavacapi
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/nbjavac/api/Bundle.properties
-OpenIDE-Module-Specification-Version: 17.1
+OpenIDE-Module-Specification-Version: 18.0
OpenIDE-Module-Hide-Classpath-Packages: com.sun.javadoc.**, com.sun.source.**, javax.annotation.processing.**, javax.lang.model.**, javax.tools.**, com.sun.tools.javac.** com.sun.tools.javac.**, com.sun.tools.javadoc.**, com.sun.tools.javap.**, com.sun.tools.classfile.**, com.sun.tools.doclint.**
OpenIDE-Module-Fragment-Host: org.netbeans.libs.javacapi
OpenIDE-Module-Provides: org.netbeans.libs.nbjavac
diff --git a/java/libs.nbjavacapi/src/org/netbeans/modules/nbjavac/api/Bundle.properties b/java/libs.nbjavacapi/src/org/netbeans/modules/nbjavac/api/Bundle.properties
index 536a074..c5c441a 100644
--- a/java/libs.nbjavacapi/src/org/netbeans/modules/nbjavac/api/Bundle.properties
+++ b/java/libs.nbjavacapi/src/org/netbeans/modules/nbjavac/api/Bundle.properties
@@ -18,6 +18,6 @@
OpenIDE-Module-Display-Category=Java
OpenIDE-Module-Long-Description=\
This library provides a Java language parser for the IDE. \
- Supports JDK-17 features.
+ Supports JDK-18 features.
OpenIDE-Module-Name=The nb-javac Java editing support library
OpenIDE-Module-Short-Description=The nb-javac Java editing support library
diff --git a/nbbuild/notice-stub.txt b/nbbuild/notice-stub.txt
index e0ce5df..48bff50 100644
--- a/nbbuild/notice-stub.txt
+++ b/nbbuild/notice-stub.txt
@@ -1,5 +1,5 @@
Apache NetBeans
-Copyright 2017-2021 The Apache Software Foundation
+Copyright 2017-2022 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
diff --git a/platform/core.network/src/org/netbeans/core/network/proxy/NbProxySelector.java b/platform/core.network/src/org/netbeans/core/network/proxy/NbProxySelector.java
index 8143984..f83ac1b 100644
--- a/platform/core.network/src/org/netbeans/core/network/proxy/NbProxySelector.java
+++ b/platform/core.network/src/org/netbeans/core/network/proxy/NbProxySelector.java
@@ -55,7 +55,7 @@
original = ProxySelector.getDefault();
LOG.log(Level.FINE, "java.net.useSystemProxies has been set to {0}", useSystemProxies());
if (original == null || original.getClass().getName().equals(DEFAULT_PROXY_SELECTOR_CLASS_NAME)) {
- NetworkProxyReloader.reloadNetworkProxy();
+ RP.post(() -> NetworkProxyReloader.reloadNetworkProxy());
}
ProxySettings.addPreferenceChangeListener(new ProxySettingsListener());
copySettingsToSystem();
diff --git a/platform/sampler/nbproject/project.properties b/platform/sampler/nbproject/project.properties
index 6a8c641..4c6597b 100644
--- a/platform/sampler/nbproject/project.properties
+++ b/platform/sampler/nbproject/project.properties
@@ -16,6 +16,6 @@
# under the License.
is.autoload=true
javac.source=1.8
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.compilerargs=-Xlint -Xlint:-serial -Werror
javadoc.arch=${basedir}/arch.xml
javadoc.apichanges=${basedir}/apichanges.xml
diff --git a/platform/sampler/nbproject/project.xml b/platform/sampler/nbproject/project.xml
index fc081e9..aad0da5 100644
--- a/platform/sampler/nbproject/project.xml
+++ b/platform/sampler/nbproject/project.xml
@@ -44,14 +44,6 @@
</run-dependency>
</dependency>
<dependency>
- <code-name-base>org.netbeans.api.progress.nb</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>1.40</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
<code-name-base>org.openide.awt</code-name-base>
<build-prerequisite/>
<compile-dependency/>
@@ -60,14 +52,6 @@
</run-dependency>
</dependency>
<dependency>
- <code-name-base>org.openide.dialogs</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.24</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
<code-name-base>org.openide.filesystems</code-name-base>
<build-prerequisite/>
<compile-dependency/>
@@ -76,14 +60,6 @@
</run-dependency>
</dependency>
<dependency>
- <code-name-base>org.openide.loaders</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.61</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
<code-name-base>org.openide.modules</code-name-base>
<build-prerequisite/>
<compile-dependency/>
@@ -92,22 +68,6 @@
</run-dependency>
</dependency>
<dependency>
- <code-name-base>org.openide.nodes</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>7.26</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
- <code-name-base>org.openide.util.ui</code-name-base>
- <build-prerequisite/>
- <compile-dependency/>
- <run-dependency>
- <specification-version>9.3</specification-version>
- </run-dependency>
- </dependency>
- <dependency>
<code-name-base>org.openide.util</code-name-base>
<build-prerequisite/>
<compile-dependency/>
diff --git a/platform/sampler/src/org/netbeans/modules/sampler/CLISampler.java b/platform/sampler/src/org/netbeans/modules/sampler/CLISampler.java
index b9a55b4..d262439 100644
--- a/platform/sampler/src/org/netbeans/modules/sampler/CLISampler.java
+++ b/platform/sampler/src/org/netbeans/modules/sampler/CLISampler.java
@@ -98,7 +98,7 @@
System.exit(0);
}
- private CLISampler(ThreadMXBean threadBean, File out) {
+ CLISampler(ThreadMXBean threadBean, File out) {
super("CLISampler");
threadMXBean = threadBean;
output = out;
@@ -111,9 +111,9 @@
@Override
protected void saveSnapshot(byte[] arr) throws IOException {
- FileOutputStream os = new FileOutputStream(output);
- os.write(arr);
- os.close();
+ try (FileOutputStream os = new FileOutputStream(output)) {
+ os.write(arr);
+ }
}
@Override
diff --git a/platform/sampler/src/org/netbeans/modules/sampler/InternalSampler.java b/platform/sampler/src/org/netbeans/modules/sampler/InternalSampler.java
index 8e8d3bf..9391891 100644
--- a/platform/sampler/src/org/netbeans/modules/sampler/InternalSampler.java
+++ b/platform/sampler/src/org/netbeans/modules/sampler/InternalSampler.java
@@ -30,12 +30,8 @@
import java.util.logging.Logger;
import org.netbeans.api.actions.Openable;
import org.netbeans.api.progress.ProgressHandle;
-import org.netbeans.api.progress.ProgressHandleFactory;
-import org.openide.DialogDisplayer;
-import org.openide.NotifyDescriptor;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
-import org.openide.loaders.DataObject;
import org.openide.modules.Places;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;
@@ -48,7 +44,6 @@
final class InternalSampler extends Sampler {
private static final String SAMPLER_NAME = "selfsampler"; // NOI18N
private static final String FILE_NAME = SAMPLER_NAME+SamplesOutputStream.FILE_EXT;
- private static final String UNKNOWN_MIME_TYPE = "content/unknown"; // NOI18N
private static final String X_DEBUG_ARG = "-Xdebug"; // NOI18N
private static final String JDWP_DEBUG_ARG = "-agentlib:jdwp"; // NOI18N
private static final String JDWP_DEBUG_ARG_PREFIX = "-agentlib:jdwp="; // NOI18N
@@ -59,7 +54,7 @@
private ProgressHandle progress;
static InternalSampler createInternalSampler(String key) {
- if (SamplesOutputStream.isSupported() && isRunMode()) {
+ if (isRunMode()) {
return new InternalSampler(key);
}
return null;
@@ -112,8 +107,9 @@
return runMode;
}
- InternalSampler(String thread) {
+ InternalSampler(String thread) throws LinkageError {
super(thread);
+ progress = ProgressHandle.createHandle(Save_Progress());
}
@Override
@@ -122,7 +118,10 @@
}
@Override
- @Messages("SelfSamplerAction_SavedFile=Snapshot was saved to {0}")
+ @Messages({
+ "# {0} - the file",
+ "SelfSamplerAction_SavedFile=Snapshot was saved to {0}"
+ })
protected void saveSnapshot(byte[] arr) throws IOException { // save snapshot
File outFile = File.createTempFile(SAMPLER_NAME, SamplesOutputStream.FILE_EXT);
File userDir = Places.getUserDirectory();
@@ -142,12 +141,15 @@
// open snapshot
FileObject fo = fs.findResource(FILE_NAME);
// test for DefaultDataObject
- if (UNKNOWN_MIME_TYPE.equals(fo.getMIMEType())) {
- String msg = SelfSamplerAction_SavedFile(outFile.getAbsolutePath());
- DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(msg));
+ Openable open = fo.getLookup().lookup(Openable.class);
+ if (open != null) {
+ open.open();
} else {
- DataObject dobj = DataObject.find(fo);
- dobj.getLookup().lookup(Openable.class).open();
+ IOException ex = new IOException("Cannot open " + fo + " with MIME type: " + fo.getMIMEType());
+ String msg = SelfSamplerAction_SavedFile(outFile.getAbsolutePath());
+ Exceptions.attachSeverity(ex, Level.WARNING);
+ Exceptions.attachLocalizedMessage(ex, msg);
+ Exceptions.printStackTrace(ex);
}
}
@@ -173,7 +175,6 @@
// log warnining
return;
}
- progress = ProgressHandleFactory.createHandle(Save_Progress());
progress.start(steps);
}
@@ -183,7 +184,7 @@
return;
}
progress.finish();
- progress = null;
+ progress = ProgressHandle.createHandle(Save_Progress());
}
@Override
diff --git a/platform/sampler/src/org/netbeans/modules/sampler/Sampler.java b/platform/sampler/src/org/netbeans/modules/sampler/Sampler.java
index ae2859d..7902c12 100644
--- a/platform/sampler/src/org/netbeans/modules/sampler/Sampler.java
+++ b/platform/sampler/src/org/netbeans/modules/sampler/Sampler.java
@@ -76,7 +76,14 @@
* is in nonstandard mode or sampling is not supported.
*/
public static @CheckForNull Sampler createSampler(@NonNull String name) {
- return InternalSampler.createInternalSampler(name);
+ if (SamplesOutputStream.isSupported()) {
+ try {
+ return InternalSampler.createInternalSampler(name);
+ } catch (LinkageError ex) {
+ return new StandaloneSampler(name);
+ }
+ }
+ return null;
}
/**
@@ -89,7 +96,11 @@
*/
public static @CheckForNull Sampler createManualSampler(@NonNull String name) {
if (SamplesOutputStream.isSupported()) {
- return new InternalSampler(name);
+ try {
+ return new InternalSampler(name);
+ } catch (LinkageError ex) {
+ return new StandaloneSampler(name);
+ }
}
return null;
}
diff --git a/platform/sampler/src/org/netbeans/modules/sampler/SamplesOutputStream.java b/platform/sampler/src/org/netbeans/modules/sampler/SamplesOutputStream.java
index e769902..9babdd4 100644
--- a/platform/sampler/src/org/netbeans/modules/sampler/SamplesOutputStream.java
+++ b/platform/sampler/src/org/netbeans/modules/sampler/SamplesOutputStream.java
@@ -36,8 +36,6 @@
import javax.management.StandardMBean;
-import org.openide.util.Exceptions;
-
/**
*
* @author Tomas Hurka
@@ -267,7 +265,6 @@
true);
return (Object[]) getterBean.getAttribute("Threads");
} catch (Exception ex) {
- Exceptions.printStackTrace(ex);
return new Object[0];
}
}
diff --git a/platform/sampler/src/org/netbeans/modules/sampler/SelfSampleVFS.java b/platform/sampler/src/org/netbeans/modules/sampler/SelfSampleVFS.java
index aa2f730..214ab8f0 100644
--- a/platform/sampler/src/org/netbeans/modules/sampler/SelfSampleVFS.java
+++ b/platform/sampler/src/org/netbeans/modules/sampler/SelfSampleVFS.java
@@ -25,10 +25,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import org.openide.filesystems.AbstractFileSystem;
-import org.openide.util.Enumerations;
/** Filesystem that allows to virtually move some files next to each other.
*
@@ -143,7 +143,7 @@
@Override
public Enumeration<String> attributes(String name) {
- return Enumerations.empty();
+ return Collections.emptyEnumeration();
}
@Override
diff --git a/platform/sampler/src/org/netbeans/modules/sampler/StandaloneSampler.java b/platform/sampler/src/org/netbeans/modules/sampler/StandaloneSampler.java
new file mode 100644
index 0000000..d9bad86
--- /dev/null
+++ b/platform/sampler/src/org/netbeans/modules/sampler/StandaloneSampler.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.sampler;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadMXBean;
+
+final class StandaloneSampler extends Sampler {
+ StandaloneSampler(String n) {
+ super(n);
+ }
+
+ @Override
+ ThreadMXBean getThreadMXBean() {
+ return ManagementFactory.getThreadMXBean();
+ }
+
+ @Override
+ void saveSnapshot(byte[] arr) throws IOException {
+ }
+
+ @Override
+ void printStackTrace(Throwable ex) {
+ ex.printStackTrace();
+ }
+
+ @Override
+ void openProgress(int steps) {
+ }
+
+ @Override
+ void closeProgress() {
+ }
+
+ @Override
+ void progress(int i) {
+ }
+}
diff --git a/platform/sampler/test/unit/src/org/netbeans/modules/sampler/AbstractSamplerBase.java b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/AbstractSamplerBase.java
new file mode 100644
index 0000000..f914a4e
--- /dev/null
+++ b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/AbstractSamplerBase.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.sampler;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.openide.util.Exceptions;
+
+public abstract class AbstractSamplerBase {
+
+ protected abstract SamplerTest.Handle createManualSampler(String name);
+ protected abstract SamplerTest.Handle createSampler(String name);
+ protected abstract boolean logsMessage();
+
+ protected static abstract class Handle {
+ protected abstract void start();
+ protected abstract void stop();
+ protected abstract void stopAndWriteTo(DataOutputStream dos) throws IOException;
+ protected abstract void cancel();
+ }
+
+ final void longRunningMethod() {
+ for (int i = 0; i < 100; i++) {
+ try {
+ Thread.sleep(30);
+ } catch (InterruptedException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ }
+
+ /**
+ * Test of cancel method, of class Sampler.
+ */
+ @Test
+ public void testCancel() {
+ SamplerTest.Handle instance = createManualSampler("cancel");
+ instance.start();
+ instance.cancel();
+ }
+
+ /**
+ * Test of createManualSampler method, of class Sampler.
+ */
+ @Test
+ public void testCreateManualSampler() {
+ String name = "gentest";
+ SamplerTest.Handle result = createManualSampler(name);
+ assertNotNull(result);
+ }
+
+ /**
+ * Test of createSampler method, of class Sampler.
+ */
+ @Test
+ public void testCreateSampler() {
+ String name = "test";
+ SamplerTest.Handle result = createSampler(name);
+ assertNotNull(result);
+ }
+
+ /**
+ * Test of stop method, of class Sampler.
+ */
+ @Test
+ public void testStop() {
+ SamplerTest.Handle instance = createManualSampler("stop");
+ assertNotNull(instance);
+ try (final SamplerTest.DD d = new SamplerTest.DD()) {
+ instance.start();
+ longRunningMethod();
+ instance.stop();
+ if (logsMessage()) {
+ assertNotNull("Cancel message has been logged", d.logged);
+ } else {
+ assertNull("CLI handler doesn't use logging", d.logged);
+ }
+ }
+ }
+
+ /**
+ * Test of stopAndWriteTo method, of class Sampler.
+ */
+ @Test
+ public void testStopAndWriteTo() throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (DataOutputStream dos = new DataOutputStream(out)) {
+ SamplerTest.Handle instance = createSampler("cancel");
+ instance.start();
+ instance.stopAndWriteTo(dos);
+ }
+ // there should no data in out, since stopAndWriteTo is
+ // invoked immediately after start
+ assertTrue(out.size() == 0);
+ }
+
+ /**
+ * Test of stopAndWriteTo method, of class Sampler.
+ */
+ @Test
+ public void testStopAndWriteTo1() throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (DataOutputStream dos = new DataOutputStream(out)) {
+ SamplerTest.Handle instance = createSampler("cancel");
+ instance.start();
+ longRunningMethod();
+ instance.stopAndWriteTo(dos);
+ }
+ // make sure we have some sampling data
+ assertTrue(out.size() > 0);
+ }
+
+ public static final class DD extends Handler implements Closeable {
+
+ private final Logger LOG = Logger.getLogger("org.openide.util.Exceptions");
+ LogRecord logged;
+
+ public DD() {
+ super();
+ LOG.addHandler(this);
+ LOG.setLevel(Level.WARNING);
+ LOG.setUseParentHandlers(false);
+ setLevel(Level.WARNING);
+ }
+
+ @Override
+ public void publish(LogRecord record) {
+ logged = record;
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ LOG.removeHandler(this);
+ }
+ } // end of DD
+
+}
diff --git a/platform/sampler/test/unit/src/org/netbeans/modules/sampler/CLISampleTest.java b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/CLISampleTest.java
new file mode 100644
index 0000000..5c8f437
--- /dev/null
+++ b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/CLISampleTest.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.sampler;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+
+public class CLISampleTest extends AbstractSamplerBase {
+ @Override
+ protected Handle createManualSampler(String name) {
+ CLISampler sampler = new CLISampler(ManagementFactory.getThreadMXBean(), null) {
+ @Override
+ protected void saveSnapshot(byte[] arr) throws IOException {
+ }
+ };
+ return new DirectSamplerHandle(sampler);
+ }
+
+ @Override
+ protected Handle createSampler(String name) {
+ return createManualSampler(name);
+ }
+
+ @Override
+ protected boolean logsMessage() {
+ return false;
+ }
+}
diff --git a/platform/sampler/test/unit/src/org/netbeans/modules/sampler/DirectSamplerHandle.java b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/DirectSamplerHandle.java
new file mode 100644
index 0000000..a3a82f5
--- /dev/null
+++ b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/DirectSamplerHandle.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.sampler;
+
+import java.io.DataOutputStream;
+
+final class DirectSamplerHandle extends AbstractSamplerBase.Handle {
+ private final Sampler sampler;
+
+ DirectSamplerHandle(Sampler sampler) {
+ this.sampler = sampler;
+ }
+
+ @Override
+ public final synchronized void start() {
+ sampler.start();
+ }
+
+ @Override
+ public final void cancel() {
+ sampler.cancel();
+ }
+
+ @Override
+ public final void stopAndWriteTo(DataOutputStream dos) {
+ sampler.stopAndWriteTo(dos);
+ }
+
+ @Override
+ public final void stop() {
+ sampler.stop();
+ }
+}
diff --git a/platform/sampler/test/unit/src/org/netbeans/modules/sampler/SamplerTest.java b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/SamplerTest.java
index 36f4cf7..9e39804 100644
--- a/platform/sampler/test/unit/src/org/netbeans/modules/sampler/SamplerTest.java
+++ b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/SamplerTest.java
@@ -18,149 +18,24 @@
*/
package org.netbeans.modules.sampler;
-import java.awt.Dialog;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import org.junit.*;
-import static org.junit.Assert.*;
-import org.netbeans.junit.MockServices;
-import org.netbeans.junit.NbTestCase;
-import org.openide.DialogDescriptor;
-import org.openide.DialogDisplayer;
-import org.openide.NotifyDescriptor;
-import org.openide.util.Exceptions;
-
/**
*
* @author Tomas Hurka
*/
-public class SamplerTest {
+public class SamplerTest extends AbstractSamplerBase {
- @BeforeClass
- public static void setUpClass() throws Exception {
- //register DialogDisplayer which "pushes" Yes option in the document save dialog
- MockServices.setServices(DD.class);
+ @Override
+ protected Handle createManualSampler(String name) {
+ return new DirectSamplerHandle(Sampler.createManualSampler(name));
}
- @AfterClass
- public static void tearDownClass() throws Exception {
+ @Override
+ protected Handle createSampler(String name) {
+ return new DirectSamplerHandle(Sampler.createSampler(name));
}
- @Before
- public void setUp() {
+ @Override
+ protected boolean logsMessage() {
+ return true;
}
-
- @After
- public void tearDown() {
- }
-
- /**
- * Test of createSampler method, of class Sampler.
- */
- @Test
- public void testCreateSampler() {
- System.out.println("createSampler");
- String name = "test";
- Sampler result = Sampler.createSampler(name);
- assertNotNull(result);
- }
-
- /**
- * Test of createManualSampler method, of class Sampler.
- */
- @Test
- public void testCreateManualSampler() {
- System.out.println("createManualSampler");
- String name = "gentest";
- Sampler result = Sampler.createManualSampler(name);
- assertNotNull(result);
- }
-
- /**
- * Test of cancel method, of class Sampler.
- */
- @Test
- public void testCancel() {
- System.out.println("cancel");
- Sampler instance = Sampler.createManualSampler("cancel");
- instance.start();
- instance.cancel();
- }
-
- /**
- * Test of stopAndWriteTo method, of class Sampler.
- */
- @Test
- public void testStopAndWriteTo() throws IOException {
- System.out.println("stopAndWriteTo");
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(out);
- Sampler instance = Sampler.createSampler("cancel");
- instance.start();
- instance.stopAndWriteTo(dos);
- dos.close();
- // there should no data in out, since stopAndWriteTo is
- // invoked immediately after start
- assertTrue(out.size() == 0);
- }
- /**
- * Test of stopAndWriteTo method, of class Sampler.
- */
- @Test
- public void testStopAndWriteTo1() throws IOException {
- System.out.println("stopAndWriteTo1");
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(out);
- Sampler instance = Sampler.createSampler("cancel");
- instance.start();
- longRunningMethod();
- instance.stopAndWriteTo(dos);
- dos.close();
- // make sure we have some sampling data
- assertTrue(out.size() > 0);
- }
-
- private void longRunningMethod() {
- for (int i=0; i<100;i++) {
- try {
- Thread.sleep(30);
- } catch (InterruptedException ex) {
- Exceptions.printStackTrace(ex);
- }
- }
- }
-
- /**
- * Test of stop method, of class Sampler.
- */
- @Test
- public void testStop() {
- System.out.println("stop");
- Sampler instance = Sampler.createManualSampler("stop");
- DD.hasData = false;
- instance.start();
- longRunningMethod();
- instance.stop();
- assert(DD.hasData);
- }
-
- /** Our own dialog displayer.
- */
- public static final class DD extends DialogDisplayer {
- static boolean hasData;
-
- @Override
- public Dialog createDialog(DialogDescriptor descriptor) {
- throw new IllegalStateException ("Not implemented");
- }
-
- @Override
- public Object notify(NotifyDescriptor descriptor) {
- hasData = true;
- return null;
- }
-
- } // end of DD
-
}
diff --git a/platform/sampler/test/unit/src/org/netbeans/modules/sampler/StandaloneSamplerTest.java b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/StandaloneSamplerTest.java
new file mode 100644
index 0000000..7e6e128
--- /dev/null
+++ b/platform/sampler/test/unit/src/org/netbeans/modules/sampler/StandaloneSamplerTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.sampler;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class StandaloneSamplerTest extends AbstractSamplerBase {
+ private static Class<?> samplerClass;
+
+ @BeforeClass
+ public static void loadInIsolatedLoader() throws ClassNotFoundException {
+ URLClassLoader l = new URLClassLoader(new URL[] {
+ Sampler.class.getProtectionDomain().getCodeSource().getLocation()
+ }, Sampler.class.getClassLoader().getParent());
+
+ samplerClass = l.loadClass("org.netbeans.modules.sampler.Sampler");
+
+ try {
+ Class<?> lookupClass = l.loadClass("org.openide.util.Lookup");
+ fail("It shouldn't be possible to load Lookup class with this classloader: " + lookupClass);
+ } catch (ClassNotFoundException ok) {
+ assertNotNull(ok);
+ }
+ }
+
+ @Override
+ protected Handle createManualSampler(String name) {
+ try {
+ Object sampler = samplerClass.getMethod("createManualSampler", String.class).invoke(null, name);
+ return new ReflectionHandle(sampler);
+ } catch (ReflectiveOperationException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ @Override
+ protected Handle createSampler(String name) {
+ try {
+ Object sampler = samplerClass.getMethod("createSampler", String.class).invoke(null, name);
+ return new ReflectionHandle(sampler);
+ } catch (ReflectiveOperationException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ @Override
+ protected boolean logsMessage() {
+ return false;
+ }
+
+ private static final class ReflectionHandle extends Handle {
+ private final Object sampler;
+
+ private ReflectionHandle(Object sampler) {
+ this.sampler = sampler;
+ }
+
+ @Override
+ protected void start() {
+ try {
+ samplerClass.getMethod("start").invoke(sampler);
+ } catch (ReflectiveOperationException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ @Override
+ protected void stop() {
+ try {
+ samplerClass.getMethod("stop").invoke(sampler);
+ } catch (ReflectiveOperationException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ @Override
+ protected void stopAndWriteTo(DataOutputStream dos) throws IOException {
+ try {
+ samplerClass.getMethod("stopAndWriteTo", DataOutputStream.class).invoke(sampler, dos);
+ } catch (ReflectiveOperationException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ @Override
+ protected void cancel() {
+ try {
+ samplerClass.getMethod("cancel").invoke(sampler);
+ } catch (ReflectiveOperationException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+ }
+}