Migrating ACRA from annotations to pluginconfigurations - acra

I use ACRA 5.8.4 and I want to update it to 5.9.6 but #annotations are deprecated and I have to change it to PluginConfigurations, but documentation isn't finished and I don't know how to do it. This is my current Application class:
package com.mycompany.myapp;
import android.app.Application;
import android.content.Context;
import androidx.multidex.MultiDex;
import org.acra.ACRA;
import org.acra.annotation.AcraCore;
import org.acra.annotation.AcraDialog;
import org.acra.annotation.AcraMailSender;
#AcraCore(buildConfigClass = BuildConfig.class)
#AcraMailSender(mailTo = "myemail#mydomain.com",
resSubject = R.string.mailsubject)
#AcraDialog(resTitle = R.string.acratitle,
resText = R.string.acratext,
resPositiveButtonText = R.string.acrasend,
resNegativeButtonText = R.string.acracancel,
resCommentPrompt = R.string.acracomprompt )
public class MyAwsomeApplication extends Application {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
// The following line triggers the initialization of ACRA
ACRA.init(this);
}
}
And I want to update it to pluginconfigurations:
public class MyAwsomeApplication extends Application {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
// The following line triggers the initialization of ACRA
CoreConfigurationBuilder builder;
builder = new CoreConfigurationBuilder()
.withBuildConfigClass(BuildConfig.class)
.withReportFormat(StringFormat.JSON)
.withPluginConfigurations(
<-- I think, here I should add new clases for dialog and mail sender -->
);
ACRA.init(this, builder);
}
}

You can use
.withPluginConfigurations(
new DialogConfigurationBuilder()
.withCommentPrompt(getString(R.string.crash_dialog_comment_prompt))
.withText(getString(R.string.crash_dialog_text))
.build(),
new MailSenderConfigurationBuilder()
.withMailTo("crash#report.xx")
.withReportAsFile(true)
.withReportFileName("Crash.txt")
.withBody("getString(R.string.mail_body)")
.build()
)
examples for configuration builders can be found on: https://www.acra.ch/docs/Senders

Related

I want to create a plugin using biometric authentication (Biometric) provided by Google and implement it in Unity

I would like to implement biometric authentication using the biometrics provided by Googole, but I am having trouble getting it to work.
The following is a reference site on biometrics.
https://developer.android.com/jetpack/androidx/releases/biometric
I've never made an Android plugin before, and I'm having a hard time finding information on how to integrate with Unity.
I'm testing it with the following code
java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/activity/ComponentActivity;
java.lang.ClassNotFoundException: androidx.activity.ComponentActivity
I'm getting an error and don't know how to fix it.
Please help me. Please help me.
◇MainActivity.java
package com.example.biometricslibs;
import android.content.Context;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.biometric.BiometricPrompt;
import androidx.fragment.app.FragmentActivity;
import java.util.concurrent.Executor;
public class MainActivity {
public static MainActivity instance() {
return new MainActivity();
}
private Executor executor = new MainThreadExecutor();
private BiometricPrompt biometricPrompt;
private BiometricPrompt.AuthenticationCallback callback = new BiometricPrompt.AuthenticationCallback() {
#Override
public void onAuthenticationError(int errorCode, #NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
if (errorCode == 13 && biometricPrompt != null)
biometricPrompt.cancelAuthentication();
}
#Override
public void onAuthenticationSucceeded(#NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
}
#Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
}
};
public void BiometricCheck(Context context) {
Toast.makeText(context, "call", Toast.LENGTH_SHORT).show();
biometricPrompt = new BiometricPrompt((FragmentActivity) context, executor, callback);
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("title")
.setSubtitle("subTitle")
.setDescription("description")
.setNegativeButtonText("cancel")
.build();
biometricPrompt.authenticate(promptInfo);
}
}
◇MainThreadExecutor.java
package com.example.biometricslibs;
import android.os.Handler;
import android.os.Looper;
import java.util.concurrent.Executor;
public class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
#Override
public void execute(Runnable r) {
handler.post(r);
}
}
◇UnityC#
using(var nativeDialog = new AndroidJavaClass("com.example.biometricslibs.MainActivity"))
{
using(var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
using(var currentUnityActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
{
using(var instance = nativeDialog.CallStatic<AndroidJavaObject>("instance"))
{
instance.Call(
"BiometricCheck",
currentUnityActivity
);
}
}
}
}

Use Datawedge with flutter

I am trying to use the datawedge intent API with my flutter application, on a Zebra android scanner. I started to use the Zebra EMDK API from a git repository, which works perfectly. Now I want to migrate it (which is recommended by Zebra) because I want it to be also available on mobiles (if it is possible).
I am trying to follow the instructions from this page and merge it with the code from the git repo, but no scan event is detected in my app.
Has someone already done this and could help me?
Here is my MainActivity.java:
package com.example.test_datawedge;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
// import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.EventChannel.EventSink;
import io.flutter.plugin.common.EventChannel.StreamHandler;
import io.flutter.plugins.GeneratedPluginRegistrant;
import java.util.ArrayList;
public class MainActivity extends FlutterActivity {
private static final String BARCODE_RECEIVED_CHANNEL = "samples.flutter.io/barcodereceived";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
// setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter();
filter.addCategory(Intent.CATEGORY_DEFAULT);
filter.addAction(getResources().getString(R.string.activity_intent_filter_action));
// registerReceiver(myBroadcastReceiver, filter);
new EventChannel(getFlutterView(), BARCODE_RECEIVED_CHANNEL).setStreamHandler(
new StreamHandler() {
private BroadcastReceiver barcodeBroadcastReceiver;
#Override
public void onListen(Object arguments, EventSink events) {
Log.d("FLUTTERDEMO", "EventChannelOnListen");
barcodeBroadcastReceiver = createBarcodeBroadcastReceiver(events);
registerReceiver(
barcodeBroadcastReceiver, new IntentFilter("readBarcode"));
}
#Override
public void onCancel(Object arguments) {
Log.d("FLUTTERDEMO", "EventChannelOnCancel");
unregisterReceiver(barcodeBroadcastReceiver);
barcodeBroadcastReceiver = null;
}
}
);
}
// #Override
// protected void onDestroy()
// {
// super.onDestroy();
// unregisterReceiver(myBroadcastReceiver);
// }
//
// After registering the broadcast receiver, the next step (below) is to define it.
// Here it's done in the MainActivity.java, but also can be handled by a separate class.
// The logic of extracting the scanned data and displaying it on the screen
// is executed in its own method (later in the code). Note the use of the
// extra keys are defined in the strings.xml file.
//
private BroadcastReceiver createBarcodeBroadcastReceiver(final EventSink events) {
return new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d("FLUTTERDEMO", "createBarcodeBroadcastReceiver " + action);
if(action.equals("readBarcode")){
String barcode = intent.getStringExtra("barcode");
String barcodetype = intent.getStringExtra("barcodetype");
Log.d("FLUTTERDEMO", "createBarcodeBroadcastReceiver " + barcode);
events.success(barcode);
}
}
};
}
//
// The section below assumes that a UI exists in which to place the data. A production
// application would be driving much of the behavior following a scan.
//
// private void displayScanResult(Intent initiatingIntent, String howDataReceived)
// {
// String decodedSource = initiatingIntent.getStringExtra(getResources().getString(R.string.datawedge_intent_key_source));
// String decodedData = initiatingIntent.getStringExtra(getResources().getString(R.string.datawedge_intent_key_data));
// String decodedLabelType = initiatingIntent.getStringExtra(getResources().getString(R.string.datawedge_intent_key_label_type));
// final TextView lblScanSource = (TextView) findViewById(R.id.lblScanSource);
// final TextView lblScanData = (TextView) findViewById(R.id.lblScanData);
// final TextView lblScanLabelType = (TextView) findViewById(R.id.lblScanDecoder);
// lblScanSource.setText(decodedSource + " " + howDataReceived);
// lblScanData.setText(decodedData);
// lblScanLabelType.setText(decodedLabelType);
// }
}
Zebra EMDK retrieves data by overriding the 'onStatus' and 'onData' functions.
Retrieve your barcode data from 'onData'

Getting user data in NewProjectCreationPage in Eclipse Plugin

I have been successful in making a plugin. However now i need that on project creation page i add some more textboxes to get the user information. Also i need to use this information to add into the auto generated .php files made in project directory.
I want to know how can i override the WizardNewProjectCreationPage to add some more textboxes to the already given layout. I am pretty new to plugin development. Here is the code for my custom wizard.
import java.net.URI;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard;
import rudraxplugin.pages.MyPageOne;
import rudraxplugin.projects.RudraxSupport;
public class CustomProjectNewWizard extends Wizard implements INewWizard, IExecutableExtension {
private WizardNewProjectCreationPage _pageOne;
protected MyPageOne one;
private IConfigurationElement _configurationElement;
public CustomProjectNewWizard() {
// TODO Auto-generated constructor stub
setWindowTitle("RudraX");
}
#Override
public void init(IWorkbench workbench, IStructuredSelection selection) {
// TODO Auto-generated method stub
}
#Override
public void addPages() {
super.addPages();
_pageOne = new WizardNewProjectCreationPage("From Scratch Project Wizard");
_pageOne.setTitle("From Scratch Project");
_pageOne.setDescription("Create something from scratch.");
addPage(one);
addPage(_pageOne);
}
#Override
public boolean performFinish() {
String name = _pageOne.getProjectName();
URI location = null;
if (!_pageOne.useDefaults()) {
location = _pageOne.getLocationURI();
System.err.println("location: " + location.toString()); //$NON-NLS-1$
} // else location == null
RudraxSupport.createProject(name, location);
// Add this
BasicNewProjectResourceWizard.updatePerspective(_configurationElement);
return true;
}
#Override
public void setInitializationData(IConfigurationElement config,
String propertyName, Object data) throws CoreException {
_configurationElement = config;
// TODO Auto-generated method stub
}
}
Ask for any other code required. Any help is appreciated. Thank You.
Instead of using WizardNewProjectCreationPage directly create a new class extending WizardNewProjectCreationPage and override the createControl method to create new controls:
class MyNewProjectCreationPage extends WizardNewProjectCreationPage
{
#Override
public void createControl(Composite parent)
{
super.createControl(parent);
Composite body = (Composite)getControl();
... create new controls here
}
}

Eclipse 4 RCP - application does not have active window

I want to have some helper functions for manipulating UI.
I don't want to pass to them any parameters except what is necessary by my domain model (i don't want to pass EModelService, EPartService etc.)
Question: The problem is i am getting exception application does not have active window.
I found where the problem is.
It happend because i am manipulating parts via EPartService accessed from the application context IWorkbench.getApplication().getContext().get(EPartService.class).
THIS IS IMPORTANT: Currently i am getting that exception when i am trying to modify my UI AFTER i read inputs from dialog. Pleas note that the error does not happened when i am trying to modify the UI just BEFORE i
opened the dialog. Look at the code, i added some comments.
NewFromDirectoryDialog.java
package cz.vutbr.fit.xhriba01.bc.handlers;
import javax.inject.Named;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import cz.vutbr.fit.xhriba01.bc.BcModel;
import cz.vutbr.fit.xhriba01.bc.resolvers.filesystem.FileSystemResolver;
import cz.vutbr.fit.xhriba01.bc.ui.dialogs.NewFromDirectoryDialog;
import cz.vutbr.fit.xhriba01.bc.ui.UI;
public class NewFromDirectoryHandler {
#Execute
public void execute(MApplication application, EPartService partService, #Named(IServiceConstants.ACTIVE_SHELL) Shell shell) {
FileSystemResolver fsr = new FileSystemResolver("/home/jara/git/cz.vutbr.fit.xhriba01.bc/bc/src",
"/home/jara/git/cz.vutbr.fit.xhriba01.bc/bc/bin");
BcModel.setResolver(fsr);
// THIS CALL IS OK AND EVERYTHING WORKS
UI.changeExplorerView("bc.partdescriptor.filesystemview", fsr);
NewFromDirectoryDialog dialog = new NewFromDirectoryDialog(shell);
dialog.create();
if (dialog.open() == Window.OK) {
String sourceDir = dialog.getSourceDir();
String classDir = dialog.getClassDir();
FileSystemResolver fsr = new FileSystemResolver(classDir, sourceDir);
//THIS CALL LEADS TO EXCEPTION: application does not have active window
UI.changeExplorerView("bc.partdescriptor.filesystemview", fsr);
}
}
}
That EPartService from application context is based on org.eclipse.e4.ui.internal.workbench.ApplicationPartServiceImpl
and not on org.eclipse.e4.ui.internal.workbench.PartServiceImpl
as EPartService instance you get when injected to #PostConstruct annotated method on Part's view.
org.eclipse.e4.ui.internal.workbench.ApplicationPartServiceImpl (not entire source code)
You can see that the error probably happened because at the time ApplicationPartServiceImpl.createPart is called in my UI.changeExplorerView, the Eclipse runtime does not know what window
is currently active.
package org.eclipse.e4.ui.internal.workbench;
import java.util.Collection;
import javax.inject.Inject;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.modeling.IPartListener;
public class ApplicationPartServiceImpl implements EPartService {
private MApplication application;
#Inject
ApplicationPartServiceImpl(MApplication application) {
this.application = application;
}
private EPartService getActiveWindowService() {
IEclipseContext activeWindowContext = application.getContext().getActiveChild();
if (activeWindowContext == null) {
throw new IllegalStateException("Application does not have an active window"); //$NON-NLS-1$
}
EPartService activeWindowPartService = activeWindowContext.get(EPartService.class);
if (activeWindowPartService == null) {
throw new IllegalStateException("Active window context is invalid"); //$NON-NLS-1$
}
if (activeWindowPartService == this) {
throw new IllegalStateException("Application does not have an active window"); //$NON-NLS-1$
}
return activeWindowPartService;
}
#Override
public MPart createPart(String id) {
return getActiveWindowService().createPart(id);
}
}
LifeCycleManager.java (how i initialize the UI helper class)
You can see i am injecting IWorkbench to my UI class.
IWorkbench allows me to access MApplication, so that is all i should
need to modify app UI.
package cz.vutbr.fit.xhriba01.bc;
import javax.inject.Inject;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.ui.di.UIEventTopic;
import org.eclipse.e4.ui.workbench.IWorkbench;
import org.eclipse.e4.ui.workbench.UIEvents;
import cz.vutbr.fit.xhriba01.bc.ui.UI;
public class LifeCycleManager {
#Inject
#Optional
private void appCompleted(#UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Object event, IWorkbench workbench) {
ContextInjectionFactory.inject(UI.getDefault(), workbench.getApplication().getContext());
}
}
UI.java
package cz.vutbr.fit.xhriba01.bc.ui;
import javax.inject.Inject;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.workbench.IWorkbench;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
import org.eclipse.jface.text.IDocument;
import cz.vutbr.fit.xhriba01.bc.BcModel;
import cz.vutbr.fit.xhriba01.bc.resolvers.ISourceAndClassResolver;
public class UI {
public static final String PART_EXPLORER_ID = "bc.part.inspector";
public static final String PART_EXPLORER_CONTAINER_ID = "bc.partstack.explorer_stack";
public static final String PART_JAVA_SOURCE_VIEWER_ID = "bc.part.javasourceview";
private static UI fInstance = new UI();
#Inject
private IWorkbench fWorkbench;
private UI() {
}
public static void changeExplorerView(String partDescriptorId, ISourceAndClassResolver resolver) {
EModelService modelService = fInstance.fWorkbench.getApplication().getContext().get(EModelService.class);
EPartService partService = fInstance.fWorkbench.getApplication().getContext().get(EPartService.class);
MApplication application = fInstance.fWorkbench.getApplication();
MPart part = partService.createPart(partDescriptorId);
MPart oldPart = partService.findPart(UI.PART_EXPLORER_ID);
MPartStack partStack = (MPartStack) modelService.find(UI.PART_EXPLORER_CONTAINER_ID, application);
partStack.setVisible(true);
if (oldPart != null) {
partService.hidePart(oldPart);
}
part.setElementId(UI.PART_EXPLORER_ID);
partStack.getChildren().add(part);
BcModel.setResolver(resolver);
partService.showPart(part, PartState.VISIBLE);
}
public static UI getDefault() {
return fInstance;
}
public static void setJavaSourceLabel(String label, EPartService partService) {
MPart part = partService.findPart(UI.PART_JAVA_SOURCE_VIEWER_ID);
if (part != null) {
part.setLabel(label);
}
}
public static void setJavaSourceText(String source) {
IDocument document = BcModel.getJavaDocument();
if (document != null) {
document.set(source);
}
}
}
I think the problem is when i open the dialog, the activeChild changes somehow to that new opened dialog and when i close it and try immediately change my UI, it does not work because the activeChild is still not properly setup back. Otherweise i don't know why it works fine just before i opened the dialog and doesn't work just after the dialog is closed.
Does anyone know if it is bug?

Control Netbeans from Commandline: attach Debugger from Shell-script

I'm using a daemon-script which is monitoring a remote server. When the remote server is up, i want that Netbeans automatically connects it's Debugger to the remote Server.
Is it possible to control this behavior from commandline?
To type Something like
netbeans --attach-debugger 192.168.178.34:9009
inside a terminal to do that? Or what other ways do i have to get access to Netbeans-internal stuff? (until now, i was just a "user" of Netbeans so i don't know the internals and how to access them very well)
Or will i have to write a Netbeans Plugin to do that? If yes, can you give me a good starting point to add that functionality?
Ok since there is no option to attach the Debugger from commandline, i wrote a Netbeans Plugin with the help of this blog entry and this thread from the NB-mailinglist. Now i'm able to call my plugin actions from the Commandline.
So build a simple NetBeans Module, which contains 2 important classes.
This is the class which gets the commandline parameters and forwards them to my Action:
import java.awt.event.ActionEvent;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import javax.swing.Action;
import org.netbeans.api.sendopts.CommandException;
import org.netbeans.spi.sendopts.Env;
import org.netbeans.spi.sendopts.OptionProcessor;
import org.netbeans.spi.sendopts.Option;
import org.openide.ErrorManager;
import org.openide.cookies.InstanceCookie;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataObject;
import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.WindowManager;
#ServiceProvider(service = OptionProcessor.class)
public class TriggerActionCommandLine extends OptionProcessor {
//Here we specify "runAction" as the new key in the command,
//but it could be any other string you like, of course:
private static Option action = Option.requiredArgument(Option.NO_SHORT_NAME, "debug");
private static final Logger logger = Logger.getLogger(AttachDebugger.class.getName());
#Override
public Set<org.netbeans.spi.sendopts.Option> getOptions() {
return Collections.singleton(action);
}
#Override
protected void process(Env env, Map<Option, String[]> values) throws CommandException {
final String[] args = (String[]) values.get(action);
if (args.length > 0) {
//Set the value to be the first argument from the command line,
//i.e., this is "GreetAction", for example:
final String ip = args[0];
//Wait until the UI is constructed,
//otherwise you will fail to retrieve your action:
WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
#Override
public void run() {
//Then find & perform the action:
Action a = findAction(AttachDebugger.ACTION_NAME);
// forward IP address to Action
ActionEvent e = new ActionEvent(this, 1, ip);
a.actionPerformed(e);
}
});
}
}
public Action findAction(String actionName) {
FileObject myActionsFolder = FileUtil.getConfigFile("Actions/PSFActions");
FileObject[] myActionsFolderKids = myActionsFolder.getChildren();
for (FileObject fileObject : myActionsFolderKids) {
logger.info(fileObject.getName());
//Probably want to make this more robust,
//but the point is that here we find a particular Action:
if (fileObject.getName().contains(actionName)) {
try {
DataObject dob = DataObject.find(fileObject);
InstanceCookie ic = dob.getLookup().lookup(InstanceCookie.class);
if (ic != null) {
Object instance = ic.instanceCreate();
if (instance instanceof Action) {
Action a = (Action) instance;
return a;
}
}
} catch (Exception e) {
ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
return null;
}
}
}
return null;
}
}
This is my Plugin Action which attaches the Debugger to the given remote address:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.api.debugger.jpda.DebuggerStartException;
import org.netbeans.api.debugger.jpda.JPDADebugger;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.awt.ActionRegistration;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.awt.ActionID;
import org.python.util.PythonInterpreter;
#ActionID(category = "PSFActions", id = "de.mackaz.AttachDebugger")
#ActionRegistration(displayName = "#CTL_AttachDebuggerAction")
#ActionReferences({
#ActionReference(path = "Menu/Tools", position = 1800, separatorBefore = 1750, separatorAfter = 1850)
})
public final class AttachDebugger implements ActionListener {
private static final Logger logger = Logger.getLogger(AttachDebugger.class.getName());
public static final String ACTION_NAME="AttachDebugger";
#Override
public void actionPerformed(ActionEvent e) {
String ip;
if (!e.getActionCommand().contains("Attach Debugger")) {
ip = e.getActionCommand();
} else {
ip = lookupIP();
}
try {
logger.log(Level.INFO, "Attaching Debugger to IP {0}", ip);
JPDADebugger.attach(
ip,
9009,
new Object[]{null});
} catch (DebuggerStartException ex) {
int msgType = NotifyDescriptor.ERROR_MESSAGE;
String msg = "Failed to connect debugger to remote IP " + ip;
NotifyDescriptor errorDescriptor = new NotifyDescriptor.Message(msg, msgType);
DialogDisplayer.getDefault().notify(errorDescriptor);
}
}
}
Now i can attach the Netbeans debugger to a specific address by calling netbeans/bin/netbeans --debug 192.168.178.79