2010-12-16 110 views
1

我正在使用监视远程服务器的守护进程脚本。当远程服务器启动时,我希望Netbeans自动将它的调试器连接到远程服务器。从命令行控制Netbeans:从Shell脚本附加调试器

是否有可能从命令行控制这种行为? 要键入类似

netbeans --attach-debugger 192.168.178.34:9009 

终端内做到这一点?或者还有什么其他方式可以访问Netbeans内部的东西? (直到现在,我只是Netbeans的“用户”,所以我不知道内部以及如何访问它们)

或者我将不得不编写一个Netbeans插件来做到这一点?如果是的话,你能给我一个很好的起点来增加这个功能吗?

回答

3

好吧,因为没有选项可以从命令行附加调试器,所以我在NB邮件列表中用this blog entrythis thread的帮助编写了一个Netbeans插件。现在我可以从命令行调用我的插件动作。

因此,构建一个简单的NetBeans模块,其中包含两个重要的类。 这是它得到的命令行参数,并将其转发到我的行动类:

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; 
    } 

} 

这是我的插件操作,其重视的调试器到指定的远程地址:

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); 
     } 
    } 
} 

现在我可以附加Netbeans调试器通过调用netbeans/bin/netbeans --debug 192.168.178.79