How to modify the Eclipse Run Configuration classpath? - java

I'm developing a project in Eclipse JDT, that has optional dependencies on OSGI - that is, it supports being used as an OSGI bundle, and if it is used as a bundle inside an OSGI environment, it will also reference some classes from OSGI.
Now I want to write JUnit test cases for both running inside OSGI and running without OSGI, included in two different test suites. The OSGI tests are run as JUnit Pulg-in Tests and the Non-OSGI tests should be run as normal JUnit Tests.
Now I have the problem, that I couldn't find any way in Eclipse to exactly specify the classpath for the JUnit Test Run Configuration and exclude the optional OSGI jars.
Is there any way to exclude jars or modify the default classpath for an Eclipse Run Configuration?
If not, does anyone have a suggestion, how one should setup JUnit tests in such a case?
The only solution I was able to find is, to create a jar file from my unit tests and run the tests without OSGI from a different project with the test jar file on the classpath. But I would prefer a more elegant solution, ideally without the necessity of a second test project.

With the help of Gimbys comment, I was able to solve the problem. Although it is not possible in Eclipse to modify the default classpath generated by JDT, it is possible to entirely remove the default classpath and then add your own classpath in the classpath tab of the Runtime Configuration.
To remove the default classpath, one has to select the root entry that is named after the currently run project, and then click on the "remove" button. After that one can add all the jar files and projects that should be loaded in the classpath. The downside of this approach is, that jar files, that are normally provided by Eclipse plugins like e.g. junit.jar, must then also be selected manually (e.g. by adding it to a library folder of the project or by selecting the external jar in the plugins directory of the Eclipse installation folder).

I would suggest that you split up your project in 4 separate projects:
Logic: This package contains all the logic, so basically what your program/plug-in does
Logic.plugin: This Project resembles a Plugin-Project (OSGI-Bundle). This project contains only configurations needed for your plugin and everything dependent on osgi. It has a dependency on your Logic Project.
Logic.plugin.test: All the test cases for your osgi bundle. It is the normal plugin approach to split up logic and test cases
Logic.cli: This project contains the command line interface (or whatever your alternate application is). This also depends on the Logic project.
If your CLI project is only very small you may merge it with the Logic project.

Related

JUnit tests in Eclipse on Java 9 modular project

I'd like to run tests with JUnit 5 on Java 9 modular project in Eclipse, with no Maven, Gradle or all that fancy stuff. So I have src/main/java path where module-info.java and module's packages live and also src/test/java where all the test classes are. Id est business as usual, prior to the Jigsaw module system. I have Eclipse Oxygen.3a (4.7.3a) an Java 10.0.1.
I've seen some video from Eclipse showing, how to add JUnit test to modular project, but this flabbergasted me deeply: they put required keyword into module-info.java of a module, binding it to JUnit module. Is that actually even correct?
I've seen also all these --patch-module/--add-reads solutions (when we're talking about working in a console) and it seems like it's the proper way to do it, but I have no idea, how to achieve that in Eclipse without binding module under test to JUnit module. Is that even possible in Eclipse (without Maven and s.o)?
I tried to solve this problem for quite a while, too. My approach is to add a filter to the source code directory for src/main/java that filters out the module-info.java. This allows to have a different module-info.java in src/test/java. It will be this one that gets copied to the output folder. This way you can run your unit tests from within the IDE and use the other one for the final build. However, you need to keep the content of the one in src/main/java updated yourself.
Right click on the project > Properties > Java Build Path > Source
Select the src/main/java entry, click Edit > Next > Exclusion Patterns > Add

Executing a single test in an installed maven jar

I have a jar installed in my local ~/.m2 repo and I would like to execute a single test using the -Dtest option via a python script. I tried using this command on the command line mvn surefire:test -DdependenciesToScan=groupId:artifactId -Dtest=NameOfTest, however it doesn't seem like maven is finding the NameOfTest in the groupId:artifactId dependency and returning back with no tests executed? Any way to execute a single test in an already installed maven artifact?
Typically Java classes in src/test/java (or your corresponding test sources directory) will not end up in a built artifact by maven by default. If you inspect the contents of the JAR, you will likely notice no compiled test classes, which is why maven can't find them.
If you really want your test source compiled into the JAR, there are plugins to help you. Particularly, the standard Maven JAR Plugin.
However, I would suggest you consider carefully why you need test classes in a built artifact. The standard use of test suites is to test the main source code being built. There are some situations that have been argued where having tests in the final artifact are valid, but they are rare and usually can be worked around in other ways ( Related discussion ).

Patching a classpath when running Surefire tests

We are developing code in the context of a legacy Java application that heavily uses static members and system properties, expecting files in various locations on the disk. The builds are run in Maven.
We are trying to allow unit testing of our code without having to deploy, configure and start the whole application. I have managed to do this by patching a small number of classes in the framework, providing my own variants of the relevant source files in Maven's test sources in src/test/java.
As a next step I would like to make this patch re-usable by providing a JAR file that can be pulled in as a test dependency on any project that develops a part of the larger application. I would like to deploy this via our normal binary repository.
Surefire offers an option to set <additionalClasspathElements>, but according to the documentation this works only with absolute paths and will add the dependency at the end of the class path.
In theory ordering the project dependencies correctly could work, but I cannot find any documentation on how that order works across multiple scopes. I would need Maven to guarantee that my test dependency is loaded before the runtime ones.
What is a reliable way of patching classes for a Surefire run by using a JAR pulled via Maven's dependency resolution mechanisms?

doubts related to plugin development for eclipse

Very new to eclipse plugin development.
I have converted jar project into eclipse plugin. But I really dont know, how to make use of it. Some basic doubts,
How to call a method available in plugin in our program??
Should every exposed method should be public, in order to use it in our program??
My idea is something like a plugin to sum two numbers. And user installs the plugin and call add(x,y) method in this plugin. Just like calling a method from an included jar.
There are many tutorials explaining how to create a plugin, but i didn't found how to use the same.
What you are describing is a plain OSGi bundle, with no Eclipse-specific features. In terms of the New Plug-in wizard, yours "doesn't contribute to the UI". Technically, it means that it doesn't need plugin.xml.
The way your outside code perceives the bundle is just as if it was a regular jar: you can access its classes, instantiate them, and call their methods. Or you can call static methods, just like you are used to.
The additional layer provided by OSGi means you can identify which Java packages your bundle exports to its users. Therefore a class which is public, but doesn't reside in an exported package, is not accessible to other bundles (this applies only to the strict mode, however; otherwise you only get an Access Restriction warning).
I think this is the situation you are describing...
You have a plugin that you want Eclipse Java (JDT) users to install. In their Java projects, you want them to be able to use some of the Java classes in your plugin.
In Java, a class has to be found on a classpath by a class loader. JDT manages the classpath for projects through "class path containers." The first example of this is when you create a Java project, JDT will add "JRE System Library" as a container. You can see it under the project in the Package Explorer.
Another example of this is the JUnit plugin. You'll notice that when you add a JUnit Test Case to JDT project the first time, a dialog will ask about adding the JUnit library to the build path. (This is an explicit behavior of the JUnit plugin's New File Wizard.) If you agree, you'll see the "JUnit 4" container in the Package Explorer.
Yet another example: PDE expands on what JDT does. When you create a Plugin project, PDE adds a "Plug-in Dependencies" container that it manages based on the plugin dependencies you declare in the plugin manifest.
Users can create and reference their own classpath containers for their favorite libraries.
But, of course, as a library provider, you want to give them one like the JUnit plugin does. To do that, in your plugin:
Add a dependency on JDT Core
Extend from this extension point: org.eclipse.jdt.core.classpathContainerInitializer
If you want a wizard page to create or edit a classpath container entry:
Add a dependency on JDT UI
Extend from this extension point: org.eclipse.jdt.ui.classpathContainerPage
Some plugins use the wizard page to customize the container (JUnit allows picking JUnit 3 or 4); Others just use the page to provide information about the container.
See the JDT documentation topic Setting the Java build path and cross-reference the source code of any examples that familiar to you.
Here is a good article: Simplify Eclipse classpaths using classpath containers
To answer your questions:
You have to add the classes to the classpath using the initialize method of your subclass of ClasspathContainerInitializer.
Yes, methods that you want clients to call must be public and be members of the classes you add to the classpath.

Using eclipse plugin independent from eclipse

Can I programmatically use an Eclipse plugin in my java code (so that it is independent from eclipse)?
Yes you can if:
The plugin you want to use doesn't have any external dependencies => it's just a library plugin
The plugin you want to use and ALL it's dependencies are in your classpath
No in all other cases. Because many plugins use at least the core concepts of OSGI/Equinox (have an activator) it will be quite hard to use them in a standalone java app.
For example, SWT can be used outside eclipse.
You should take a look in your eclipse directory. In the plugins folder you'll find a lot of .jar files. Sure, you could use these as dependencies in your project.
Yes, sure, you just need to care deploy plugin's jar files with you project properly.
Eclipse plugins are OSGi bundles.
OSGi bundles are JAR files that have extra info in META-INF that declares exports and imports. They sometimes make calls to OSGi APIs.
Many Eclipse plugins depend on other Eclipse-specific plugins.
If you use OSGi in your environment, you can easily reuse those plugins that have no Eclipse dependencies. If your application is not OSGi, you can only easily reuse those that avoid the direct use of OSGi APIs.
Well designed plugins are split into UI and "core" parts. You would probably want to grab just the core component. And you may well need to provide an OSGi framework to properly load and activate the plugin too - depending on how complex it is.
As others have also mentioned, don't forget the dependencies.

Categories

Resources