Open GoogleCodeExporter opened 8 years ago
Hi,
Are you running this signed jar in an OSGI container ?
Original comment by brice.du...@gmail.com
on 7 Nov 2012 at 1:11
No - the test is executed in Eclipse but using "Run as JUnit...". So a "normal"
JVM is launched without any OSGi class loading in place.
Otherwise I would expect some Equinox classes in my stack trace (e.g.
org.eclipse.osgi.internal.loader.BundleLoader)
Original comment by jebo0...@googlemail.com
on 7 Nov 2012 at 1:20
OK, anyway when reading your reported issue, I'm nit sure we could do
something. I don't know very well the security / signed package and related
stuff, it might not be an issue with mockito, but related to policies.
Java offers a policy mechanism that CGLIB is documenting here :
http://cglib.sourceforge.net/howto.html
JAVA security protects system resources form unauthorized access by untrusted
code. Code can be identified by signer and code base url (jar or class file) it
can be local or downloaded from network. Classes generated by CGLIB do not
exist at configuration and JVM startup time (generated at runtime), but all
generated classes have the same protection domain (signer and codebase) as
cglib itself and can be used in WS or by RMI application with security manager.
To grant permissions for generated classes grant permissions for cglib
binaries. Default security configuration is in java.policy file. This is
example policy file, it grants all permissions for cglib and generated code.
grant codeBase "file:${user.dir}/jars/cglib.jar"{
permission java.security.AllPermission;
};
You can try that, just replace cglib.jar by mockito.jar
Original comment by brice.du...@gmail.com
on 7 Nov 2012 at 5:12
Also if you have any pointer or even pull request to fix the issue, it would be
very welcome :)
Original comment by brice.du...@gmail.com
on 7 Nov 2012 at 6:17
Linking to the original issue on eclipse :
https://bugs.eclipse.org/bugs/show_bug.cgi?id=349164
Original comment by brice.du...@gmail.com
on 8 Nov 2012 at 9:51
Thanks for cross-referencing... from my point of view these cases are *similar*
but they are not the same. The Eclipse bug refers to the situation where a
signed mockito bundle is used (the one from the Eclipse Orbit project). This
bug (and my own problem) seems to be caused by creating mocks for a package
that originates from a signed jar.
But your java.policy file approach seems promising to me. I hope to find some
time to try this later today.
Thanks.
Original comment by mknaue...@gmail.com
on 8 Nov 2012 at 9:55
Unfortunately it didn't work in our case, and after some digging around I am
quite confident that the java.policy approach cannot work. The
SecurityException will be thrown anyway.
What's a bit weird is the fact that we are not seeing the error together with
Mockito.
In any case, we've changed our build setup now to work around this problem. In
case we are signing our jar files, we are not running the JUnit tests at all.
They are run in a non-signing build only. This is not an approach that I'd
suggest that others should follow, but it helps us to survive the time until we
have a proper fix and a final solution for this problem.
Original comment by mknaue...@gmail.com
on 10 Nov 2012 at 6:35
So it looks like Mockito is not really working if one wants to mock classes
that come from signed jars?
I haven't spend great deal of time so I may be wrong. We need to generate the
proxies to the same package so that it is possible to mock package-protected
methods.
1. we could improve mockito so that we can generate proxies with a different
package but make sure mocking still works nicely for package-protected methods.
I don't know if this is even possible :)
2. we could offer a configuration option / extension point so that the user can
specify the package of the proxy classes. For example, mock(Foo.class,
withSettings().fromSignedJar()). However, mocking of package-protected methods
or classes will not be possible. Some of those limitations may not be
detectable so we won't be able to improve their error reporting.
Hope that helps!
Original comment by szcze...@gmail.com
on 10 Nov 2012 at 6:49
I found in some descriptions in the web that PowerMock
(http://code.google.com/p/powermock/) is able to work with signed jar's. Maybe
it would help to look into their code how they solved this.
Original comment by mknaue...@gmail.com
on 10 Nov 2012 at 7:02
We also deal with signed packages. E.g. we check if the jar is signed and then
we apply different package naming rule. Apparently, it does not work for your
scenario.
Can you try using PowerMockito and see if it can work in your environement?
Original comment by szcze...@gmail.com
on 10 Nov 2012 at 8:08
I'm facing the same issue. The tests are actually executed outside of an OSGi
container using Maven Surefire plug-in (maven-surefire-plugin:2.14.1). It seems
that I can't spy/mock any class out of a signed jar. Unfortunately, the signed
jars come from a dependency. Thus, I'm not in a situation to easily work around
this.
Original comment by eclipseguru@gmail.com
on 9 Dec 2013 at 2:45
FWIW, my stack trace is a litte bit different, though:
org.mockito.cglib.core.CodeGenerationException:
java.lang.reflect.InvocationTargetException-->null
at java.lang.ClassLoader.checkCerts(ClassLoader.java:952)
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:666)
at java.lang.ClassLoader.defineClass(ClassLoader.java:794)
at sun.reflect.GeneratedMethodAccessor12.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.mockito.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:385)
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:220)
at org.mockito.cglib.reflect.FastClass$Generator.create(FastClass.java:65)
at org.mockito.cglib.proxy.MethodProxy.helper(MethodProxy.java:121)
at org.mockito.cglib.proxy.MethodProxy.init(MethodProxy.java:75)
at org.mockito.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:214)
at org.mockito.internal.creation.AbstractMockitoMethodProxy.invokeSuper(AbstractMockitoMethodProxy.java:10)
at org.mockito.internal.invocation.realmethod.CGLIBProxyRealMethod.invoke(CGLIBProxyRealMethod.java:22)
at org.mockito.internal.invocation.realmethod.FilteredCGLIBProxyRealMethod.invoke(FilteredCGLIBProxyRealMethod.java:27)
at org.mockito.internal.invocation.Invocation.callRealMethod(Invocation.java:213)
at org.mockito.internal.stubbing.answers.CallsRealMethods.answer(CallsRealMethods.java:36)
at org.mockito.internal.MockHandler.handle(MockHandler.java:101)
at org.mockito.internal.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:48)
at codegen.my.SpyedClass$$EnhancerByMockitoWithCGLIB$$65d4d85.getSomething(<generated>)
at my.SpyedClass.getSomething(SpyedClass.java:123)
..
Original comment by eclipseguru@gmail.com
on 9 Dec 2013 at 2:58
Hey,
I'm not an expert on signed package, I've never worked with them. However it
does look similar to this issue :
http://stackoverflow.com/questions/19358145/cglib-error-after-launching-program-
signer-information-does-not-match-signer-in
Could it be a classpath issue.
Also it the problem is still there, if you could reproduce in a project and
attach it to the issue.
Original comment by brice.du...@gmail.com
on 9 Dec 2013 at 5:45
Or even better cold you check the MANIFEST of the mockito jar ?
I'm not sure but users have reported similar error with signed CGLIB jars,
Mockito is not signed, but maybe you are running a different version of
mockito.
⇒ https://forums.oracle.com/thread/2472732
Original comment by brice.du...@gmail.com
on 9 Dec 2013 at 5:50
Also if it is a classpath issue, because there's different version of a class,
take a look at a possible way to troubleshoot the issue ⇒
http://stackoverflow.com/a/17565202/48136
Original comment by brice.du...@gmail.com
on 9 Dec 2013 at 5:58
FWIW, there is a very good analysis posted on https://bugs.eclipse.org/349164
(comment 5). I'll quote the relevant bits below:
> This is how mockito determines the projection domain used later for class
> definition.
>
>
> static {
> PROTECTION_DOMAIN = (ProtectionDomain)AccessController
> .doPrivileged(new PrivilegedAction() {
> public Object run() {
> return ReflectUtils.class.getProtectionDomain();
> }
> });
>
>
> The class definition takes place here:
>
>
> public static Class defineClass(String className,
> byte[] b,
> ClassLoader loader)
> throws Exception
> {
> Object[] args = new Object[]{
> className,
> b,
> new Integer(0),
> new Integer(b.length),
> PROTECTION_DOMAIN
> };
> return (Class)DEFINE_CLASS.invoke(loader, args);
> }
>
> DEFINE_CLASS is a Method object that points to the according
> java.lang.ClassLoader.defineClass(...). The latter method calls
> ClassLoader.checkCerts(). A comment in that code states
>
> // first class in this package gets to define which
> // certificates must be the same for all other classes
> // in this package
>
> If you debug the example above you will see that the first class loaded in
> the package is the class or the interface that you want to mock. As the
> certificates of the mock are provided by the
> PROTECTION_DOMAIN.getCodeSource().getCertificates() they do not match. This
> throws a SecurityException, which is swallowed. But it leads to the
> misleading exception message mentioned in my description above.
>
> Not signing mockito would solve the problem described above, since then the
> certificates of both classes would be the same (that is to say none). But
> once you want to mock a class that actually has certificates, I would expect
> that the same problem occurs, since the certificates again would not match.
>
> Maybe I'm getting this all wrong, since it isn't my domain at all. But I
> think a solution would be to retrieve the protection domain of the class I
> want to mock instead using the static approach.
>
Original comment by eclipseguru@gmail.com
on 15 Apr 2014 at 11:07
Actually the mentioned code is the one of CGLIB.
But to try a fix we would need a test case for that. Also I'm not sure about
this either, as I wonder how the generated class (mock) will behave as it will
use other classes of CGLIB/Mockito.
Original comment by brice.du...@gmail.com
on 21 Apr 2014 at 4:51
Is it allowed to customize code in mockito-repackaged or should the modifcation
be submitted upstream to CGLIB?
Original comment by gun...@wagenknecht.org
on 17 Jul 2014 at 12:09
FYI:
I submitted a pull request to CGLIB in order to allow Mockito (and other users
of CGLIB) to use the proper ProtectionDomain when generating classes.
https://github.com/cglib/cglib/pull/15
Feedback is welcome!
Original comment by gun...@wagenknecht.org
on 17 Jul 2014 at 8:46
Hi, the pull request has been merged. Is there a procedure for updating CGLIB
in Mockito?
Original comment by gun...@wagenknecht.org
on 18 Jul 2014 at 4:27
Original issue reported on code.google.com by
jebo0...@googlemail.com
on 7 Nov 2012 at 12:36