IDEA Scala: Could not find output directory - scala

Trying to play with scala in IDEA with scala plug-in:
My HelloWorld object:
object HelloWorld {
def main(args: Array[String]) {
println("Hello")
}
}
And sometimes I getting next error when pressing 'Run HelloWorld' from context menu.
scalac: Error: Could not find an output directory for /Users/username/Work/src/sandbox/src/HelloWorld.scala in List((/Users/username/work/src/sandbox/src,/Users/username/work/src/sandbox/out/production/sandbox))
scala.reflect.internal.FatalError: Could not find an output directory for /Users/username/Work/src/sandbox/src/HelloWorld.scala in List((/Users/username
/work/src/sandbox/src,/Users/username/work/src/sandbox/out/production/sandbox))
at scala.tools.nsc.settings.MutableSettings$OutputDirs.outputDirFor(MutableSettings.scala:303)
at scala.tools.nsc.backend.jvm.BytecodeWriters$class.outputDirectory(BytecodeWriters.scala:26)
at scala.tools.nsc.backend.jvm.BytecodeWriters$class.scala$tools$nsc$backend$jvm$BytecodeWriters$$getFile(BytecodeWriters.scala:37)
at scala.tools.nsc.backend.jvm.BytecodeWriters$ClassBytecodeWriter$class.writeClass(BytecodeWriters.scala:89)
at scala.tools.nsc.backend.jvm.GenASM$AsmPhase$$anon$4.writeClass(GenASM.scala:67)
at scala.tools.nsc.backend.jvm.GenASM$JBuilder.writeIfNotTooBig(GenASM.scala:458)
at scala.tools.nsc.backend.jvm.GenASM$JMirrorBuilder.genMirrorClass(GenASM.scala:2954)
at scala.tools.nsc.backend.jvm.GenASM$AsmPhase.run(GenASM.scala:113)
at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1583)
at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1557)
at scala.tools.nsc.Global$Run.compileSources(Global.scala:1553)
at scala.tools.nsc.Global$Run.compile(Global.scala:1662)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:126)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:102)
at xsbt.CompilerInterface.run(CompilerInterface.scala:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:102)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:48)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
at org.jetbrains.jps.incremental.scala.local.IdeaIncrementalCompiler.compile(IdeaIncrementalCompiler.scala:26)
at org.jetbrains.jps.incremental.scala.local.LocalServer.compile(LocalServer.scala:25)
at org.jetbrains.jps.incremental.scala.remote.Main$.make(Main.scala:58)
at org.jetbrains.jps.incremental.scala.remote.Main$.nailMain(Main.scala:21)
at org.jetbrains.jps.incremental.scala.remote.Main.nailMain(Main.scala)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.martiansoftware.nailgun.NGSession.run(NGSession.java:319)
This error very annoying because to fix it I need to restart IDEA, clean/compile my project, add/remove launch configuration few times. Also command line from the error properly can be executed from the terminal manually.

Looking at the error comment:
Could not find an output directory for:
/Users/username/Work/src/sandbox/src/HelloWorld.scala
in
/Users/username/work/src/sandbox/src
/Users/username/work/src/sandbox/out/production/sandbox
Depending on the environment you're running the IntelliJ in the upper/lower case difference matters. Please make sure your user.home property is set correctly.

Answer from Norbert Radyk didn't apply to me. Paths were correct in my case. I had to delete target/scala-2.11/test-classes folder in order to compel Intellij to recompile the test class. A bit of a pain though as it will work as long as I don't have to modify the test itself. So not really a solution but a bit of a hack in case you really need to debug a test.

Related

How do I set up Scala in VS Code to run a simple "Hello World!" statement?

I am trying to run Scala in VS Code, a simple hello world statement, but I get this output:
PS C:\Users\thmga\OneDrive\Documents\Notebook\vscode_test> scala "c:\Users\thmga\OneDrive\Documents\Notebook\vscode_test\test.scala"
Exception in thread "main" dotty.tools.scripting.StringDriverException: No main methods detected for [c:\Users\thmga\OneDrive\Documents\Notebook\vscode_test\test.scala]
at dotty.tools.scripting.StringDriverException$.apply(StringDriver.scala:47)
at dotty.tools.scripting.Util$.detectMainClassAndMethod(Util.scala:51)
at dotty.tools.scripting.ScriptingDriver.compileAndRun(ScriptingDriver.scala:28)
at dotty.tools.scripting.Main$.main(Main.scala:45)
at dotty.tools.MainGenericRunner$.run$1(MainGenericRunner.scala:249)
at dotty.tools.MainGenericRunner$.main(MainGenericRunner.scala:268)
at dotty.tools.MainGenericRunner.main(MainGenericRunner.scala)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at coursier.bootstrap.launcher.a.a(Unknown Source)
at coursier.bootstrap.launcher.Launcher.main(Unknown Source)
The code:
#main def hello(): Unit =
println("Hello, World!")
I tried with the file named "test.sc" and "test.scala". When I used "test.scala" the icon of Scala appeared beside the file.
I installed Scala Syntax (official) and Scala (Metals). Anyone any clue? Thanks.

Why do I keep getting java.lang.NoClassDefFoundError at main when I try to run scalafx code in eclipse?

Please I need help with this very simple example here. I can't get to run this without getting this annoying error messages
Exception in thread "main" java.lang.NoClassDefFoundError:
scalafx/application/JFXApp$class
at HelloScalaFX$.<init>(HelloScalaFX.scala:6)
at HelloScalaFX$.<clinit>(HelloScalaFX.scala)
at HelloScalaFX.main(HelloScalaFX.scala)
Caused by: java.lang.ClassNotFoundException: scalafx.application.JFXApp$class
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.Scene
import scalafx.scene.control.Label
object HelloScalaFX extends JFXApp {
stage = new PrimaryStage {
scene = new Scene {
content = new Label {
text = "Hello ScalaFX"
}
}
}
}
So, from experience, I can honestly say that if you press the run button on eclipse you should get a popup window that will often ask for a class to run. If not try and right click on your eclipse editor (where you wrote your code) go to run, check the options and select run configurations. At that point you will see what your main class is and what file you want to run. The main class usually starts with the name of the package the file is in ... it might be default if you did not name it and followed by dot name of the class like this your case it would be HelloScalaFx... if you do not see it written then you can type it in manually.
.
If this also fails... make sure your code contains the package name! after setting those configurations you should be able to run the program.

Problems with classloading when running JUnit plug-in tests in Eclipse

I have a problem when running JUnit Plug-in tests in Eclipse 4.3 and 4.2 and possible other versions. This worked in version 3.6 so I do not know what has changed.
The test are written using JUnit 4 and using parameterized tests (though I have tested with normal tests and the problem is the same). The test cases are written in YAML format and inflated at runtime using SnakeYAML.
When running the test as a normal JUnit test everything works fine, but when running the test as a JUnit Plug-in tests the test fails since it can no longer inflate objects from Yaml using SnakeYAML.
This is the code that reads test cases from YAML
public static ArrayList<StartsWithCommentTestCase> readTests(String filename) {
// set up how Java types match to the YAML file
Constructor testCaseConstructor = new Constructor(StartsWithCommentTestCase.class);
TypeDescription testCaseDesc = new TypeDescription(StartsWithCommentTestCase.class);
testCaseConstructor.addTypeDescription(testCaseDesc);
Yaml yamlParser = new Yaml(testCaseConstructor);
// read all the documents in the test file
String tests = TestUtils.readFile(filename);
ArrayList<StartsWithCommentTestCase> testCases = new ArrayList<StartsWithCommentTestCase>();
for (Object testCase : yamlParser.loadAll(new StringReader(tests))) {
testCases.add((StartsWithCommentTestCase) testCase);
}
return testCases;
}
#Test
public void bla(){
List<StartsWithCommentTestCase> tests = readTests(TEST_FILES_DIR + "starts-with-comment.yaml");
for(StartsWithCommentTestCase test : tests){
boolean actual = ToggleCommentHandler.startsWithComment( test.getLine() );
assertEquals( test.getName(), test.getExpected(), actual );
}
}
And this is the stacktrace that is received when running as a JUnit Plug-in test
Can't construct a java object for tag:yaml.org,2002:pde.test.tests.StartsWithCommentTestCase;exception=Class not found: pde.test.tests.StartsWithCommentTestCase
in "<reader>", line 4, column 1:
name: Empty line
^
at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:325)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:181)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:140)
at org.yaml.snakeyaml.constructor.BaseConstructor.getData(BaseConstructor.java:109)
at org.yaml.snakeyaml.Yaml$1.next(Yaml.java:317)
at pde.test.tests.StartsWithCommentTest.readTests(StartsWithCommentTest.java:86)
at pde.test.tests.StartsWithCommentTest.bla(StartsWithCommentTest.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:62)
at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethodWithException(EclipseAppContainer.java:587)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:198)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
at org.eclipse.equinox.launcher.Main.main(Main.java:1426)
Caused by: org.yaml.snakeyaml.error.YAMLException: Class not found: pde.test.tests.StartsWithCommentTestCase
at org.yaml.snakeyaml.constructor.Constructor.getClassForNode(Constructor.java:625)
at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.getConstructor(Constructor.java:313)
at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:323)
... 49 more
The strange thing (for me at least) is that I can make a StartsWithCommentTestCase object with
new StartsWithCommentTestCase()
without any problem also when running as a plugin test. In otherwords the class is avaiable at runtime, but for some reason not available to SnakeYAML.
Any pointers on this would be very helpful :)
Edit 1
The first lines of the YAML file:
#all the lines must have newlines in them since newlines are returned
#by Document.get()
---
name: Empty line
line:
expected: false
---
name: "Line where first character is #"
line: "#
"
expected: true
Edit 2
Added more code to the sample.
It looks like the Junit plugin don't know how to read the SnakeYAML code. Are you sure the class-loader of SnakeYAML is correctly initialized when you run the tests through the plug in?
And how does the mentioned line 4 look in your YAML code? Is it empty?
Maybe the junit plugin uses another jar dependency than your ordinary setup. Which maven binary/path does the junit plugin use? Is this the same as your ordinary one? If you have different m2-configurations or even different repos there will be strange issues.
I found out that this is because I had moved the SnakeYAML dependency to another plugin. SnakeYAML was then part of another plugin with a different class loader than the test plugin.
The solution was to add the following to the META-INF/MANIFEST.MF file in the dependeny plugin
Eclipse-BuddyPolicy: registered
And the following to the META-INF/MANIFEST.MF file in the test plugin
Eclipse-RegisterBuddy: <symbolic name of the dependency plugin>
Now on to see if I can move the SnakeYAML dependency back into a lib/ folder or similar.

How to set environmental variable from Scala?

I need to set environmental variable (PATH) from Scala.
I tried this:
val cmd = Seq("export", "PATH='bla'")
cmd.lines
but I got error:
java.io.IOException: Cannot run program "export": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1041)
at scala.sys.process.ProcessBuilderImpl$Simple.run(ProcessBuilderImpl.scala:68)
at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.lines(ProcessBuilderImpl.scala:140)
at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.lines(ProcessBuilderImpl.scala:106)
at .<init>(<console>:12)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:914)
at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:546)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:577)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:543)
at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:694)
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:745)
at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:651)
at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:542)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:550)
at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:822)
at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:851)
at xsbt.ConsoleInterface.run(ConsoleInterface.scala:57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:73)
at sbt.compiler.AnalyzingCompiler.console(AnalyzingCompiler.scala:64)
at sbt.Console.console0$1(Console.scala:23)
at sbt.Console$$anonfun$apply$2$$anonfun$apply$1.apply$mcV$sp(Console.scala:24)
at sbt.TrapExit$.executeMain$1(TrapExit.scala:33)
at sbt.TrapExit$$anon$1.run(TrapExit.scala:42)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:135)
at java.lang.ProcessImpl.start(ProcessImpl.java:130)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1022)
... 35 more
Is there some other way to do that?
Example from doc for sys.process.Process:
apply("java", new java.ioFile("/opt/app"), "CLASSPATH" -> "library.jar")
Edit for more helpful verbiage:
That is, you specify the env when you spawn a child process.
The environment of the current process is read-only; see System.getenv, or compare the abstractions sys.props and sys.env.
The fact that a shell augments the environment it bestows on subshells with exported variables is a shell convention. See 3.7.4 in the bash reference, for example:
On invocation, the shell scans its own environment and creates a
parameter for each name found, automatically marking it for export to
child processes. Executed commands inherit the environment. The export
and ‘declare -x’ commands allow parameters and functions to be added
to and deleted from the environment. If the value of a parameter in
the environment is modified, the new value becomes part of the
environment, replacing the old. The environment inherited by any
executed command consists of the shell's initial environment, whose
values may be modified in the shell, less any pairs removed by the
unset and ‘export -n’ commands, plus any additions via the export and
‘declare -x’ commands.
This is the first time my answer was longer than the Daniel Sobral answer it duplicates.
'export' isn't an executable, it's a shell built-in command. If you're trying to set the path in the parent shell, well, you can't. You can set it for a new shell that you execute. This is really more of a unix FAQ.

Formatting a simple string, but `java.lang.NoSuchMethodError`

I'm using Scala 2.9.2.
Run Scala and test a simple code, this code is… OK:
...
val title = "Hashing file (%s)..." format sizeToStr(file.length)
But I couldn't understand what is what, while I put that code into a simple app, compiling OK, at runtime it throws this one:
java.lang.NoSuchMethodError: scala.Predef$.augmentString(Ljava/lang/String;)Lscala/collection/immutable/StringOps;
at group.pals.penguin.app.shasher.Shasher$.calcHash(shasher.scala:119)
at group.pals.penguin.app.shasher.Shasher$.main(shasher.scala:76)
at group.pals.penguin.app.shasher.Shasher.main(shasher.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:71)
at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:139)
at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:71)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:139)
at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:28)
at scala.tools.nsc.JarRunner$.run(MainGenericRunner.scala:16)
at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:35)
at scala.tools.nsc.JarRunner$.runAndCatch(MainGenericRunner.scala:16)
at scala.tools.nsc.JarRunner$.runJar(MainGenericRunner.scala:28)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:78)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Could you please help me out? Thanks.
It seems like you're compiling against a different version of the standard library than you're using at runtime.