SecurityException when running plain JUnit + Mockito in Eclipse RCP Project - junit

I have an Eclipse RCP Project with multiple plugins. I am writing plain JUnit tests (no dependencies to Eclipse/UI) as separate fragments to the plugin-under-test.
When using Mockito and trying to mock an interface from another plugin (which is exported correctly; I can use the interface in my code), I get a SecurityException related to class signing:
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: interface ch.sbb.polar.client.communication.inf.service.IUserService
Mockito can only mock visible & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl$1.withBefores(JUnit45AndHigherRunnerImpl.java:27)
[...]
Caused by: org.mockito.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:238)
[...]
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[...]
Caused by: java.lang.SecurityException: Signers of 'ch.sbb.polar.client.communication.inf.service.IUserService$$EnhancerByMockitoWithCGLIB$$a8bfe723' do not match signers of other classes in package
at java.lang.ClassLoader.checkPackageSigners(ClassLoader.java:361)
at java.lang.ClassLoader.defineClass(ClassLoader.java:295)
... 40 more
When I run the tests as "JUnit Plugin tests", i.e. with an OSGi environment, everything works as expected. But I'd like to use the plain JUnit execution because of speed; in the class under test, I don't need the OSGi environment.
Does anybody know a way to do that?

As is mentioned in the comments, the root cause is that the Eclipse Orbit package of Mockito (which I had added to my target platform) is signed, and because of a bug in the underlying CGLIB, you cannot mock unsigned classes/interfaces with a signed Mockito.
See https://code.google.com/p/mockito/issues/detail?id=393 for the most detailed description. The bug is fixed in CGLIB head, but has not yet appeared in a release. Mockito only uses released versions as dependencies, so the fix is not yet in Mockito, with an unknown (to me) timeline, as when this will be in.
Workaround: Provide unsigned Mockito in separate bundle
The workaround is to package the Mockito JAR (and its dependencies) in its own bundle and export the necessary API packages.
When using Maven Tycho, JUnit, Hamcrest, and Mockito, the only way I was able to make this work and resolve all dependency / classpath / classloader issues correctly was the following way:
Create Maven module with the following entries in the pom.xml:
<packaging>eclipse-plugin</packaging>
[...]
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
</dependency>
</dependencies>
[...]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-test-libs</id>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>lib</outputDirectory>
<stripVersion>true</stripVersion>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
Use following entries in the MANIFEST.MF:
Bundle-ClassPath: lib/mockito-core.jar,
lib/objenesis.jar
Export-Package: org.mockito,
org.mockito.runners
Require-Bundle: org.junit;bundle-version="4.11.0";visibility:=reexport,
org.hamcrest.library;bundle-version="1.3.0";visibility:=reexport,
org.hamcrest.core;bundle-version="1.3.0";visibility:=reexport
And finally in your unit test fragment, add this new bundle as a dependency.

I ran into this same issue and was able to resolve it by using a more recent Orbit repository which pulls Mockito 2.x:
http://download.eclipse.org/tools/orbit/downloads/drops/R20181128170323/?d
This repository contains Mockito 2.23.0 which uses Byte Buddy instead of CGLIB.
In my target, I simply pull mockito-core 2.23.0 and Byte Buddy Java Agent 1.9.0 from the Orbit repository above.
<unit id="org.mockito" version="2.23.0.v20181106-1534"/>
<unit id="org.mockito.source" version="2.23.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>

Related

Cannot resolve type problems with eclipse

It seems that I got the wires crossed & ask you to point me the right direction.
I have a problem with the Eclipse IDE for Enterprise Java Developers (version: 2019-06 (4.12.0), build id: 20190614-1200). There is a code part where I get the error message MysqlDataSource cannot be resolved to a type. Searching the Web, I found out that this class is included in the download of mysql-connector-java JAR 8.0.14 with all dependencies. I added it over the 'Fix project setup…', where I added the JAR file to the libraries of the Java Build Path.
Unfortunately, the error message does not vanish. Can you see what I am doing wrong?
Edit 1:
With the hint from another Website, I found out that the hibernate JAR included was the source files JAR. So, I corrected it the hibernate-entitymanager JAR, clicked "Clean…" under "Project", but to no avail: the EntityManager is still unlocatable. (Well, after several tries, the first error message to resolve is no more with MySQL.)
As I learned from somebody on another Web site, the following lines have to be added to the pom.xml file:
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.2.Final</version>
</dependency>
or
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>

Junit in Jboss fuse : Waiting for dependency

I have written Junit for a camel route. The route accepts json input. The service is building and installing fine. I have installed JsonPath bundle in karaf, but I am getting the below exception while running my Junit. I have specified the maven dependency as compile.
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>1.2.0</version>
<scope>compile</scope>
</dependency>
Exception message:
Bundle Test is waiting for dependencies [(&(language=jsonpath)(objectClass=org.apache.camel.spi.LanguageResolver))]
I think the problem is in the Camel test. If you provide the source, probably we can give you some ideas.
BTW for a good reference for "How to write Camel test about something" you can check the official repo. I'm attaching you a link to the tests of jsonPath component:
https://github.com/apache/camel/tree/master/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath

osgi.wiring.package; (&(osgi.wiring.package=com.google.gson)(version>=2.3.0)(!(version>=3.0.0))))

I am trying to use com.google.maps in my OSGi bundle. I've added the dependency like this:
<dependency>
<groupId>com.google.maps</groupId>
<artifactId>google-maps-services</artifactId>
<version>0.1.7</version>
</dependency>
However, when I try to deploy this bundle to AEM, I get an error:
Unable to resolve 392.38: missing requirement [392.38] osgi.wiring.package; (&(osgi.wiring.package=com.google.gson)(version>=2.3.0)(!(version>=3.0.0))))
How can I resolve this?
go to maven central: http://search.maven.org
Advanced search
Write to the By Classname section: com.google.gson
In the list of results, find the ones that might be good for you
Download the jars and check the manifest header if the required package is exported
If you do that, you will find the following maven dependency:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
</dependency>
Alternatively, you can use JPM website for the search as it indexes all OSGi related MANIFEST headers and it mirrors the whole maven central repo. After you find the artifact that is necessary for you, there is a good chance that it is from maven central originally (so you do not have to set alternate repositories in your maven project). You can check the origin of the bundle in the details page.

Akka configuration overwritting

I'm trying to overwrite Akka configuration in my application. I have created additional lib for the application, which also has application.conf file as it uses Akka. So I have 2 of them:
application.conf in my lib:
my-conf {
something = 1
}
application.conf in my app, which uses the lib:
something-else = "foo"
my-conf {
something = 1000
}
When I'm running the app from Intellij Idea, everything is fine, and lib configuration is being overwritten. To load the config in my app I'm using simple ConfigFactory.load() operation.
But when I create a jar of my app with mvn clean compile assembly:single and try to run it with this command: java -Xmx4048m -XX:MaxPermSize=512M -Xss256K -classpath myApp.jar com.myapp.example.MyMain I get error:
Caused by: com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'something-else'
So I decided to rename the conf file in my app, and load it in such way:
val defConfig = ConfigFactory load
val myConfig = ConfigFactory load "myconf"
val combined = myConfig.withFallback(defConfig)
val config = ConfigFactory load combined
It finds missing settings, but unfortunately config from my app doesn't override config in my lib.
In my lib I load config in default way: val settings = ConfigFactory load
Also, "my-conf.something" is an important setting, and I'd like to overwrite it from my app.
What I'm doing wrong? Thanks in advance!
Also, I thought there could be an issue how I create the jar:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>com.myapp.example.MyMain</mainClass>
</manifest>
</archive>
<finalName>loadtest</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>dist-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
Straight from akka documentation:
If you are using Maven to package your application, you can also make use of the Apache Maven Shade Plugin support for Resource Transformers to merge all the reference.confs on the build classpath into one.
This resolved the issue for me.
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>reference.conf</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>akka.Main</Main-Class>
</manifestEntries>
</transformer>
</transformers>
As far as I understand, your library should create file called reference.conf. According to https://github.com/typesafehub/config :
libraries should use a Config instance provided by the app, if any,
and use ConfigFactory.load() if no special Config is provided.
Libraries should put their defaults in a reference.conf on the
classpath.
So, i suggest putting a reference.conf into your library first, to make it clear that it is default configuration, and you won't need to have a withFallback - typesafe-config will handle it for you.
Update: I don't remember how maven-assembly-plugin works - it may combine all of jar files and resources in a single file, meaning that lib/src/main/resources/application.conf will be overwritten by app/src/main/resources/application.conf in your case - so yet another reason to use reference.conf.
That's right! Just in order to add a bit more information related to that reference.conf I would say that you should go to:
Akka Documentation: http://akka.io/docs/?_ga=1.90177882.150089464.1402497958
, pick the version you are using and in it look for General->Configuration
inside that page look for 'Listing of the Reference Configuration', that's all the content you may need for that reference.conf. In my case I just copied it all.
Hope it helps to save sometime!

Help: org.apache.hadoop.hbase.MasterNotRunningException 12.34.56.78:60000

I am writting a small Java application to connect to a HBase node. The ZooKeeper connection is successful, but later, I systematically get the following error (I have changed my IP address of course):
org.apache.hadoop.hbase.MasterNotRunningException 12.34.56.78:60000
Does anyone know what is happening and how to solve this issue?
Thanks!
Ok, solved that issue. Before someone commits suicide... -> the problem is caused by a mismatch between the HBase.jar versions available in the central maven repository (currently 0.90.xx) and those used by Cloudera's CDH3 installation package (0.89.xx).
The main issue is that Cloudera compiles its own Hbase.jar and these are not available from the central repository. But, Cloudera makes them available from:
<repositories>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/content/groups/public/</url>
</repository>
</repositories>
To find the HBase version you need for your application, open http://your.node.ip.address:60010. For CDH3Beta3, it is 0.89.20100924-28. Then, add it in your pom.xml as a dependency:
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
<version>0.89.20100924-28</version>
</dependency>
Et voila!