Unable to compile unless .jar is included in bootclasspath - classpath

I'm trying to build an android project with gradle: it's a library project with ndk flavor, spiced with an external .jar, courtesy of Unity.
I don't really think that the details about the gradle file are important, suffices to say that I'm including the external jar file (provided by Unity) with something like:
dependencies {
compile files('libs/unity.jar')
}
which actually seems to work, as during the java compilation, gradle issues a command like:
BASE="<Some directory>"
javac -d "${BASE}/PluginsSources/Android/libproject/build/intermediates/classes/fat/debug" \
-g -encoding UTF-8 \
-bootclasspath /Users/myusername/Applications/adt/sdk/platforms/android-23/android.jar \
-sourcepath "${BASE}/PluginsSources/Android/libproject/build/tmp/compileFatDebugJavaWithJavac/emptySourcePathRef" \
-classpath "${BASE}/PluginsSources/Android/libproject/libs/unity.jar" \
"${BASE}/PluginsSources/Android/libproject/src/main/java/org/example/ScriptBridge/JavaClass.java" \
"${BASE}/PluginsSources/Android/libproject/build/generated/source/r/fat/debug/org/example/ScriptBridge/R.java" \
"${BASE}/PluginsSources/Android/libproject/build/generated/source/buildConfig/fat/debug/org/example/ScriptBridge/BuildConfig.java" \
-XDuseUnsharedTable=true
indentation and BASE variable added by yours truly. Note that unity.jar is a classpath entry.
Problem is, the compilation fails as javac is apparently unable to find a class in unity.jar when compiling, unless that jar is put into the -bootclasspath option (!!).
Why does this happen? AFAIK, the search path for the classes should be hierarchic and after bootclasspath, javac should be searching classpath...
Is it possible to tell gradle to stick some jar into the bootclasspath somhow (this would clumsily solve the issue)?
Is it there a cleaner/better way?
Thank you for any insight!

EDIT:
After a closer scrutiny, it looks like that classpath works (surprise!) and Unity Technologies didn't create a mutant-classpath-resilient jar as it's first step to take over the world, after all...
The problem was in the path to the compile statement, after replacing it with the correct relative path to the jar, everything worked as expected.
The answers to the question's point are:
Q1: Why does this happen?
Because java cannot find a class in a jar that doesn't exist
Q2: Is it possible to tell gradle to stick some jar into the bootclasspath somhow?
See the answer below
Q3: is there a cleaner/better way?
Yeah: making sure that the path to whatever you are linking is correct might be a good start :)
Note that gradle will not issue any error for missing jars, not even in debug mode (which is an infamy IMHO).
OLD ANSWER
I got to solve the issue myself, somehow (I don't think that my workaround is optimal, but given the attention on this question I guess it's as good as it's gonna get...)
Q1: Why does this happen?
There is no flipping reason, as far as I understand.
The document:
How Classes are Found (Oracle canon)
clearly specifies that the classes in bootstrap are:
Bootstrap classes are the classes that implement the Java 2 Platform.
that is, the classes used to implement the platform. That's why android.jar is there, and unity.jar should not.
Q2: Is it possible to tell gradle to stick some jar into the bootclasspath somhow?
Yes! The following link details how:
Modify bootclasspath in compiler args (gradle forums)
and that is:
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "Xbootclasspath/a:src/main/libs/unity.jar"
}
}
}
which, in my projects maps to loading a unity.jar archive after the android one, located in the src/main/libs directory of my android library.
Q3: is there a cleaner/better way?
I don't think so, at least not without understanding why the jar needs to be in bootstrap in the first place (which would make most of the issues here pointless): changing the bootstrap classpath is not something the high level programmer should do, so I don't expect gradle to provide a cleaner shortcut.
I'm still waiting for someone with some insights about the issue (I can't sink more of my time on this), but I hope this will help someone anyway.

Related

Possible to compile and run scala-akka scripts from command-line without build tools like sbt?

I am a beginner learning to program in scala-akka and I have had no problems running my scripts on IntelliJ IDE / and 'sbt run'. However, I can't seem to find any resources that teaches me how to manually use scalac and the akka jar dependency to compile and run just from the command-line. Can anyone point me in the right direction?
Let's assume you have Scala and Akka installed somewhere under /home/leo/apps/ and Scala binaries are searchable (e.g. export PATH=$PATH:home/leo/apps/scala-2.11.8/bin)
Next, let's say you have a Scala main app Tweets.scala along with a few supplementary classes packaged in akkastreams under /home/leo/myproject/:
akkastreams/
Tweets.scala
Author.scala
HashTag.scala
Message.scala
...
Here's how you'll compile and run the app:
cd /home/leo/myproject/
# Compile all files in package akkastreams:
scalac -cp "/home/leo/apps/akka-2.4.9/lib/akka/*" akkastreams/*.scala
# Run the main app Tweets (object Tweets extends App):
# Note that classpath includes also current subdir '.'
scala -cp "/home/leo/apps/akka-2.4.9/lib/akka/*:." akkastreams.Tweets
A few notes:
You could include only specific Akka jars instead of all of them.
Without dependencies and versioning being managed by sbt, you'll need to manually maintain version consistency between Scala's bundled Akka libraries versus Akka's own ones.
While it's a good exercise to see how things are done in a crude way, it's obviously unproductive to do this on a regular basis.
In my opinion You should perform scalac and scala with classpath parameter and selected library jar file.
By the way it's still more convenient to use sbt.

IntelliJ IDEA / Scala: run configuration miss resources on class path

I have this problem on an off since quite while without ever understanding what is going on: I import an sbt-based project in IntelliJ, and when running it from within IntelliJ, it seems to be missing project resources (src/main/resources) on the class path, resulting in .getClass.getResource(...) calls to return null.
I tend to delete .idea and create the project anew as I'm suspecting a caching problem from upgrading an existing .idea from previous IntelliJ version. But no luck today. Sometimes changing .getResource to .getResourceAsStream seems to solve it, but again no luck today.
Checking the project settings, the directory is correctly toggled as 'Resources':
And checking the run configuration, the module/class-path is correctly selected:
Needless to say, using sbt test:run from the terminal works as expected, resources are found.
FWIF, here is the run call from IDEA, where I cannot find the resources in the classpath at all:
/usr/lib/jvm/java-8-oracle/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:47427,suspend=y,server=n -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/java-8-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-8-oracle/jre/lib/deploy.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jaccess.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jfxrt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/nashorn.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-8-oracle/jre/lib/javaws.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfr.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfxswt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-8-oracle/jre/lib/management-agent.jar:/usr/lib/jvm/java-8-oracle/jre/lib/plugin.jar:/usr/lib/jvm/java-8-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-8-oracle/jre/lib/rt.jar:/home/hhrutz/Documents/devel/Wolkenpumpe/target/scala-2.11/test-classes:/home/hhrutz/Documents/devel/Wolkenpumpe/target/scala-2.11/classes:/home/hhrutz/.ivy2/cache/com.github.scopt/scopt_2.11/jars/scopt_2.11-3.4.0.jar:/home/hhrutz/.ivy2/cache/org.slf4j/slf4j-simple/jars/slf4j-simple-1.7.18.jar:/home/hhrutz/.ivy2/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.7.18.jar:/home/hhrutz/.ivy2/cache/org.scalatest/scalatest_2.11/bundles/scalatest_2.11-2.2.6.jar:/home/hhrutz/.ivy2/cache/org.scala-stm/scala-stm_2.11/jars/scala-stm_2.11-0.7.jar:/home/hhrutz/.ivy2/cache/org.scala-lang.modules/scala-xml_2.11/bundles/scala-xml_2.11-1.0.5.jar:/home/hhrutz/.ivy2/cache/org.scala-lang.modules/scala-swing_2.11/bundles/scala-swing_2.11-1.0.2.jar:/home/hhrutz/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.11.7.jar:/home/hhrutz/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.8.jar:/home/hhrutz/.ivy2/cache/net.sourceforge.jtransforms/jtransforms/jars/jtransforms-2.4.0.jar:/home/hhrutz/.ivy2/cache/net.htmlparser.jericho/jericho-html/jars/jericho-html-3.3.jar:/home/hhrutz/.ivy2/cache/lucene/lucene/jars/lucene-1.4.3.jar:/home/hhrutz/.ivy2/cache/junit/junit/jars/junit-4.8.2.jar:/home/hhrutz/.ivy2/local/de.sciss/weblaf-ui/2.1.0/jars/weblaf-ui.jar:/home/hhrutz/.ivy2/local/de.sciss/weblaf-core/2.1.0/jars/weblaf-core.jar:/home/hhrutz/.ivy2/local/de.sciss/treetable-scala_2.11/1.3.8/jars/treetable-scala_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/treetable-java/1.3.8/jars/treetable-java.jar:/home/hhrutz/.ivy2/cache/de.sciss/topology_2.11/jars/topology_2.11-1.0.0.jar:/home/hhrutz/.ivy2/local/de.sciss/swingplus_2.11/0.2.1/jars/swingplus_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/submin/0.2.0/jars/submin.jar:/home/hhrutz/.ivy2/cache/de.sciss/span_2.11/jars/span_2.11-1.3.1.jar:/home/hhrutz/.ivy2/local/de.sciss/soundprocesses-views_2.11/3.4.0/jars/soundprocesses-views_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/soundprocesses-core_2.11/3.4.0/jars/soundprocesses-core_2.11.jar:/home/hhrutz/.ivy2/cache/de.sciss/serial_2.11/jars/serial_2.11-1.0.2.jar:/home/hhrutz/.ivy2/cache/de.sciss/scissdsp_2.11/jars/scissdsp_2.11-1.2.2.jar:/home/hhrutz/.ivy2/local/de.sciss/scalaosc_2.11/1.1.5/jars/scalaosc_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/scalacolliderugens-plugins_2.11/1.14.1/jars/scalacolliderugens-plugins_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/scalacolliderugens-core_2.11/1.14.1/jars/scalacolliderugens-core_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/scalacolliderugens-api_2.11/1.14.1/jars/scalacolliderugens-api_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/scalacolliderswing-core_2.11/1.28.0/jars/scalacolliderswing-core_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/scalacollider_2.11/1.18.1/jars/scalacollider_2.11.jar:/home/hhrutz/.ivy2/cache/de.sciss/scalaaudiofile_2.11/jars/scalaaudiofile_2.11-1.4.5.jar:/home/hhrutz/.ivy2/local/de.sciss/raphael-icons_2.11/1.0.3/jars/raphael-icons_2.11.jar:/home/hhrutz/.ivy2/cache/de.sciss/processor_2.11/jars/processor_2.11-0.4.0.jar:/home/hhrutz/.ivy2/local/de.sciss/prefuse-core/1.0.1/jars/prefuse-core.jar:/home/hhrutz/.ivy2/cache/de.sciss/numbers_2.11/jars/numbers_2.11-0.1.1.jar:/home/hhrutz/.ivy2/cache/de.sciss/model_2.11/jars/model_2.11-0.3.2.jar:/home/hhrutz/.ivy2/local/de.sciss/lucresynth_2.11/3.4.0/jars/lucresynth_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/lucreswing_2.11/1.3.0/jars/lucreswing_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/lucre-expr_2.11/3.3.1/jars/lucre-expr_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/lucre-core_2.11/3.3.1/jars/lucre-core_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/lucre-confluent_2.11/3.3.1/jars/lucre-confluent_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/lucre-bdb_2.11/3.3.1/jars/lucre-bdb_2.11.jar:/home/hhrutz/.ivy2/cache/de.sciss/intensitypalette/jars/intensitypalette-1.0.0.jar:/home/hhrutz/.ivy2/cache/de.sciss/fingertree_2.11/jars/fingertree_2.11-1.5.2.jar:/home/hhrutz/.ivy2/cache/de.sciss/fileutil_2.11/jars/fileutil_2.11-1.1.1.jar:/home/hhrutz/.ivy2/local/de.sciss/desktop_2.11/0.7.2/jars/desktop_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/audiowidgets-swing_2.11/1.9.4/jars/audiowidgets-swing_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/audiowidgets-core_2.11/1.9.4/jars/audiowidgets-core_2.11.jar:/home/hhrutz/.ivy2/local/de.sciss/audiowidgets-app_2.11/1.9.2/jars/audiowidgets-app_2.11.jar:/home/hhrutz/.ivy2/cache/com.thoughtworks.xstream/xstream/jars/xstream-1.4.8.jar:/home/hhrutz/.ivy2/cache/com.sleepycat/je/jars/je-5.0.104.jar:/home/hhrutz/.ivy2/cache/com.mortennobel/java-image-scaling/jars/java-image-scaling-0.8.6.jar:/home/hhrutz/.ivy2/cache/com.jhlabs/filters/jars/filters-2.0.235.jar:/home/hhrutz/Applications/idea-IC-16/lib/idea_rt.jar de.sciss.nuages.Demo
Deleting the run configuration and creating it anew "fixed" the problem. It seems to be a bug in IntelliJ, perhaps related to caching or indexing.
The previous broken call was:
java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:47427,suspend=y,server=n \
-classpath ... \
de.sciss.nuages.Demo
The new correct call became:
java -Didea.launcher.port=7534 \
-Didea.launcher.bin.path=/home/hhrutz/Applications/idea-IC-16/bin \
-classpath ... \
com.intellij.rt.execution.application.AppMain de.sciss.nuages.Demo
So while the classpath is same, the launching mechanism is completely different.

scala & intellij : difficulties to create a runnnable jar

I can't launch a scala jar; when I launch it I get the error "Exception in thread "main" java.lang.NoClassDefFoundError: scala/collection/immutable/List" which seems to mean the scala library is not loaded...
this is a screenshot showing a lot of informations on the artifact window.
here is the manifest:
Manifest-Version: 1.0
Class-Path: libs/scala-library-2.10.0.jar libs/commons-logging-1.1.1.j
ar libs/jcip-annotations-1.0.jar libs/jwnl-1.4_rc3.jar libs/laf-plugi
n-7.2.1.jar libs/laf-widget-7.2.1.jar libs/miglayout-core-4.2.jar lib
s/miglayout-swing-4.2.jar libs/scala-actors.jar libs/scala-library.ja
r libs/scala-swing.jar libs/slf4j-api-1.6.4.jar libs/slick_2.10-1.0.0
.jar libs/sqlite-jdbc-3.7.2.jar libs/substance-7.2.1.jar libs/trident
-7.2.1-swing.jar
Main-Class: Fenetre
and when I enter "java xf myJar.jar", there are extracted files in the directory:
- .class files
- in the libs folder, there are the libraries INCLUDING scala-library.jar & scala-library-2.10.0.jar(I specified only one of these two files in the manifest to avoid conflicts)
can you help me?
I'm new to Scala and don't know what the problem is however I've been compiling "fat jars" which include all the required libs.
I've been using https://github.com/sbt/sbt-assembly to do this successfully.
Despite what your manifest is telling you, when you run the application you either do not have the scala-library included in your class path or there's some confusion when you attempt to import List. Scala should automatically import the immutable collection classes in your project with the root Predef implementation.
Predef provides type aliases for types which are commonly used, such as the immutable collection types scala.collection.immutable.Map, scala.collection.immutable.Set, and the scala.collection.immutable.List constructors (scala.collection.immutable.:: and scala.collection.immutable.Nil). The types Pair (a scala.Tuple2) and Triple (a scala.Tuple3), with simple constructors, are also provided.
Predef in core Scaladocs
Try printing the classpath from within your app to confirm.
Although not pertinent to your question, I would recommend using SBT for dependency management now that IntelliJ IDEA 13 has full SBT integration support. Your collaborators not using IntelliJ will also be happier because SBT gives them more options for build technologies, editors, and other tooling when working on the project.

Getting IntelliJ IDEA understand SBT dependencies

I have SBT and Scala installed and things work well.
Now I have an IntellIJ IDEA project, which works otherwise OK except that dependencies which are downloaded into /Users/MyName/.ivy2/cache/ are not understood.
I tried setting the cache path as a source folder:
but still things don't work out:
As you can see, org.eclipse is in red color meaning it can't find it. It must be inside that .jar file I showed on the left.
I just want to update/download dependencies using SBT, and then get the compilation to work in IntelliJ IDEA with those dependencies.
Use the sbt-idea plugin for SBT. Then you can run "gen-idea" from the sbt command line and it will generate the metadata files used by IDEA. These files contain the locations of jars as SBT uses them so that IDEA will know where the dependencies are, just like SBT.

scala compilation problem - with java libs

Im trying to put together a simple ant build file for compiling a scala project (scala 2.7.6)...
I have everything working correctly except that its bringing up the
"fatal error: class java.lang.Object not found." both the scalac and scala libs are all in the project folder, so Im refering to them relativelly to the project root.
Im hoping that someone could help with which command line scalac option I can use to point the compiler towards the java core lib (if thats what it needs). Im hoping not to use any environemnt variables, and instead have the needed java libs in my project root folder...
that way I can have everything needed to compile movable with the project, and not need any setup for others to be able to compile
thank you
Scala 2.7.6 is a broken release.
Please upgrade to 2.7.7
Also, do you have javac on PATH and JAVA_HOME set?