How can I add Mockito to the test classpath in Tycho's unit-tests with eclipse-plugin packaging - eclipse

Recently, it has become possible to Execute unit-tests with eclipse-plugin packaging. And, in addition there is support for resolving JUnit Classpath Containers.
I would like to execute unit-tests with eclipse-plugin packaging, but would like to use the mockito library in addition to JUnit. I have a pomless build and would like to keep it that way. I do not want to add non-PDE files to the build, unless this is unavoidable.
Question: What is the idiomatic/intended/correct way to add this dependency, or any other test-time dependencies?
Note: I am aware of the use of fragments for unit testing. This is not what I am after. I actually want to use the new mechanism, if possible, or hear that this is currently impossible.
For my initial purposes, and given these are intended to be Unit-tests, running non-OSGI would be ok. If there is a means for OSGI as well, that would be great, but I cannot imagine where the platform configuration could be stored.

See this tycho discussion, short summary:
you can add Mockito as an optional bundle dependency
you can add a M2_REPO Classpath variable reference

Related

Adding Dependency Management to an Existing Java Project

I'm working on upgrading a legacy Java project to be compatible with jboss wildfly. As part of that process, I'm replacing our old system of managing dependencies (manually scanning for jars in a folder) with an automated system.
My first thought was to use maven, which worked well initially. The maven plugin for eclipse was able to scan my project and create a pom with most of the required dependencies. That works fine for compiling and running with eclipse, but production deployment uses an ant build script. I looked into maven-ant-resolver ( https://maven.apache.org/resolver-ant-tasks/index.html ) but as far as I can tell that project doesn't have a way to add dependencies to the classpath, the best it can do is bundle them into a jar.
The other option I looked at was Ivy. It seems better suited to integration with ant. Unfortunately, the tooling for ivy seems primitive compared to maven. From what I can tell, there is no option to generate the dependency file (ivy.xml) from an existing project. With the number of dependencies I'm dealing with, especially from jboss, creating the dependency xml from scratch is not a realistic option.
What are my options for solving this problem? Is there a way to do what I want with maven or ivy that I'm not seeing? Is there another dependency management tool out there that offers all the features I need?
The maven-assembly-pluginis what i can recommend for likely usecases. Not sure if it suits you though.
In a nutshell:
You can pack folders, jars, resources, dependencies, whatever into a jar for production deployment. This jar is packaged with the, from maven-assembly-plugin internally used and thus not needed to be referenced explicitly, maven-archiver-plugin which also stores a MANIFEST.MF with the classpath in it (not by default but with few codes of tweaking).
Useful to know though: Maven allows you to quite easily create own Plugins that completely do what you want. If its just a file with the stored classpath, this could be a clean solution.

Where should JUnit specific Guice module be configured?

I'm going to start using dependency injection in my Eclipse plugin. My test plugin depends on the main one and should use different injection context. Production should work fine standalone (it should have its own injection context), but behave differently when used from tests (should use Junit's injection context).
How could I resolve the injector so that a different one is used in production and in tests?
I don't like the idea to somehow inject context manually in a static variable on test start. Is there a better way? Can extensions be somehow used for that?
I know that in e4 there is a solution for that, but I'm bound to Eclipse Indigo for now and could not find quickly how exactly is that done in latest version. A link to injector configuration with an ability to override in test infrastructure in e4 source is appreciated.
I wound up writing my own JUnit runner modeled largely after the Spring JUnit runner, but would highly recommend looking at the Jukito project now.
At this point I try to have one Guice module per feature, so I end up with one Guice module for test that installs the production module and overrides or binds any external dependencies. I keep that test module in a base test class along with the necessary annotation for the JUnit runner, which is very similar to the JukitoModule examples in the link above.

Eclipse plugin to detect jars only needed for Test classes

I have 10 projects with each having 20 dependencies. Is there an Eclipse Plugin to detect jars only needed for Test classes?
This way I can exclude them from production.
I don't know such a plugin and static code analysis will only help you if you never use reflection or things like JDBC (which map Strings to Java types).
A good tool to clean the classpath is Maven. Maven (unlike Eclipse) keeps separate classpaths for the main code and unit tests. After migrating your build to Maven, simply set the scope of all dependencies to test.
Compile and the compiler will print the missing symbols. Remove the <scope> element for those and compile until Maven is happy.

Selectively include dependencies in JAR

I have a library that I wrote in Scala that uses Bouncy Castle and has a whole bunch of dependencies. When I roll a jar, I can either roll a "fat" jar that has all the dependencies (including scala), which weighs in around 19 MB, or I can roll a skinny jar, which doesn't have dependencies, but is only a few hundred KB.
The problem is that I need to include the Bouncy Castle classes/jar with my library, because if its not on the classpath at runtime, all kinds of exceptions get thrown.
So, I think the ideal situation is if there is some way that I can get either Maven or SBT to include some but not all dependencies in the jar that gets rolled. Some dependencies are needed at compile-time, but not at run time, such as the Scala standard libraries. Is there some way to get that to happen?
Thanks!
I would try out the sbt proguard plugin from https://github.com/nuttycom/sbt-proguard-plugin . It should be able to weed out the classes that are not in use.
If it is sufficient to explicitly define which dependencies should be added (one the artifact-level, i.e., single JARs), you can define an assembly (in case of a single project) or an additional assembly project (in case of a multi-module project). Assembly descriptors can explicitly exclude/include artifacts from the dependencies.
Here is some good documentation on this topic (section 8.5.4), here is the official documentation.
Note that you can include all artifacts that belong to one group by using the wildcard notation in dependecySets, e.g. hibernate:*:jar would include all JAR files belonging to the hibernate group.
Covering maven...
Because you declare your project to be dependent upon bouncy castle in your maven pom, anybody using maven to depend upon your library will by default pull in bouncy castle as a transitive dependency.
You should set the appropriate scope on your dependencies, e.g. compile for stuff needed at compile and runtime, test for dependencies only needed in testing and provided for stuff you expect to be provided by the environment.
Whether your library's dependencies are packaged into dependent projects when they are built is a question of how those are projects configured and setting the scopes will influence the default behaviour.
For example, jar type packaging by default does not include dependencies, whereas war will include those in compile scope (but not test or provided). The design aim here was to have packaging plugins behave in the most commonly required way without needing configuration, but of course packaging plugins in maven can be configured to have different behaviour if needed. The plugins themselves which do packaging are well documented at the apache maven site.
If users of your library are unlikely to be using maven to build their projects, an option is to use the shade plugin which will allow you to produce an "uber-jar" which contains all the dependencies you wish. You can configure particular includes or excludes.
This can be a problematic way to deliver, for example where your library includes dependencies which version clash with the direct dependencies of projects using it, i.e. they use a different version of the same libraries yours does.
However if you can it is best that you leave this to maven to manage so that projects using your library can decide whether they want your dependencies or to specify particular versions giving them more flexibility. This is the idiomatic approach.
For more information on dependencies and scopes in maven, see the reference guide published by Sonatype.
I'm not a scala guy, but I have played around with assembling stuff in Java + Maven.
Have you tried looking into creating your own assembly descriptor for the assembly plugin? https://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
You can copy / paste the jar-with-dependencies descriptor then just add some excludes to your < dependencySet >. I'm not a Maven expert, but you should be able to configure it so different profiles kick off different assembly builds.
EDIT: Ack, didn't see my HTML got hidden

eclipse, one classpath for compiling, another for launching

example:
For logging, my code uses log4j. but other jars my code is dependent upon, uses slf4j instead. So both jars must be in the build path. Unfortunately, its possible for my code to directly use (depend on) slf4j now, either by context-assist, or some other developers changes. I would like any use of slf4j to show up as an error, but my application (and tests) will still need it in the classpath when running.
explanation:
I'd like to find out if this is possible in eclipse. This scenario happens often for me. I'll have a large project, that uses alot of 3rd party libraries. And of course those 3rd party jars have their own dependencies as well. So I have to include all dependencies in the classpath ("build path" in eclipse) for the application and its tests to compile and run (from within eclipse).
But I don't want my code to use all of those jars, just the few direct dependencies I've decided upon myself. So if my code accidentally uses a dependency of a dependency, I want it to show up as a compilation error. Ideally, as class not found, but any error would do.
I know I can manually configure the classpath when running outside of eclipse, and even within eclipse I can modify the classpath for a specific class I'm running (in the run configurations), but thats not manageable if you run alot of individual test cases, or have alot of main() classes.
It sounds like your project has enough dependency relationships that you might consider structuring it with OSGi bundles (plug-ins). Each bundle gets its own classloader and gets to specify what bundles (and optionally what version ranges, etc.) it depends on, what packages it exports, whether it re-exports stuff from its dependencies, etc.
Eclipse itself is structured out of Eclipse plug-ins and fragments, which are just OSGi bundles with an optional tiny bit of additional Eclipse wiring (plugin.xml, which is used to declare Eclipse "extension points" and "extensions") attached. Eclipse thus has fairly good tooling for creating and managing bundles built-in (via the Plug-in Development Environment). Much of what you find out there may lead you to conflate "OSGi bundle" with "plug-in that extends the Eclipse IDE", but the two concepts are quite separable.
The Eclipse tooling does distinguish rather clearly (and sometimes annoyingly, but in the "helpful medicine" way) between the bundles in your build environment vs. the bundles that a particular run configuration includes.
After a few years of living in OSGi land, the default Java "flat classpath" feels weird and even kind of broken to me, largely because (as you've experienced) it throws all JARs into one giant arena and hopes they can sort of work things out. The OSGi environment gives me a lot more control over dependency relationships, and as a "side effect" also naturally demands clarification of those relationships. Between these clear declarations and the tooling's enforcement of them, the project's structure is more obvious to everyone on the team.
if my code accidentally uses a dependency of a dependency, I want it to show up as a compilation error. Ideally, as class not found, but any error would do.
Put your code in one plug-in, your direct dependencies in other plug-ins, their dependencies in other plug-ins, etc. and declare each plug-in's dependencies. Eclipse will immediately do exactly what you want. You won't be offered dependencies' dependencies' contents in autocompletes; you'll get red squiggles and build errors; etc.
Why not use access rules to keep your code clean?
It looks like it would better be managed with maven, integrated in eclipse with m2eclipse.
That way, you can only execute part of the maven build lifecycle, and you can manage separate set of dependencies per build steps.
In my experience it helps to be more resrictive, I made the team filling out (paper) forms why this jar is needed and what license...
and they did rather type in a few lines of code instead of drag along 20 jars to open a file using only one line of code, or another fancy 'feature'.
Using maven could help for a while, but when you first spot jars having names like nightly-build or snapshot, you will know you're in jar-hell.
conclusion: Choose dependencies well
Would using the slf4j-over-log4j jar be useful? That allows using slf4j with actual logging going to log4j.