I have an sbt project configured (via build.sbt) to generate an OSGI bundle (using the sbt-osgi plugin).
For some reason, the generated MANIFEST.MF contains an Include-Resource directive pointing to the (completely empty) "resource" subdirectories in my build directory (src/main/resources and target/scala_2.10/resource_managed/main, specifically), despite the fact that I have done nothing to tell it to do this (and I definitely don't want my artifacts pointing to locations in my home directory).
Why is sbt-osgi doing this, and, more importantly, how can I get it to stop?
My build.sbt can be found here: https://github.com/reggert/reb4s/blob/1cd91fb82aa978b2f202c618ca6403a66c15f8d7/build.sbt
It has been several months since I utilized the OSGI plugin, but I think I can recall enough to get you on track. First, be aware that it is BND which is doing all of the hard work here. The sbt plugin is just a wrapper. There is some discussion regarding the Include-Resource header. I believe you can set this header to None or an empty string with the plugin's additionalHeaders setting.
Related
I've been using sbt-assembly to generate standalone JAR file for my scala project. However, I would like to reduce the size of my JAR file (its currently around 150MB and there's defintely room for improvement there).
I used the following command to list the contents of the JAR file that's produced:
jar tf <JAR file>
This revealed that there are lots of classes in the generated JAR file that are not used in the project. I believe these classes get included as part of third-party JARs.
Questions
(a) Is there an option that I can use to instruct sbt-assembly to generate a minimal JAR file that does not include the third-party classes that are not used in my project?
(b) I could use AssemblyStrategy to manually specify which files need to be excluded. Is this a sound strategy? I'm a bit concerned that with this approach the JAR file might end up throwing unexpected ClassNotFound exceptions.
Thanks in advance.
It's not easy to say what's used in your project and what is not. If you include a dependency into a project it might bring a few other ones in. Those child dependencies might also require their own dependencies and so on.
By default if you include some dependency in your project you intend to use it. The author of a dependency usually does the same thing. Thus, there is usually not much you can throw away, it's there for a reason. There are couple cases when this is not true:
Dependency author includes additional dependencies that will be used only in some settings, and that does not apply to your project
You are using a mega-dependency when you actually need only one of its libraries/features.
There are counter examples to this as well: Scalatest does not ship pegdown for generating html test reports because you don't need it usually. But it might be needed if you try to use -h flag to generate html.
Imagine the case when you use Apache Tika for pdf parsing. It wraps PDFBox to do the parsing. You don't need a bloat of all other libraries in that case that parse MS documents. The best thing to do is not to exclude files manually via sbt exclude or sbt-assembly rules because there is a risk you get it wrong and get run time class loading exception. Instead you need to use the right dependency like PDFBox directly. Unfortunately this is a lot of manual work in many cases to figure out all dependencies that you need, so it's your choice: easy and fat JAR, or painful and lean.
There are two ways to exclude dependencies:
Exclude transitive dependencies with exclude. See the docs here.
Don't use the top level dependency and manually add its subdependencies as you need them.
Ok, one more less fun option: use provided and make sure libraries are copied to your target environment and are on classpath. If you have many jars using the same libraries this helps to share those.
You can visualize your dependency tree with this plugin: https://github.com/jrudolph/sbt-dependency-graph. It's very helpful when trying to figure out what you are using and what you can remove. There are some tools like tattletale and loosejar that people suggest but I haven't tried them. If anyone has experience with those please share.
What might want to look at are treeshakers
For Java there's the following (I have not tried/used it):
http://proguard.sourceforge.net/
I have exactly the same problem as in this question: Eclipse: Using "Open Declaration" ... in a Scala project
However, I'm using the latest Scala IDE in version 3.0.2 (I have downloaded the Eclipse bundle from the site), and I would assume such basic functionality works by now, and apparently it's me who have something misconfigured.
I have created a new Scala project. Then I open some standard library class/trait/whatever, let's say scala.util.parsing.combinator.JavaTokenParsers. The source is neatly displayed, but when I try to show class hierarchy, I get the message: The resource is not on the build path of a Java project.
Also, searching for references etc. won't work.
I guess it is a matter of properly configuring the build path? Or maybe I should somehow attach Scala library sources to my project? But I can see the source, so aren't they attached already?
Here is the snapshot of my project configuration:
UPDATE:
By playing a bit with setting/resetting build path stuff, I managed to get rid of pop-up warning but the class hierarchy comes up empty and when searching for references I get only hits from my own sources, nothing from standard library.
In another workspace I also tried randomly adding and removing scala-library jars and got it work almost, but the type hierarchy comes up only with super-classes, without any sub-classes (which renders it quite useless). Searching for references works ok though.
Funny thing, I cannot make it work in my original workspace...
Gotta love Eclipse.
Your build path is not configured properly.
If you take a look under Scala Library[...] you have scala-library.jar we can only see one top-level package scala. There should be numerous other packages besides that. (Ruled Out)
I would recommend you follow these steps
Right-click project, build-path, Java-build-path, Libraries and make sure that the correct library is referenced there.
If it is the one you need, Try to remove this library and add it again, then clean and re-fresh the project. Also try this step in a fresh workspace.(something must have messed up this workspace )
Lastly. Goto the path D:\Eclipse For Scala\configuration\org.eclipse.osgi\bundles\286\1\.cp\lib and verify the sizes of the jars there. There should be 6 jars there and the size of scala-library jar should be around 6.8M. If size is smaller, consider re-downloading
This is a very simple question, but I surprisingly havn't gotten an answer for it yet.
Simply put, in most non trivial SBT projects you will have a plugins.sbt file that contains plugins that are required to run your project (like a web container plugin if your SBT project is a website). However in the same file (plugins.sbt), plugins which have nothing to do with actually running your project (such as ensime/intellij/eclipse project generators) are also typically placed in plugins.sbt
I have seen this behavior for many SBT projects which are placed into github
This ideally speaking is not the correct way to do things, ideally plugins which have nothing to do with actually running/compiling your project should be in a separate file which is put into a .gitignore
What is the idiomatic SBT way of dealing with this (I assume it should be something that consists of having 2 separate plugins.sbt files, one with actual project plugins and the other with IDE generators and whatnot)
You can install plugins globally by placing them in ~/.sbt/0.13/plugins/. .sbt or .scala files located here are loaded for every project that you have.
You can also use addSbtPlugin() in a .sbt file to add other plugins.
Check out http://www.scala-sbt.org/release/docs/Getting-Started/Using-Plugins.html
I have inherited a big project with several subprojects.
all of them use several jar files, all of them located under each project's lib directory. I want to take all the projects and migrate them to maven, but dependencies are a problem (too many of them), some of them are commonly used libraries (apache projects, xerces, jms, etc) and others are not.
is there a way to autogenerate maven dependencies for those jars that can be found on public maven repositories. for example, see that my project use the spice-jndikit-1.2.jar file and automatically get the appropiate depedency with group, artifact and (if possible) version?
thank you
I wrote a groovy script to generate a starting set of Apache ivy files.
https://github.com/myspotontheweb/ant2ivy
In my case, I wanted to "Maven-ize" my ANT builds without switching completely away from ANT.
It is feasible to extend this code to generate a Maven POM, if people were interested in this feature.
You can convert a project to Maven using the m2e plugin, but this erases your jar references, and should not be used.
I doubt that such a thing exists since typical jars (unless themselves built with Maven) don't have the necessary information to correlate the groupId, artifactId and version back to a repository to get the proper path.
You might be able to write something that parses the file name for the name and version, but you still have the package-based path to figure out.
If you're building using Ant, you might also consider using Apache Ivy, and its file-system based resolution (very fast and easy to configure), to get you started, and slowly role over to the Maven repos for the artifacts, this way you're not spending a lot of time up-front finding Maven dependencies.
Note: This is an exact repost of the same question on the Scala-IDE mailing list, where I got zero reply and gave up waiting after 5 days.
I'm writing a Scala Compiler Plugin. It's currently called
scalawrapper (but I might find a better name later). I have the
Typesafe Stack installed, and I put my plugin in it under:
C:\Program Files\typesafe-stack\misc\scala-devel\plugins
Now I can call scalac like this:
scalac -classpath ... -Xplugin-require:scalawrapper test\...
and it finds and uses my plugin automatically.
Unfortunately, I just can't get the Scala-IDE to use it. I always get
Missing required plugin: scalawrapper. In the "Project Properties
\Scala Compiler (Use Project Settings)\Advanced" tab, I have entered
scalawrapper in the Xplugin-require field, and that works, since I get
the error. But nothing I can type in Xpluginsdir seem to have any
effect.
I have tried the absolute path given above, have tried with forward
and backward slashes, have tried a temporary directory without spaces
in it, have tried relative to project directory, have tried relative
to workspace. It just will not use anything. I should also note that
is is not specific to my own plugin, as I tried to use the ScalaCL
plugin before in a previous version of the Scala-IDE, and failed for
the exact same reason.
I have just updated today (15.10.2011) and so should have the latest
version (it seems I can finally explicitly set the indentation to 4,
but maybe I just overlooked the setting in the past).
Can someone tell me what it actually expects, and what is uses as
default when I don't put anything in Xpluginsdir?
The Scala IDE uses the presentation compiler, not the compiler that you've installed. To use a plugin, with Scala IDE, you need to specify it in the preferences in Eclipse.
Try Windows->Preferences->Scala->Compiler. See the Advanced tab. The paths are relative to the workspace.
EDIT: When I say relative to the workspace, I mean the actual workspace directory under which the .metadata is stored ($workspace_loc). I have a project where project files including the source code is stored in one directory and the workspace is elsewhere, i.e the $project_loc (c:\code\project\source) is different from the $workspace_loc (c:\code\project\workspace). The directory that you specify in the compiler parameters is relative to the workspace ($workspace_loc).
To find out if you have a similar setup, go to the project and select Properties->Resource->Linked Resources.
I created a directory under $workspace_loc called plugin and placed the jar file in there. Under Windows->Preferences->Scala->Compiler Advanced tab I have
Xplugin = C:\code\project\workspace\plugin\xxx-0.0.1.jar
Xplugin-require = xxx
Please note that you can specify the plugin in the project properties as well, but it still uses $workspace_loc. The above configuration works for me.