pax-exam: are the tests running inside of a bundle? - maven

I have a Maven project that builds a very simple OSGi bundle. No activator; it's only job is to deliver some shared code to an OSGi project. I want to test that I have got the dependencies all set up and embedded correctly.
So, I've added pax-exam to the situation.
I'll paste a unit test shell at the end of this. Is my #Test method in fact running inside of a bundle that is in turn depending on the bundle built in my project?
#RunWith(PaxExam.class)
#ExamReactorStrategy(PerClass.class)
public class CommonBundleTest {
#Configuration
public Option[] config() {
return options(
// this is the current project's result artifact
mavenBundle("com.basistech.osgi", "rosette-common-java-lib"),
junitBundles()
);
}
#Test
public void atest() {
}
}

Are the tests running inside of a bundle: yes
Pax Exam creates a TinyBundle for the Unit test itself. But it doesn't add extra dependencies on any bundle declared in the config method.
If you want to make sure those packages are imported you can alter the way the TinyBundle is build.
#ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
// makes sure the generated Test-Bundle contains this import!
probe.setHeader(Constants.IMPORT_PACKAGE, "*,your.extra.package");
return probe;
}

The so-called probe bundle created by Pax Exam on the fly contains all classes from the src/test/java folder containing your test class. The probe bundle manifest has a Dynamic-ImportPackage: * header, so it is not normally required to add explicit imports by means of a probe builder.
Any bundles required by your tests must be provisioned by a configuration option in the #COnfiguration method.
If you want your test to fail immediately when a bundle does not resolve, you can set a config property:
pax.exam.osgi.unresolved.fail = true

Related

spring-boot-starter-freemarker does not find templates

Using spring-boot-starter-freemarker without further config I would expect to be able to load templates from the default template path(src/resources/templates) (note it's src/... not build/...).
Having this file here:
src/resources/templates/emails/welcome.ftl
Trying to load it as a template:
// some service class
#Autowired
private Configuration freemarkerConfig;
public void doStuff() {
Template t = freemarkerConfig.getTemplate("emails/welcome.ftl");
// ...
}
Fails with this error message:
freemarker.template.TemplateNotFoundException: Template not found for name "emails/welcome.text.ftl".
The name was interpreted by this TemplateLoader: MultiTemplateLoader(loader1 = FileTemplateLoader(baseDir="/some/path/backend/build/resources/main/templates", canonicalBasePath="/some/path/backend/build/resources/main/templates/"), loader2 = ClassTemplateLoader(resourceLoaderClass=org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer, basePackagePath="" /* relatively to resourceLoaderClass pkg */)).
So the configuration seems kind of ok-ish, but instead of the src folder it is using the build folder. When running via./gradlew bootRun we see the error. Doing a ./gradlew buildand then ./gradlew bootRun the templates are found - because they are now in the build folder. But for development it would be much appreciated to not require a full re-build.
So, I know we now could configure freemarker manually to load from the src folder, but that feels hacky.
Am I doing something wrong or is this expected behavior?
You can configure bootRun so that sources are loaded from their source location. Assuming that the templates are part of the main source set, i.e. they're in src/main/resources, the configuration would be the following:
bootRun {
sourceResources sourceSets.main
}
This is described in the reference documentation for Spring Boot's Gradle plugin.

Spring - Run test from IDE - how to load test properties from a file like 'application-test.properties'

How can I load test properties from a file like 'application-test.properties'?
The file is stored in the src/test/resources folder. I put the file also in all possible folders as well. When running the test as part of the Maven test run, all works fine.
When running the new (single) test from the (IntelliJ) IDE, each time I get same the error message:
Caused by: java.io.FileNotFoundException: class path resource
[application-test.properties] cannot be opened because it does not
exist
This is the test class:
#RunWith(SpringRunner.class)
#EnableAutoConfiguration
#ComponentScan(basePackages = {"nl.deholtmans.tjm1706.todolist"})
#PropertySource( "application-test.properties")
public class TodoListServiceTest {
#Autowired
TodoListService todoListService;
#Test
public void testBasic() { ... }
It looks that I have to run the test first time from Maven. Why is that?
Spring Boot will automatically load the correct properties file if the profile is activated. In a test you can use the #ActiveProfiles annotation for that.
Next you would need to make sure that you actually use the proper Spring Boot infrastructure to run your test, using #SpringBootTest. That being said your test header should look something like the following
#RunWith(SpringRunner.class)
#SpringBootTest
#ActiveProfiles("test")
public class TodoListServiceTest { ... }
And ofcourse make sure that your IDE builds the application before running the tests.

Resource injection in Spring Boot not working with gradle

I have a Configuration bean.
#Component
public class Config {
#Value("classpath:${app.file.name.srgbicc}")
public Resource icc;
#PostConstruct
void init(){
try {
tempdir = Files.createTempDir();
newIcc = copyIccFileToTemp();
}catch (IOException e){
throw new RuntimeException(e);
}
}
private File copyIccFileToTemp() throws IOException {
File tempIcc = new File(tempdir, icc.getFilename());
FileUtils.copyFile(icc.getFile(),tempIcc);
return tempIcc;
}
}
On icc.getFile() there is a FileNotFoundException
application.properties
app.file.name.srgbicc = sRGB.icc
I looked in my classpath and found the following situation:
build/classes/main (no icc file)
build/resources/main (icc file, application.properties)
When printed out my classpath during application start I only found ...myApp/build/classes/main.
No ../build/resources/main or ../src/main/resources entries there.
So I was wondering why is the resources not on the classpath?
according to http://docs.spring.io/spring-boot/docs/1.1.5.RELEASE/reference/htmlsingle/#build-tool-plugins-gradle-running-applications
this should be.
Of course if I put the icc file in build/classes/main its all working as expected, but it is not supposed to be there. right?
I tried to run the application with gradle run or gradle bootRun in intellij I use static main. The good thing is that the application fails consistently independent of how I start it.
My Project layout
myApp
src
main
java
pkg
Config.java
resources
sRGB.icc
application.properties
For the reference:
IntelliJ 13
spring-boot 1.1.5
Fgradle 2.0
Update
Here is a stripped down example of my code
https://gist.github.com/Vad1mo/bb5d23ca251341236fbd
I removed #PostConstruct in the config.init and run the application with gradle build all test are success when i rund from intellij the tests fail. this is strange that i know have different behavior
I solved the problem now.
What helped me was just to do a simple clean build and rebuild project in intellij. I was using to much eclipse and maven so I expected it to happen automagically.

Selenium Netbeans Project to runnable jar

I'm developing tests using junit, maven and Selenium inside Netbeans IDE. I don't have any main class inside the src folder. I can run the tests easily from the IDE, but I'm trying to pack all of them into one jar file (so I can later use with linux cron and schedule daily tests). I've searched around the web but so far my search hasn't been successful. Can anyone point me in some enlightment path please?
Add a class in your project that contains the main function and accepts test class names as parameter.
class RunTest
{
public static void main(String args[])
{
// Run the tests contained in the classes named in the args.
org.junit.runner.JUnitCore.main(args);
}
}
Now create the jar using maven including all the dependancies in pom.xml. you will be able to run tests through jar by passing test class names
for more information read this

OSGI application gets NoClassDefFoundError when using Liberty Feature

I have an OSGI bundle (awesome.test) that calls code from a jar file (testlibrary.jar). I have included the bundle as a Liberty feature (awesome.test.feature) and I have it installed on a WebSphere Application Server Liberty Profile V8.5.5. I also have an OSGI bundle (awesometest) that is a part of an OSGI application (awesometest.app) and it has an Activator class.
Here is a picture of my workspace setup
What I want to do is call methods in testlibrary.jar through methods in awesome.test, which includes testlibrary.jar in its build path. My awesome.test.feature is available to any applicaions running on my Liberty server. I want my applications to be able to use that feature to gain access to the functionality in testlibrary.jar through what I provide in awesome.test. I don't want OSGI applications to directly import packages from testlibrary.jar.
The following error appears in the binary logs when I run the application on the server:
CWWKZ0402E: A bundle exception was generated when trying to install the application awesometest.app into an OSGi framework. The error text from the OSGi framework is: Exception in awesometest.Activator.start() of bundle awesometest.
Debugging the problem finds that this exception is thrown:
java.lang.ClassNotFoundException: testlibrary.test.TestAPI
Source from TestLibraryRunner.java in awesome.test:
package awesome.test;
import testlibrary.test.TestAPI;
public class TestLibraryRunner {
public static void runNonLibTest() {
System.out.println("No Library code is being called");
}
public static void runLibTest() {
TestAPI ta = new TestAPI("This is a message.");
ta.display();
}
}
Note that runNonLibTest() will work when called from the OSGI application. Calling the TestAPI code in runLibTest from the OSGI application will cause the error above.
Source from Activator.java in awesometest:
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception {
System.out.println("Starting...");
TestLibraryRunner.runNonLibTest();
TestLibraryRunner.runLibTest();
System.out.println("Finishing...");
}
public void stop(BundleContext context) throws Exception {
System.out.println("Stopping...");
}
}
Source from MANIFEST.MF in awesometest:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: awesometest
Bundle-SymbolicName: awesometest
Bundle-Version: 1.0.0
Bundle-Activator: awesometest.Activator
Import-Package: awesome.test,
org.osgi.framework
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: awesometest
In summary, my OSGI application cannot touch code from the jar in the build path of the bundle included in my Liberty feature. Is there something fundamental I'm missing here? Is what I'm trying to do even possible?
Thanks
Having had the same runtime exceptions in my educational project, the simplest solution I have found is to add the used JARs under Runtime - Classpath of the imported bundle (in your case awesome.test).
I hope this late answer helps someone else.
You use the package testlibrary.test but you do not import it. You should add that package to the Import-Package statement of the bundle.
It looks like the problem is in the packaging of awesome.test. The awesometest bundle (application bundle) can find your feature code fine, but then problems occur in the feature bundle. Have you confirmed that testlibrary.jar is packaged within awesome.test (feature bundle) and that the manifest of awesome.test includes the embedded jar?
You'll also need to list your exported feature packages in your feature manifest using the IBM-API-Package header, but I assume you've already done that or your application bundle activator wouldn't be able to see the feature bundle's TestLibraryRunner.
The problem with my project was that I was not including the testlibrary.jar correctly. While it was in the build path of awesome.test, it wasn't being included with the OSGI feature bundle.
There are two possible solutions:
1.) In Eclipse, go to File > Import and choose OSGi > Java Archive into an OSGi Bundle and create a new bundle. This will put the jar in its own bundle and then awesome.test can import the packages it needs from that new bundle.
2.) In Eclipse, go to File > Import and choose OSGi > Java Archive into an OSGi Bundle and include it in an existing bundle. This has the same effect as making the jar its own bundle, but it's less modular. The advantage of this approach is that you can not export the packages from the jar and just export your own interfaces.
There is also the BND Tool. It can help automate a lot of this process. I haven't used it myself.

Resources