Using Spring autowired bean from other project in JUnit - spring

I'm writing unit tests for my app consisting of several projects. I have project A for which I'm writing tests, and project B where I want to store some needed beans to be autowired in A test classes.
Prject A also needs B in the compilation scope.
If using dependency like that:
...
A/pom.xml
...
<dependency>
<artifactId>B</artifactId>
<scope>compile</scope>
<dependency>
spring is unable to autowire beans of B project. It's strange, because according to the Maven docs, compile scope also makes project content available at the stage phase.
In case I use the save dependency but with test scope, unit tests work, but app itself faild (pretty predictable).
In case when I use both dependencies, like:
...
A/pom.xml
...
<dependency>
<artifactId>B</artifactId>
<scope>compile</scope>
<dependency>
<dependency>
<artifactId>B</artifactId>
<scope>compile</scope>
<type>test-jar</type>
<scope>test</scope>
<dependency>
mvn clean install fails since it's unable to resolve dependencies.
So what can I do? Is there any best practise of using other project beans in unit tests in Spring?

The default maven scope (compile) should do it. Should give you access to the classes at compile/test time.
You should look at:
what packaging do you use for each project (jar/war)
how are you autowiring beans from B to A, does the autowiring works at runtime,
maybe there is a difference on how you create the Spring context at test time VS runtime
could be that Spring auto-scan mechanism doesn't scan the B project packages (at least in tests)

We usually do it like :
<dependency>
<artifactId>B</artifactId>
<groupId>groupID</groupId>
<version>version number</version>
<scope>compile</scope>
<type>jar or war</type>
</dependency>

Related

How to include kotlin.test properly via Maven?

Our team is making first steps into Kotlin and I'm about to to migrate a test. I tried a first example from mockk (https://github.com/mockk/mockk/blob/master/mockk/common/src/test/kotlin/io/mockk/it/InjectMocksTest.kt). For some reason it seems I'm not able to use kotlin.test although I have added it via maven. Do I have to include any other modules? Or do I have to change something else?
(the mockk example uses Gradle so it doesn't help me).
This is what I'd like to use in my Kotlin test file but it which can't be found (at least not the packages I need):
(Restarting Intellij doesn't help, neither running mvn seperately)
This is my maven dependancy (Intellij shows now error):
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version> <!-- kotlin.version == 1.7.0 -->
<scope>test</scope>
</dependency>
The solution was (see hotkey's answer) to add the following maven dependency:
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit5</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
You need to add a dependency on one of kotlin-test-junit (for JUnit 4), kotlin-test-junit5 (for JUnit Jupiter), or kotlin-test-testng (for TestNG), depending on what test framework you are using.
The artifact kotlin-test contains only the common code, asserters and other stuff that can be reused across the frameworks.
The kotlin.test annotations like #Test or #BeforeTest are shipped in the test-framework-specific artifacts as typealiases to the actual annotations types of the test frameworks.

Using different JBoss BOM in profiles

I have a general question about the usage of the BOM from JBoss and WildFly.
Is the a way to build a project for both JBoss 7 and WildFly 10 using a different profile?
I tried to copy the BOM definition from WildFly into a profile like this:
<profile>
<id>WildFly10</id>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly-javaee7-with-tools</artifactId>
<version>${version.jboss.bom}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- JSON -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${version.json}</version>
</dependency>
</dependencies>
</dependencyManagement>
</profile>
Of course accourdingly with a JBoss7 profile.
But this way it won't add important libraries to the lib folder, i.e. this definition is in an ear pom and a subproject (war) adds the json dependency. Without a profile maven adds the json jar inside the lib folder, but not if I put it inside a profile.
After I read that changing dependencies in a profile is an anti-pattern [1] I would like to know how I can build my project for both JBoss7 and WildFly 10.
Update
Ok sorry for this quick shot of a question. Here are more details.
project structure:
|-parent (pom)
|- myapp (war)
|- core (jar)
|- deployment (ear)
So deployment is the project building the whole ear containing myapp as a web apllication and core as a library. myapp has a dependency to core and core to json.
In order to have all needed depenedencies with the correct version I included wildfly-javaee7-with-tools in the dependencyManagment. Also is the version of json defined in there. The core project has the json library as a normal dependency.
At this point this should be quite standard. But the thing is I want to be able to build for JBoss 7 and WildFly 10, for what I have to change
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly-javaee7-with-tools</artifactId>
<version>${version.jboss.bom}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
to
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-tools</artifactId>
<version>${version.jboss.bom}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Of course ${version.jboss.bom} will be changed from 10.1.0.Final for WildFly to 1.0.7.Final for JBoss.
In order to do so I tried to move wildfly-javaee7-with-tools into a profile. My first guess was to only move this dependency to a profile. But then the json jar doesn't get included. After that I also tried to move jsonlike above.
Without seeing the original not-profiled nor profiled pom in whole cannot say anything accurate but educated guess.
You have json in profiles dependency management.
Is it also in poms main dependencies without version? If not it will not be copied to lib nor packed. It is only managed by profiles <dependencyManagement>.
Does json need managing per profile? It seems to have ${version.json} which then anyway would be same for each profile if copied as it is in the example.
For me it seems that fix might be that you remove the json from profiles dependencyManagement and add it to main dependencies as normal dependency - this just to make profiling more simple - it can be managed but if not needed set the version of json directly to dependency.

Maven: How to disable unwanted Spring annotation configurations from another artifact?

Let's say I have two local projects A and B which both have annotated configurations, and I want to include some classes from project B (mainly domain classes) to project A. My problem is that, if I have the project B dependency in A, when I actually run A, the B project's configurations are run, and things such as a web server are started.
So my question is: how can I either disable the annotated configurations in B or exclude the classes that have the configurations to stop the unwanted configurations from running?
The solution (as per Sujata's link) turned out to be quite simple.
Say you have a dependency in project A:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
This turns into:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<optional>true</optional>
</dependency>
Now in project B, when you add the dependency to project A, A's dependencies that are declared optional will not be loaded.

#Webservice annotation exception on weblogic

I am trying to run my application which contain JAX WS (2.1) Webservice using JDeveloper 11g R2(11.1.2.3.0) in JDK 1.6.0_31-b05. The error is coming from #WebService annotation present on the class.
When I am running the application, I am getting below error,
java.lang.IllegalArgumentException: Argument(s) "type" can't be null.
at com.sun.xml.bind.api.TypeReference.<init>(TypeReference.java:89)
at com.sun.xml.ws.model.RuntimeModeler.processDocWrappedMethod(RuntimeModeler.java:758)
at com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:678)
at com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:428)
at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:277)
at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:363)
at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:202)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:496)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:539)
at weblogic.wsee.jaxws.JAXWSDeployedServlet.getEndpoint(JAXWSDeployedServlet.java:183)
It seems that embedded Web Logic is using the internal libraries instead of provided one from JDK. The classes RuntimeModeler or TypeReference are present in JDK rt.jar starts with package com.sun.xml.ws.internal. Weblogic is picking these classes from glassfish.jaxb_1.0.0.0_2-1-12.jar & glassfish.jaxws.rt_1.2.0.0_2-1-5.jar, but these jars are not part of my application.
I have already used weblogic.xml with below tag,
<prefer-web-inf-classes>true</prefer-web-inf-classes>
I tried adding jaxws-api.jar & jws-api.jar in DefaultDomain/lib directory, but that didn't work
Any clue how to resolve this exception or how to force weblogic to use jdk runtime classes? The same application work properly on stand alone weblogic.
I had the same problem and found the answer here: http://www.intropro.com/resources/blog/66-argument-s-type-can-t-be-null
In short - the problem appears because you have jaxb-impl in you classpath which overrides WebLogics own jaxb, You may not explicitly refer to this dependency from your pom.xml, but some of your other dependencies do.
In my case I had apache-cxf as maven dependency and it had jaxb 2.1.13 as sub-dependency with scope "compile". All I had to do is exclude this apaches jaxb and add my own dependency with scope "provided" to explicitly use WebLogics jaxb.
in pom.xml it looked like this:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.2</version>
<exclusions>
<exclusion>
<artifactId>jaxb-impl</artifactId>
<groupId>com.sun.xml.bind</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<scope>provided</scope>
<version>2.1.13</version>
</dependency>
You can use eclipses "Dependency Hierarchy" tab in pom.xml view or simply command line "mvn dependency:tree" to find out how jaxb-impl made it to your classpath.
In my case, i had a typo in the arguments of the operation, where two arguments had the same webParam name. Modified that and deployed, issue was resolved.
Have you tried listing the correct jar in the manifest class-path: attribute? You could also put the jdk classes in the app and try using a FilteringClassLoader to specify which classes to use from the app rather than system classloader.
http://docs.oracle.com/cd/E15051_01/wls/docs103/programming/classloading.html#wp1097263

Maven test dependency not being found

I'm declaring a test dependency on powermock with easymock bundled in.
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>1.4.12</version>
<type>pom</type>
<scope>test</scope>
</dependency>
When I run mvn test, the test src claims to be able to find org.powermock but not org.easymock, despite it being included in the above dependency.
I wondered whether it was a problem due to transitivity of the test scope, so i tried compile scope also (as the documentation http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html mentions that the compile dependencies are available at test time) without any luck.
I've also tried using a bundled jar instead of pom, to no avail. I realise i could declare the dependencies separately (ie separate dependencies for powermock and easymock) but for my purposes i'm restricted to having just the one dependency including all necessary test libs.
Tracing this back to the powermock parent pom I see that the easymock dependency is marked "provided."
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.1</version>
<scope>provided</scope>
</dependency>
Looks like powermock is expecting its clients (you in this case) to supply the easymock jars.
According to the powermock-easymock-release-full POM, it does not depend on easymock (ie easymock does not appear in the powermock-easymock-release-full dependencies). So you'll have to add another dependency to easymock, dependending on the test engine you're using (JUnit or TestNG): http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.powermock%22%20AND%20%22easymock%22

Resources