IntelliJ IDEA / Scala - cannot read resources - scala

I have had this problem before, but it has been a while. Now it resurfaced: I am having an sbt-build based Scala project in IntelliJ IDEA, and when I launch a run config, the program does not find resources via getResource or getResourceAsStream. It did work before, so definitely the paths in my code are correct. For example, here is a view of the project browser:
You can see that the resources directory is correctly marked, and so "/at/iem/sysson/color-tables.bin" should be found. Here is the reader code:
package at.iem.sysson
object Main {
lazy val colorTables: Map[String, ColorPaletteTable] = {
val is = Main.getClass.getResourceAsStream("color-tables.bin")
...
}
}
This used to work in IntelliJ, it still works when running through sbt or creating a standalone application. But now with my run config from IntelliJ it is broken - getResourceAsStream returns null.
I have already deleted the .idea project and recreated it from scratch. I have also quit and restarted IntelliJ. The resources are definitely marked:
What's wrong? It looks related to this, but deleting and recreating the run configuration does not help. I do get /usr/bin/java -Didea.launcher.port=7537 ..., but the resources directory is simply missing from the -classpath.

The same has just happened to me (IntelliJ IDEA 2016.3.5).
When I looked into the target/scala-2.11/classes dir, the resource dirs/files were missing.
Just rebuilding the project didn't help, but deleting target/scala-2.11/classes and rebuilding did.

Related

Error: Could not find or load main class Main Scala

I've recently installed Scala as a part of my functional programming course and I've encountered a problem: IntelliJ IDEA 2017.2.1 (Java version 9, build 9+181) doesn't run any of my scala code, exitting with
Error: Could not find or load main class Main
This code is an example.
object Main {
def length[A](list:List[A]):Int = {
if (list == Nil) 0
else 1 + length(list.tail)
}
def main(args: Array[String]): Unit = {
length(List[Int](1, 4, 5, 12, -1))
}
}
It's really simple, yet IntelliJ refuses to run it. Windows CMD doesn't even react to a scala command, resulting into
'scala' is not recognized as an internal or external command,
operable program or batch file.
even though I have it installed on my computer. If I call Scala Console inside of IntelliJ everything works fine and compiles as expected. I've tried switching to JDK 1.8 inside of IntelliJ, yet it led to no result.
What could be the problem?
For me it turns out that the src/main was not marked as Sources Root
which causes the following error
...
One of the two will be used. Which one is undefined.
Error: Could not find or load main class Main
Process finished with exit code 1
So of course after I mark the src/main as Sources Root, the Scala Hello World example runs happy again.
Notice the blue color of directory src/main when it's marked as Sources Root
Are you using the little green arrow to run the program from inside of your Main object?
How did you create the program? It could be that your build file SBT configuration of the project is a different Scala version than what's installed on your computer.
It's really simple, yet IntelliJ refuses to run it. Windows CMD
doesn't even react to a scala command, resulting into
'scala' is not recognized as an internal or external command, operable program or batch file.
This means that Scala is not added to your class path in your terminal. Look up how to do that and see if that doesn't help out your IntelliJ problem too.

Debugging OfBiz in Eclipse gives MissingResourceException

I downloaded the OfBiz Java application and the following line throws an MissingResourceException:
ResourceBundle res = ResourceBundle.getBundle(settingsResourceName);
The value of settingsResourceName is "cache", but I cannot find any file called cache.properties or cache_en.properties.
Where should I be looking? I'm new to Java. All my research on SO says there should be such a file.
I imported OfBiz in Eclipse using the Import menu option and selecting Existing Project from File System (I'm not in front of my dev machine so I don't remember the exact wording). But I chose the root folder of the downloaded OfBiz.
I then added the appropriate VM Arguments in the Run Configuration to get it to run properly at least. And that's it, on the first Run I got the above error. I think it has to do with a missing class path but I don't know what to add to class path.
Here is the stack trace:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.apache.ofbiz.base.util.Debug.<clinit>(Debug.java:68)
at org.apache.ofbiz.base.container.ContainerLoader.load(ContainerLoader.java:61)
at org.apache.ofbiz.base.start.StartupControlPanel.loadStartupLoaders(StartupControlPanel.java:202)
at org.apache.ofbiz.base.start.StartupControlPanel.start(StartupControlPanel.java:69)
at org.apache.ofbiz.base.start.Start.main(Start.java:84)
Caused by: java.util.MissingResourceException: Can't find bundle for base name cache, locale en
at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1564)
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1387)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:773)
at org.apache.ofbiz.base.util.cache.UtilCache.setPropertiesParams(UtilCache.java:174)
at org.apache.ofbiz.base.util.cache.UtilCache.setPropertiesParams(UtilCache.java:170)
at org.apache.ofbiz.base.util.cache.UtilCache.setPropertiesParams(UtilCache.java:166)
at org.apache.ofbiz.base.util.cache.UtilCache.<init>(UtilCache.java:124)
at org.apache.ofbiz.base.util.cache.UtilCache.createUtilCache(UtilCache.java:769)
at org.apache.ofbiz.base.util.UtilProperties.<clinit>(UtilProperties.java:75)
... 5 more
UPDATE:
My mistake, I found two files both called cache.properties in the following folders:
ofbiz-trunk/build/resources/main
ofbiz-trunk/framework/base/config
But these are folders, not packages. I tried putting them in the .classpath but that did not work, I still kept getting the same error.
As suspected, I knew it was because of a missing reference to a class path. After looking at a section on this page: http://www.opensourcestrategies.com/ofbiz/ofbiz_eclipse.php, I learned that I was supposed to go to the Java Build Path and in the Libraries tab, click on Add Class Folder, then point that to ofbiz-trunk/framework/base/config. Which is where I have one of the cache.properties files.

Watch for project files also

I use sbt in the following fashion: I run ~ test:compile in sbt and then work in IDE, watching occasionaly if the project still compiles, because the IDE's presentation compiler tends to be buggy. When I git pull some code, there might be changes in the project/ files, so I want to have reload. Is there a way, how to watch both source files and project files, so when there is change in project files, I actually get the update?
As jsuereth explained this isn't a task SBT can handle in 1 instance. What's required is a reboot of SBT to abort the watching process and reload it's own configuration.
The following Scala script does exactly this, it uses Java NIO WatchService and Scala Process to monitor a path and restart a process. The code should be fairly simple to understand:
#!/usr/bin/env scala
import java.nio.file._
import scala.collection.JavaConversions._
import scala.sys.process._
val file = Paths.get(args(0))
val cmd = args(1)
val watcher = FileSystems.getDefault.newWatchService
file.register(
watcher,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE
)
def exec = cmd run true
#scala.annotation.tailrec
def watch(proc: Process): Unit = {
val key = watcher.take
val events = key.pollEvents
val newProc =
if (!events.isEmpty) {
proc.destroy()
exec
} else proc
if (key.reset) watch(newProc)
else println("aborted")
}
watch(exec)
Usage in your sbt dir would be:
watchr.scala project/ "sbt ~ test:compile"
If anything is unclear don't hesitate to ask, of course any scripting language could be used to implement this behavior.
You actually can't use ~ <task> and have it rebuild the project itself right now, because ~ <task> needs to read the build definition itself to determine:
What source files to watch
How to run the task.
What you're doing is altering the config whe project/ changes. This requires a full reload or reboot of sbt to pull in the new configuration.
So, as of sbt 0.13, this isn't possible. You can have it so it will rebuild your source code when project/ changes, but without rebuilding the build definition, not much help.
You could create a new sbt prompt, or task, that when run could check to see if source files in project/ are updated and issue a warning/error so you know to reboot. That's probably the best option right now.

Unable to use a class from a package in /lib directory

I did a simple thing: I put a jar file I've made myself into /lib directory of a Play application. However, it doesn't work:
def index = Action {
val a = new com.mypackage.Class123 // error! not found Class123
Ok(views.html.index("hello"))
}
It already said sbt, compile, gen-idea but everything is still the same.
By the way, the file /lib/mypackage.jar is 38Mb for some reason.
Try reload in sbt. This is needed to rescan the build file; it might also be needed to rescan the lib directory (I'm not sure).

Scala project won't compile in Eclipse; "Could not find the main class."

I have installed Eclipse 3.5.2 and today's Scala plugin from /update-current (that's Scala 2.8 final.) I can compile and run Scala projects consisting of a single singleton object that implements main().
But, if a project contains more classes, I receive the "Could not find the main class" error.
I have tried searching for the solution and I discovered:
Eclipse is correctly looking for the Main$ class, not the Main class
* under Debug Configurations, my main class is correctly identified as mypackage.Main
* my plugin is up to date and recommended for my version of Eclipse
* cleaning, restarting etc. doesn't help.
The same project will compile with scalac.
Thanks for any ideas on how to solve this.
EDIT: MatthieuF suggested I should post the code.
This snippet produces an error. It's not the most idiomatic code, but I wrote it that way to test my environment. I tried it as a single file and as separate files. It DOES work with scalac.
import swing._
class HelloFrame extends Frame {
title = "First program"
contents = new Label("Hello, world!")
}
object Hello {
val frame = new HelloFrame
def main(args : Array[String]) : Unit = {
frame.visible = true
}
}
BUT, if I nest the definition of HelloFrame within Hello, it works. This snippet runs perfectly:
import swing._
object Hello {
class HelloFrame extends Frame {
title = "First program"
contents = new Label("Hello, world!")
}
val frame = new HelloFrame
def main(args : Array[String]) : Unit = {
frame.visible = true
}
}
For me, the problem was that there was a build error (see Problems tab) which was preventing compilation; oops! The reason you see the error is that the run macro proceeds despite the failed compilation step, and attempts to run class files it expects to be there; they don't exist because there was a build error preventing compilation, so it says it can't find Main (not compiled).
Problem goes away when build can complete successfully, i.e. errors are fixed.
I guess, theoretically, there may be more complicated reasons your build is not completing successfully that are not listed in Problems.
One possibility is that you are trying to launch using ctrl-F11, but from a different class.
The Scala Eclipse plugin does not obey the defaults for Java launching. In Preferences->Run/Debug->Launching, there are some options Launch Operation->Always Launch the previously selected application, etc. This currently does not work in the Scala eclipse plugin. To launch a specified main, you need to launch it from the editor for the class.
There has been a bug raised for this. http://scala-ide.assembla.com/spaces/scala-ide/tickets/1000023-scala-launch--does-not-follow-jdt-behaviour
EDIT: This is now (mostly) fixed.
For me it was Eclipse specific problem. I noticed that .class file wasn't built at all. So bin directory doesn't have compiled classes.
When I manually compiled *.scala file using *.sbt and copied it to bin directory it was working as expected.
I tried different tips and tricks and it wasn't worked until I reinstalled Scala plugin in Eclipse .
I'd solve similar problem by executig "Project->Clean.." with next automatically building.
I had the same error message with a Java application made by myself.
The problem was that I deleted (though inside Eclipse) a jar that belonged to the Java build path, without deleting it from the Java build path (project's Properties window). When I did it the class could compile and run again.
Make sure that the .class files exist, usually below the bin directory.
In particular, if you have errors in unrelated files in the same project then the compilation may fail, and no .class files will be produced.
There can be the case of projects, containing errors, added to the build path of the application which prevents the completion of successful compilation. Make sure you remove any such project from the build path before running the application.
Removing these projects solved the problem for me.
Do you have a proper build tool setup? Like sbt have you installed it?
You can check its version by $sbt --version
If it is not setup you can download from here http://www.scala-sbt.org/download.html
You might have to restart your eclipse after installation.
Just copy your XXX.scala file code. Remove the package and create a new Scala Class. Paste your XXX.scala code. (If you are using maven, do a maven clean and build.) Run configuration again. This works for me.
I have faced this issue. I have just deleted the package name, created scala class, Written the same code, Set Build to "Build Automatically". Finally, It works perfectly fine.
Check scala-ide.log
For me the issue was that there were errors on:
AppData\Local\Temp\sbt_10d322fb\xsbt\ClassName.scala:16: error: not found: value enteringPhase
enteringPhase(currentRun.flattenPhase.next) { s fullName separator }
If you are using Intellij, mark directory as source root