Sbt Assembly Include Conf Files inside the JAR - scala

I'm using the sbt assembly plugin to create a JAR file and I have the following folder structure:
src
-main
-scala
-resources
-application.conf
Now, when I do
sbt clean assembly
I can see in the produced Jar file that the application.conf file is included. I have two questions:
Why is the inluded application.conf not inside the resources folder in the final Jar, but rather it is on the top level as shown below (the contents of the Jar)
drwxr-xr-x 3 joe staff 102B May 16 21:03 com/
-rw-r--r-- 1 joe staff 187B Mar 4 2016 library.properties
drwxr-xr-x 3 joe staff 102B May 16 21:03 typesafe/
How can I load this application.conf by setting a System.property? For example., I want to be able to load the application.conf by setting a System property like:
System.setProperty("config.file", "application.default.conf")
With this I could control from outside (while running the jar file), which config file to use. When I tried this, I got a NulPointerException:
val someConfigFile = Option(System.getProperty("config.file"))
ConfigFactory.parseURL(getClass.getResource(someConfigFile.get)) // NullPointerException happens here...

The answer to your first question is that the resources folder is like a src folder and so the content is copied, not the folder itself.

Here is what I needed to do so that the config file inside the jar could be loaded based on what I specify from outside!
val is = new InputStreamReader(getClass.getResourceAsStream(s"/$cfgFile"))
ConfigFactory.parseReader(is).resolve()

Related

How to specify the main class (in the root directory) for Mill to run?

I am new to the sbt and mill, and I am practicing to use both tool to build the chisel (scala project). View this github repo as a reference, I am wondering to know how to write the mill-version build.sh in that repo.
Here is my directory structure
─ chisel-template (root directory / projects directory)
├── build.sc
├── build.sh
├── src
| └─main
| └─scala
| └─lab1
| └─Mux2.scala
└── _temphelper.scala
What the build.sh do is preparing a boilerplate as main function in the root directory to make compile and run process much easier, and it's sbt version. I'm curious that why sbt can detect the main function (_temphelper.Elaborate) even it's not in the src/main directory. And when I change to use Mill, Mill can't detect the _temphelper.scala at all, unless I move the file to root/src/main. Is there settings that can make Mill do what sbt can do?
I'm not sure whether this issue is related to...
altering the sourceDirectories in sbt and chiselMoudule.sources in Mill. Any advice is welcome.
modify the millSourcePath to realize my request.
My quetions is What setting should I do to make mill can detect the main class that be in the root directory?
This is because sbt is including any Scala files it finds in the project root directory as sources files, unless told otherwise.
In contrast, Mill will only use the source files found under whatever directories are specified with sources. As a consequence, you may want to add the project root directory as source directory, but I strongly advice to do not so.
Best is to move the _temphelper.scala file either to one of the source directories or create a new dedicated directory, move the file there and add this directory to the sources like this:
object chiselModule extends CrossSbtModule // ...
{
def sources = T.sources {
super.sources() ++ Seq(PathRef(T.workspace / "your" / "new" / "directory"))
}
}

Can I run sbt new with a local template (not GitHub)?

I work in a secure environment where developers are not allowed to git-clone from GitHub, or any other external repos.
I was able to download a g8 template (play-scala-seed) from GitHub as a zip file and I've unzipped it to a local folder. Can I use that local directory instead of a git repo?
My first attempt at this failed:
> dir .\play-scala-seed
Volume in drive C is OSDisk
Volume Serial Number is A074-A016
Directory of C:\workspace\play-scala-seed
03/22/2018 11:03 AM <DIR> .
03/22/2018 11:03 AM <DIR> ..
03/22/2018 11:01 AM <DIR> project
03/22/2018 10:57 AM <DIR> src
03/22/2018 11:03 AM <DIR> target
03/22/2018 10:57 AM 70 .gitignore
03/22/2018 10:57 AM 509 .travis.yml
03/22/2018 10:57 AM 453 build.sbt
03/22/2018 10:57 AM 439 LICENSE
03/22/2018 10:57 AM 1,166 README.md
5 File(s) 2,637 bytes
5 Dir(s) 220,172,980,224 bytes free
Even though I'm sure the template exists and in in a directory called "play-scala-seed", it's not accepted by the SBT new command:
> sbt new .\play-scala-seed
Template not found for: .\play-scala-seed
So how can I make sbt new use a local directory for a g8 template?
I'm running Windows (if that matters!)
When you use giter8 directly you just need to refer to your local template with the file:// prefix:
g8 file://play-scala-seed
As mentioned by #volia17, you can find it in the giter8 documentation: Testing templates locally.
But when you use sbt new, you need you template name (folder) to end with .g8. sbt can accept different types of templates and this way it knows that this is a giter8 template. So you can rename your template folder to play-scala-seed.g8:
sbt new file://play-scala-seed.g8
P.S. Using giter8 directly is much faster, because sbt new takes time to start (it loads global sbt plugins every time).

Eclipse Plugin only contains manifest

I am attempting to develop an Eclipse plugin. The plugin runs from inside Eclipse (i.e. when I launch a test instance of Eclipse with my plugin from inside Eclipse, I can use the plugin in the test instance.)
However, when I attempt to generate a plugin that could be installed by other systems using File > Expoort > Deployable Plug-ins and fragments, the zip file created, contains a single jar file which itself contains only a manifest file:
$ jar tvf com.foo.bar_1.0.0.d.jar
0 Wed Feb 10 12:14:12 EST 2016 META-INF/
863 Wed Feb 10 12:14:10 EST 2016 META-INF/MANIFEST.MF
For example, it does not include my icons or my plugin.xml file.
I am not (yet) using maven-tycho or any other extra-Eclipse means of building the plugin.
Can anyone suggest what I may be doing wrong?
You must list everything you want in the plugin in the build.properties file, so check that file. When you run from within Eclipse this file is not checked for accuracy but it must be correct when you export.
For a simple plugin it might look something like:
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
OSGI-INF/
source.. = src/
This is including the 'META-INF' folder, the 'bin' folder (where your class files are), the 'plugin.xml' file and the 'OSGI-INF' folder.
In the plugin.xml editor use the 'Build' tab to set the contents of this file.

Using tycho to materalize products results in missing .eclipseproduct file

I'm an Eclipse RCP developer who is using the tycho-p2-director-plugin to build an application.
The good news is that the assembly is generated and can be run successfully. The bad news is that one of the artifacts that I expect to be generated (the .eclipseproduct file) is not being generated.
I have tried to figure out what the deal with this file is - not only that it does not generate through Tycho, but it also does not generate when I use the Eclipse product export wizard. Based upon the documentation I found here, I expect that it would be.
I'm basically wondering about two things at this point, because I can't find any good documentation on where that .eclipseproduct file is supposed to come from / at what point it is supposed to get generated.
If it is generated during the tycho maven lifecycle, then I would expect to find the file under my target folder - which it is not. I have not found a way to have tycho statically include configuration files (besides config.ini), otherwise I would have used that method to attach a static .eclipseproduct file to the root of my install directory.
If this is something that should be generated by an installer, what is the mechanism using p2 such that you can accomplish this? I've considered including the .eclipseproduct file in my main P2 IU, but I'm unclear on whether that file would actually be copied into the root directory and how exactly that would be accomplished.
As you can tell, I haven't been able to find very much direction as to how getting this file included with my build would be accomplished. Any pointers in the right direction would be helpful. I can also include my product configuration files if necessary.
This should be a comment as it's only a partial answer, but it's too long.
It seems that .eclipseproduct is a file generated at build time, and not created by p2 at provisioning time:
To find this I provisioned a copy of Eclipse 4.2 using p2 director (for instructions I used the Installing a Complete product section of this page, updating the repository to the 4.2 site instead of using the 3.6 ones, and changed from using Windows paths to ones more suited for my mac).
I noticed on the file listing that the .eclipseproduct file seemed to be an unzipped artifact instead of a generated one since the time stamp was different:
$ ls -lA
total 304
-rw-r--r-- 1 myself group 60 Sep 14 18:13 .eclipseproduct
drwxr-xr-x 3 myself group 102 Nov 2 14:49 Eclipse.app
-rw-r--r-- 1 myself group 112366 Nov 2 14:49 artifacts.xml
...
This got me looking through the various caches in the ./p2 directory, and I found that there is an Installable Unit org.eclipse.platform_root which is a zip file containing licensing and the .eclipseproduct file...
:p2 $ zipinfo org.eclipse.equinox.p2.core/cache/binary/org.eclipse.platform_root_*
Archive: org.eclipse.equinox.p2.core/cache/binary/org.eclipse.platform_root_4.2.1.v20120814-120134-9JF7BHVGFyMveli1uX6aTH0q-eAap6PAgOP5mO 38125 5
-rw---- 2.0 fat 0 bl defN 14-Sep-12 18:13 readme/
-rw---- 2.0 fat 104173 bl defN 14-Sep-12 18:13 readme/readme_eclipse.html
-rw---- 2.0 fat 9051 bl defN 14-Sep-12 18:13 notice.html
-rw---- 2.0 fat 60 bl defN 14-Sep-12 18:13 .eclipseproduct
-rw---- 2.0 fat 16536 bl defN 14-Sep-12 18:13 epl-v10.html
5 files, 129820 bytes uncompressed, 37501 bytes compressed: 71.1%
I found the P2 IU information in the content.xml files found in the org.eclipse.equinox.p2.repository/cache/content*.jar files:
...
<unit id='org.eclipse.platform_root' version='4.2.1.v20120814-120134-9JF7BHVGFyMveli1uX6aTH0q-eAap6PAgOP5mO'>
<provides size='1'>
<provided namespace='org.eclipse.equinox.p2.iu' name='org.eclipse.platform_root' version='4.2.1.v20120814-120134-9JF7BHVGFyMveli1uX6aTH0q-eAap6PAgOP5mO'/>
</provides>
<artifacts size='1'>
<artifact classifier='binary' id='org.eclipse.platform_root' version='4.2.1.v20120814-120134-9JF7BHVGFyMveli1uX6aTH0q-eAap6PAgOP5mO'/>
</artifacts>
<touchpoint id='org.eclipse.equinox.p2.native' version='1.0.0'/>
<touchpointData size='1'>
<instructions size='2'>
<instruction key='install'>
unzip(source:#artifact, target:${installFolder});
</instruction>
<instruction key='uninstall'>
cleanupzip(source:#artifact, target:${installFolder});
</instruction>
</instructions>
</touchpointData>
</unit>
...
In short: when this IU is installed (as required by org.eclipse.platform.feature.group), p2 simply unzips the artifact with .eclipseproduct to the install folder. No transformations required. Therefore it must be generated before install time.
Edit: I also found it in the Eclipse Git Repositories but haven't figured out if this is the one that is turned into the IU mentioned above or not...

scala :How to read file in jar

I have directory structure like this
src
main
resources
text.txt
scala
hello
world.scala
test
same as main folder
pom.xml
When in IDE (Intellij10), I could access it with relative path ("src/main/resource/text.txt") but it seems I can not do that when I compile in jar. How to read that file ?
also, I found that test.txt is copy into root of jar. Is this normal behavior ? Since I fear this will be clash with other resources file in src/test/resources.
thanks
From http://www.java-forums.org/advanced-java/5356-text-image-files-within-jar-files.html -
Once the file is inside the jar, you cannot access it with standard FileReader streams since it is treated as a resource. You will need to use Class.getResourceAsStream().
The test.txt being copied into the root is not normal behavior and is probably a setting with your IDE.
8 years later, I am also facing the same question. To ease the life of future developers, here is the answer:
Being copied into the root is normal behaviour, as:
the resources folder is like a src folder and so the content is
copied, not the folder itself.
Now concerning the how-to question:
import scala.io.Source
val name = "text.txt"
val source: Source = Source.fromInputStream(getClass.getClassLoader.getResourceAsStream(name))
// Add the new line character as a separator as by getLines removes it
val resourceAsString: String = source.getLines.mkString("\n")
// Don't forget to close
source.close