2010-12-16 89 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