Everlaw / nbts

NetBeans TypeScript editor plugin
283 stars 46 forks source link

Cannot create NodeJS process on Mac OS X #3

Closed istvan-antal closed 9 years ago

istvan-antal commented 9 years ago

I just installed the plugin on Mac OS X and this is the error I get:

screenshot 2015-10-09 06 49 14

I found no options in NetBeans to specify the path to my NodeJS executable and I have installed NodeJS with the standard installer, the executable's path is /usr/local/bin/node

I managed to run an echo $PATH from NetBeans and this is what I got: /usr/bin:/bin:/usr/sbin:/sbin

mintern commented 9 years ago

Thanks for the high quality bug report! It might be nice for the plugin to fallback to some standard install locations if it can't be found on the PATH, but I'll defer to @jeffrey-easyesi on that decision.

In the meantime, I might be able to help you get up and running. On Linux at least, NetBeans inherits the desktop environment, which is populated on login by reading /etc/environment and ~/.profile.

Perhaps you are updating PATH in ~/.bashrc or ~/.bash_profile to include /usr/local/bin? If so, that will work for a Bash Terminal but not for Netbeans.

After a bit of research, it looks like you might have to update /etc/launchd.conf with the appropriate PATH and restart.

EDIT: From that same thread, you might be able to run launchctl setenv PATH "$PATH:/usr/local/bin" to avoid the need to restart your computer (only NetBeans), but you'll still need to edit launchd.conf for the setting to persist across reboots.

istvan-antal commented 9 years ago

hi @mintern, thank you for the suggestions , I tried the above methods, and some other ones as well, however it seems to have no affect on NetBeans, maybe it's the Java runtime, that isn't picking up the paths.

istvan-antal commented 9 years ago

I made a quick fix for this and opened a pull request, it's a really small and simple change, but it gets the job done.

geekdenz commented 9 years ago

Would it make sense to use the HTML5 settings for nodejs executable? Please look under Tools -> Options -> HTML/JS -> Node.js. One can select the nodejs executable there. Maybe this project should check the setting instead of using the environment or at least do that first.

istvan-antal commented 9 years ago

I can't really see that menu. I even created a HTML5 project and can't eve see it there.

geekdenz commented 9 years ago

Are you using 8.1 or 8.0? I think it's there in 8.1 but not in 8.0 from memory.

mkleint commented 9 years ago

I believe there is an NetBeans ExtExecution API that makes the PATH handling easier - http://bits.netbeans.org/8.0/javadoc/org-netbeans-modules-extexecution/org/netbeans/api/extexecution/ExternalProcessBuilder.html

I've tried to create a PR but the plugin doesn't compile for me so at least here's the simple untested patch to the file in question.

diff --git a/src/netbeanstypescript/TSService.java b/src/netbeanstypescript/TSService.java
index 5a09576..4d1ce08 100644
--- a/src/netbeanstypescript/TSService.java
+++ b/src/netbeanstypescript/TSService.java
@@ -56,6 +56,7 @@
 import org.json.simple.JSONObject;
 import org.json.simple.JSONValue;
 import org.json.simple.parser.ParseException;
+import org.netbeans.api.extexecution.ExternalProcessBuilder;
 import org.netbeans.lib.editor.util.StringEscapeUtils;
 import org.netbeans.modules.csl.api.*;
 import org.netbeans.modules.csl.api.DeclarationFinder.DeclarationLocation;
@@ -71,6 +72,7 @@
 import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
 import org.netbeans.modules.refactoring.spi.SimpleRefactoringElementImplementation;
 import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
 import org.openide.filesystems.URLMapper;
 import org.openide.modules.InstalledFileLocator;
 import org.openide.text.CloneableEditorSupport;
@@ -120,10 +122,13 @@
             System.out.println("TSService: starting nodejs");
             File file = InstalledFileLocator.getDefault().locate("nbts-services.js", "netbeanstypescript", false);
             for (String command: new String[] { "nodejs", "node" }) {
-                try {
-                    Process process = new ProcessBuilder()
-                        .command(command, "--harmony", file.toString())
-                        .start();
+            try {
+                    ExternalProcessBuilder builder = new ExternalProcessBuilder(command)
+                        .redirectErrorStream(true)
+                        .addArgument("--harmony")
+                        .addArgument(file.toString());
+
+                    Process process = builder.call();
                     stdin = process.getOutputStream();
                     stdout = new BufferedReader(new InputStreamReader(process.getInputStream()));
                     process.getErrorStream().close();
jeffrey-easyesi commented 9 years ago

It looks like by default OS X has an entry in /etc/paths for /usr/local/bin, but it applies only to login shells like those started by Terminal, and not to .app bundles run from the Finder. I think checking for node in /usr/local/bin if it's not on the PATH is the least bad option here. I'll apply @istvan-antal's PR.

As a workaround on existing versions of this plugin, you can start NetBeans from the Terminal (/Applications/NetBeans/NetBeans\ 8.0.2.app/Contents/MacOS/netbeans)

@mkleint: ExternalProcessBuilder does have a prependPath method, but it only affects the environment of the child process and does not affect searching for the executable. Besides, I would want a hard-coded location like /usr/local/bin to be the last thing to search, not the first (so a non-root user can override it with an executable in ~/bin or something)