I use TestNG and I would like to run different times the same test and each time use specific data providers which will be used in a subset of test methods, in other words I would like to run the test class with different data without change the test itself.
I have got a problem creating the factory for the test class, here is my case:
#Test
public class MyTest {
#Factory
public Object[] createInstances() {
DataTest dataTest_1 = new DataTest("foo", true);
DataTest dataTest_2 = new DataTest("FOO", false);
Object[] result = new Object[]{
new MyTest(dataTest_1);
new MyTest(dataTest_2)
};
return result;
}
private final DataTest dataTest;
public MyTest(DataTest dataTest) {
this.dataTest = dataTest;
}
}
Error:
Configuring TestNG with: org.apache.maven.surefire.testng.conf.TestNGMapConfigurator#18e8568
org.apache.maven.surefire.util.SurefireReflectionException: java.lang.reflect.InvocationTargetException; nested exception is java.lang.reflect.InvocationTargetException: null
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.testng.TestNGException:
The factory method class MyTest.createInstances() threw an exception
at org.testng.internal.FactoryMethod.invoke(FactoryMethod.java:92)
at org.testng.internal.TestNGClassFinder.<init>(TestNGClassFinder.java:140)
at org.testng.TestRunner.initMethods(TestRunner.java:405)
at org.testng.TestRunner.init(TestRunner.java:231)
at org.testng.TestRunner.init(TestRunner.java:201)
at org.testng.TestRunner.<init>(TestRunner.java:150)
at org.testng.SuiteRunner$DefaultTestRunnerFactory.newTestRunner(SuiteRunner.java:523)
at org.testng.SuiteRunner.init(SuiteRunner.java:157)
at org.testng.SuiteRunner.<init>(SuiteRunner.java:111)
at org.testng.TestNG.createSuiteRunner(TestNG.java:1212)
at org.testng.TestNG.createSuiteRunners(TestNG.java:1199)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1053)
at org.testng.TestNG.run(TestNG.java:974)
at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:77)
at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:110)
at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:106)
... 9 more
Caused by: java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.testng.internal.FactoryMethod.invoke(FactoryMethod.java:80)
... 24 more
Moreover, DataTest component at the moment contains two parameters but it will contains much more parameters - to define the expected values - and a collection of data providers.
Eventually, if I use a String as parameter of the test class - just as a attempt - the test runs.
The problem is that you cannot instantiate a new instance of MyTest in order to call createInstances. So it becomes a chicken and egg problem. If you declare createInstances as a static method, it should work.
Related
I'm trying to send objects using Java RMI in a JavaFX 2 project, but when the following code runs it returns a NotSerializableException.
My Admin class is Serializable and so is the super class. However it seems the exception is pointing towards the JavaFX SimpleIntegerProperty fields inside the Admin class.
I don't know what to do from here as the class being sent via RMI is serializable. Any help much appreciated.
ObservableList<Admin> data = null;
try
{
data = FXCollections.observableArrayList(Main.docServer.getAllAdmins());
}
catch (RemoteException e)
{
e.printStackTrace();
}
The error I receive:
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: javafx.beans.property.SimpleIntegerProperty
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:191)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at $Proxy0.getAllAdmins(Unknown Source)
at com.reece.doc.views.ViewAdmin.getContent(ViewAdmin.java:34)
at com.reece.doc.ApplicationWindow.start(ApplicationWindow.java:32)
at com.reece.doc.Main.start(Main.java:57)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:206)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:173)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)
Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: javafx.beans.property.SimpleIntegerProperty
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at java.util.ArrayList.readObject(ArrayList.java:733)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:324)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:173)
... 10 more
Caused by: java.io.NotSerializableException: javafx.beans.property.SimpleIntegerProperty
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at java.util.ArrayList.writeObject(ArrayList.java:710)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:975)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at sun.rmi.server.UnicastRef.marshalValue(UnicastRef.java:292)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:332)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
the class being sent via RMI is serializable
It's only serializable if it extends Serializable or Externalizable and all of its non-static non-transient member variables do so as well, and so on recursively until closure. In this case you clearly have one of type javafx.beans.property.SimpleIntegerProperty, which as the exception tells you isn't serializable:
java.io.NotSerializableException: javafx.beans.property.SimpleIntegerProperty
So any class that refers to it, directly or indirectly, isn't serializable either.
You may mark a member variable not to be serialized. And add to class new int field.
private int variableInt = 0;
private transient IntegerProperty variable;
public IntegerProperty variableProperty()
{
if(variable == null)
{
variable = new SimpleIntegerProperty();
variable.set(variableInt);
}
return variable;
}
public void setVariable(int variable)
{
if(this.variable != null)
this.variable.set(variable);
variableInt = variable;
}
public int getVariable()
{
if(variable == null)
return variableInt;
else
return variable.get();
}
I wrote a validation advisor in Kotlin which throws EntityValidationException when validation fails:
#Aspect
#Named
class ValidationAdvisor
#Inject constructor(val validator: EntityValidator) {
#Around(EVERY_SAVE_AND_UPDATE_TO_DATABASE)
fun validate(point: ProceedingJoinPoint): Any {
val result: List<ConstraintViolation<Any>> = validator.validate(getEntity(point))
if (isEntityValid(result))
return point.proceed()
throw EntityValidationException(
violationInfos = result as List<ConstraintViolationInfo>
)
}
private fun getEntity(point: ProceedingJoinPoint): Any {
return point.args[0]
}
private fun isEntityValid(result: List<ConstraintViolation<Any>>): Boolean {
return result.isEmpty()
}
companion object {
const val EVERY_SAVE_AND_UPDATE_TO_DATABASE = "execution(* beans.repositories.BaseRepository.save(..))"
}
}
I have a JUnit test (I write some parts in Kotlin and some in Java, to learn Kotlin in existing private project) which checks if exception is thrown:
#Test(expected = EntityValidationException.class)
public void test_WhenNameIsNotPresent_ThenExceptionIsThrown() throws Exception {
repository.save(/* entity to save */);
}
But then I saw that test fails because it throws UndeclaredThrowableException instead of EntityValidationException. Next, I read that Kotlin does not have checked exception. I think not only me have this problem - I am pretty sure that way of handling exceptions with #ControllerAdvice in Spring and Java also may be problematic when we decide to switch to Kotlin in production projects - because it rely on class which is thrown, and throwing UndeclaredThrowableException take away from us this possibility. Is there a way to by-pass this behaviour, to make sure that is possible to switch to Kotlin and old Spring way of handling exceptions (and unit tests for ValidationAdvisor) will remain unchanged? Thank you in advance for any help.
P.S. Github repo for project is available here: Playgroud for Kotlin, Spring Data etc..
P.S.2 Stacktrace:
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.reflect.UndeclaredThrowableException
at com.sun.proxy.$Proxy65.save(Unknown Source)
at ActorValidationTest.test_WhenNameIsNotPresent_ThenExceptionIsThrown(ActorValidationTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
... 26 more
Caused by: beans.validator.exceptions.EntityValidationException
at beans.aop.validation.ValidationAdvisor.validate(ValidationAdvisor.kt:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
... 37 more
For me looks like EntityValidationException (which I want to be thrown) causes UndeclaredThrowableException.
EntityValidationException Kotlin class code:
package beans.validator.exceptions
import beans.validator.constraintViolation.ConstraintViolationInfo
class EntityValidationException (val violationInfos: List<ConstraintViolationInfo>) : Exception() {
}
P.S.3 This also didn't work:
#Around(EVERY_SAVE_AND_UPDATE_TO_DATABASE)
#Throws(EntityValidationException::class)
fun validate(point: ProceedingJoinPoint): Any /* rest of code*/
P.S.4 Maybe the problem is that #Aspect is #Around Spring Data repository?
companion object {
const val EVERY_SAVE_AND_UPDATE_TO_DATABASE = "execution(* beans.repositories.BaseRepository.save(..))"
}
....
#NoRepositoryBean
public interface BaseRepository<ENTITY, IDENTIFIER extends Serializable>
extends JpaRepository<ENTITY, IDENTIFIER>, JpaSpecificationExecutor<ENTITY> {
}
You're trying to make the method save() or your repository throw a checked exception that it doesn't declare. So even if the aspect declares it, that can't work. You need to make your exception extend RuntimeException.
Below is the code for my attempt to run aggregates on hazelcast using Hazelcast Client. The first aggregate works out just fine, but the 2nd one throws an java.io.NotSerializableException: co.near.hazelcast.AggregateExperiment
My code:
public class AggregateExperiment {
public void runTest(){
ClientConfig clientConfig = new ClientConfig();
clientConfig.addAddress("127.0.0.1:5701");
clientConfig.setClassLoader(this.getClass().getClassLoader());
HazelcastInstance client = HazelcastClient.newHazelcastClient(clientConfig);
IMap<String, Integer> map = client.getMap("customers");
Supplier<String, Integer, Integer> supplier = Supplier.all();
// Choose the average aggregation
Aggregation<String, Integer, Integer> aggregation = Aggregations.integerAvg();
int average = map.aggregate(supplier, aggregation);
System.out.println("Average of inputs = "+average);
supplier = Supplier.fromKeyPredicate(new MyKeyPredicate());
// Choose the sum aggregation
aggregation = Aggregations.integerSum();
average = map.aggregate(supplier, aggregation );
System.out.println("Average of inputs = "+average);
}
public class MyKeyPredicate implements KeyPredicate<String> {
public boolean evaluate(String key) {
return Integer.parseInt(key) % 4 == 0;
}
}
}
Error messages :
Average of inputs = 1
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.hazelcast.core.HazelcastException: java.util.concurrent.ExecutionException: com.hazelcast.nio.serialization.HazelcastSerializationException: java.io.NotSerializableException: co.near.hazelcast.AggregateExperiment
at com.hazelcast.client.proxy.ClientMapProxy.aggregate(ClientMapProxy.java:988)
at com.hazelcast.client.proxy.ClientMapProxy.aggregate(ClientMapProxy.java:960)
at co.near.hazelcast.AggregateExperiment.runTest(AggregateExperiment.java:31)
at co.near.hazelcast.MainExperiment.main(MainExperiment.java:131)
... 6 more
Caused by: java.util.concurrent.ExecutionException: com.hazelcast.nio.serialization.HazelcastSerializationException: java.io.NotSerializableException: co.near.hazelcast.AggregateExperiment
at com.hazelcast.client.spi.impl.ClientInvocationFuture.resolveException(ClientInvocationFuture.java:188)
at com.hazelcast.client.spi.impl.ClientInvocationFuture.resolveResponse(ClientInvocationFuture.java:160)
at com.hazelcast.client.spi.impl.ClientInvocationFuture.access$000(ClientInvocationFuture.java:41)
at com.hazelcast.client.spi.impl.ClientInvocationFuture$1.run(ClientInvocationFuture.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76)
at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:92)
Caused by: com.hazelcast.nio.serialization.HazelcastSerializationException: java.io.NotSerializableException: co.near.hazelcast.AggregateExperiment
at com.hazelcast.nio.serialization.SerializationServiceImpl.handleException(SerializationServiceImpl.java:380)
at com.hazelcast.nio.serialization.SerializationServiceImpl.writeObject(SerializationServiceImpl.java:307)
at com.hazelcast.nio.serialization.ByteArrayObjectDataOutput.writeObject(ByteArrayObjectDataOutput.java:315)
at com.hazelcast.mapreduce.aggregation.impl.KeyPredicateSupplier.writeData(KeyPredicateSupplier.java:79)
at com.hazelcast.nio.serialization.DataSerializer.write(DataSerializer.java:140)
at com.hazelcast.nio.serialization.DataSerializer.write(DataSerializer.java:39)
at com.hazelcast.nio.serialization.StreamSerializerAdapter.write(StreamSerializerAdapter.java:37)
at com.hazelcast.nio.serialization.SerializationServiceImpl.writeObject(SerializationServiceImpl.java:305)
at com.hazelcast.nio.serialization.ByteArrayObjectDataOutput.writeObject(ByteArrayObjectDataOutput.java:315)
at com.hazelcast.mapreduce.aggregation.impl.SupplierConsumingMapper.writeData(SupplierConsumingMapper.java:75)
at com.hazelcast.nio.serialization.DataSerializer.write(DataSerializer.java:140)
at com.hazelcast.nio.serialization.DataSerializer.write(DataSerializer.java:39)
at com.hazelcast.nio.serialization.StreamSerializerAdapter.write(StreamSerializerAdapter.java:37)
at com.hazelcast.nio.serialization.SerializationServiceImpl.writeObject(SerializationServiceImpl.java:305)
at com.hazelcast.nio.serialization.ByteArrayObjectDataOutput.writeObject(ByteArrayObjectDataOutput.java:315)
at com.hazelcast.mapreduce.impl.client.ClientMapReduceRequest.writeData(ClientMapReduceRequest.java:204)
at com.hazelcast.mapreduce.impl.client.ClientMapReduceRequest.write(ClientMapReduceRequest.java:173)
at com.hazelcast.client.impl.client.ClientRequest.writePortable(ClientRequest.java:86)
at com.hazelcast.nio.serialization.PortableSerializer.writeInternal(PortableSerializer.java:62)
at com.hazelcast.nio.serialization.PortableSerializer.write(PortableSerializer.java:53)
at com.hazelcast.nio.serialization.PortableSerializer.write(PortableSerializer.java:29)
at com.hazelcast.nio.serialization.StreamSerializerAdapter.write(StreamSerializerAdapter.java:37)
at com.hazelcast.nio.serialization.SerializationServiceImpl.toData(SerializationServiceImpl.java:227)
at com.hazelcast.nio.serialization.SerializationServiceImpl.toData(SerializationServiceImpl.java:207)
at com.hazelcast.client.spi.impl.ClientInvocationServiceSupport.send(ClientInvocationServiceSupport.java:104)
at com.hazelcast.client.spi.impl.ClientSmartInvocationServiceImpl.invokeOnRandomTarget(ClientSmartInvocationServiceImpl.java:60)
at com.hazelcast.client.spi.impl.ClientInvocation.invokeOnSelection(ClientInvocation.java:163)
at com.hazelcast.client.spi.impl.ClientInvocation.invoke(ClientInvocation.java:147)
at com.hazelcast.client.proxy.ClientMapReduceProxy$ClientJob.invoke(ClientMapReduceProxy.java:124)
at com.hazelcast.mapreduce.impl.AbstractJob.submit(AbstractJob.java:119)
at com.hazelcast.mapreduce.impl.AbstractJob$ReducingSubmittableJobImpl.submit(AbstractJob.java:348)
at com.hazelcast.client.proxy.ClientMapProxy.aggregate(ClientMapProxy.java:985)
at com.hazelcast.client.proxy.ClientMapProxy.aggregate(ClientMapProxy.java:960)
at co.near.hazelcast.AggregateExperiment.runTest(AggregateExperiment.java:31)
at co.near.hazelcast.MainExperiment.main(MainExperiment.java:131)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:745)
at ------ End remote and begin local stack-trace ------.(Unknown Source)
at com.hazelcast.client.spi.impl.ClientInvocationFuture.resolveException(ClientInvocationFuture.java:175)
... 8 more
Caused by: java.io.NotSerializableException: co.near.hazelcast.AggregateExperiment
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at com.hazelcast.nio.serialization.DefaultSerializers$ObjectSerializer.write(DefaultSerializers.java:223)
at com.hazelcast.nio.serialization.StreamSerializerAdapter.write(StreamSerializerAdapter.java:37)
at com.hazelcast.nio.serialization.SerializationServiceImpl.writeObject(SerializationServiceImpl.java:305)
at com.hazelcast.nio.serialization.ByteArrayObjectDataOutput.writeObject(ByteArrayObjectDataOutput.java:315)
at com.hazelcast.mapreduce.aggregation.impl.KeyPredicateSupplier.writeData(KeyPredicateSupplier.java:79)
at com.hazelcast.nio.serialization.DataSerializer.write(DataSerializer.java:140)
at com.hazelcast.nio.serialization.DataSerializer.write(DataSerializer.java:39)
at com.hazelcast.nio.serialization.StreamSerializerAdapter.write(StreamSerializerAdapter.java:37)
at com.hazelcast.nio.serialization.SerializationServiceImpl.writeObject(SerializationServiceImpl.java:305)
at com.hazelcast.nio.serialization.ByteArrayObjectDataOutput.writeObject(ByteArrayObjectDataOutput.java:315)
at com.hazelcast.mapreduce.aggregation.impl.SupplierConsumingMapper.writeData(SupplierConsumingMapper.java:75)
at com.hazelcast.nio.serialization.DataSerializer.write(DataSerializer.java:140)
at com.hazelcast.nio.serialization.DataSerializer.write(DataSerializer.java:39)
at com.hazelcast.nio.serialization.StreamSerializerAdapter.write(StreamSerializerAdapter.java:37)
at com.hazelcast.nio.serialization.SerializationServiceImpl.writeObject(SerializationServiceImpl.java:305)
at com.hazelcast.nio.serialization.ByteArrayObjectDataOutput.writeObject(ByteArrayObjectDataOutput.java:315)
at com.hazelcast.mapreduce.impl.client.ClientMapReduceRequest.writeData(ClientMapReduceRequest.java:204)
at com.hazelcast.mapreduce.impl.client.ClientMapReduceRequest.write(ClientMapReduceRequest.java:173)
at com.hazelcast.client.impl.client.ClientRequest.writePortable(ClientRequest.java:86)
at com.hazelcast.nio.serialization.PortableSerializer.writeInternal(PortableSerializer.java:62)
at com.hazelcast.nio.serialization.PortableSerializer.write(PortableSerializer.java:53)
at com.hazelcast.nio.serialization.PortableSerializer.write(PortableSerializer.java:29)
at com.hazelcast.nio.serialization.StreamSerializerAdapter.write(StreamSerializerAdapter.java:37)
at com.hazelcast.nio.serialization.SerializationServiceImpl.toData(SerializationServiceImpl.java:227)
at com.hazelcast.nio.serialization.SerializationServiceImpl.toData(SerializationServiceImpl.java:207)
at com.hazelcast.client.spi.impl.ClientInvocationServiceSupport.send(ClientInvocationServiceSupport.java:104)
at com.hazelcast.client.spi.impl.ClientSmartInvocationServiceImpl.invokeOnRandomTarget(ClientSmartInvocationServiceImpl.java:60)
at com.hazelcast.client.spi.impl.ClientInvocation.invokeOnSelection(ClientInvocation.java:163)
at com.hazelcast.client.spi.impl.ClientInvocation.invoke(ClientInvocation.java:147)
at com.hazelcast.client.proxy.ClientMapReduceProxy$ClientJob.invoke(ClientMapReduceProxy.java:124)
at com.hazelcast.mapreduce.impl.AbstractJob.submit(AbstractJob.java:119)
at com.hazelcast.mapreduce.impl.AbstractJob$ReducingSubmittableJobImpl.submit(AbstractJob.java:348)
at com.hazelcast.client.proxy.ClientMapProxy.aggregate(ClientMapProxy.java:985)
at com.hazelcast.client.proxy.ClientMapProxy.aggregate(ClientMapProxy.java:960)
at co.near.hazelcast.AggregateExperiment.runTest(AggregateExperiment.java:31)
at co.near.hazelcast.MainExperiment.main(MainExperiment.java:131)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:745)
Any help is much appreciated. Thanks
Instances of the inner class MyKeyPredicate contain an implicit reference to parent AggregateExperiment instance. This makes MyKeyPredicate not serializable. You should make MyKeyPredicate static:
public static class MyKeyPredicate implements KeyPredicate<String> {
...
Hazelcast as of now does not support distributed classloading which would be needed for the code above to work properly.
An issue is github is already opened for the same https://github.com/hazelcast/hazelcast/issues/7394
For now, those who really want to use Hazelcast in this manner can explore https://github.com/serkan-ozal/hermgen as well
I've done a bunch of googling and messing around with my code but in the end I can't seem to figure out why the static mocking isn't working with PowerMock and Mockito.
I am trying to mock the LogCommand class' on() method in the JavaHg Library https://bitbucket.org/aragost/javahg which takes a javahg BaseRepository object as an argument and returns an instance of the LogCommand class. I want to have this return a mock log object so I can verify whether it's execute() command is called, but Mockito exceptions keep getting thrown.
Here's my code:
#RunWith(PowerMockRunner.class)
#PrepareForTest(LogCommand.class)
public class MyRepositoryTest {
private BaseRepository mockHgRepo;
private MyRepository myRepository;
#Before
public void before() {
mockHgRepo = mock(BaseRepository.class);
PowerMockito.mockStatic(LogCommand.class);
}
#Test
public void staticMockTest() throws IOException {
LogCommand mockLogCommand = mock(LogCommand.class);
when(LogCommand.on(any(BaseRepository.class))).thenReturn(mockLogCommand); // Problem Line!
myRepository = new MyRepository(mockHgRepo);
}
}
With this code I get stack trace:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected here:
-> at com.mycompany.repository.config.MyRepositoryTest.getNextTagNumberTest(MyRepositoryTest.java:39)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
at com.mycompany.myRepository.config.MyRepositoryTest.staticMockTest(MyRepositoryTest.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:312)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTestInSuper(PowerMockJUnit49RunnerDelegateImpl.java:116)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTest(PowerMockJUnit49RunnerDelegateImpl.java:77)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:284)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:209)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
If I remove the matchers and use a BaseRepository object in the when instead of a matcher, it still throws an exception:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
It is a limitation of the mock engine.
-> at com.mycompany.repository.config.MyRepositoryTest.getNextTagNumberTest(MyRepositoryTest.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:312)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTestInSuper(PowerMockJUnit49RunnerDelegateImpl.java:116)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTest(PowerMockJUnit49RunnerDelegateImpl.java:77)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:284)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:209)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Any help would be greatly appreciated--thanks!
Edit: As per #Ducan's request, here is some example code that is doing a very similar thing as the third party code I am using. Thanks!
public class TestRepository {
private String repoLocation;
public static TestRepository on (String repoLocation) {
return new TestRepository(repoLocation);
}
public TestRepository(String repoLocation, String extraflags) {
this.repoLocation = repoLocation;
}
private TestRepository (String repoLocation) {
this(repoLocation, "default flags");
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(TestRepository.class)
public class MyRepositoryTest {
#Test
public void staticMockTest() throws IOException {
PowerMockito.mockStatic(TestRepository.class);
TestRepository mockRepository = mock(TestRepository.class);
when(TestRepository.on(anyString())).thenReturn(mockRepository);
}
}
This does not work, but gives a different exception from above, which I'm guessing may be a root problem that are somehow hidden from the ones above:
java.lang.VerifyError: Inconsistent stackmap frames at branch target 51 in method com.mycompany.repository.config.TestRepository.<init>(Ljava/lang/String;)V at offset 41
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2413)
at java.lang.Class.getDeclaredConstructors(Class.java:1855)
at org.mockito.internal.creation.jmock.ClassImposterizer.setConstructorsAccessible(ClassImposterizer.java:75)
at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:70)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:110)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:60)
at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:70)
at com.mycompany.MyRepositoryTest.staticMockTest(MyRepositoryTest.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:312)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTestInSuper(PowerMockJUnit49RunnerDelegateImpl.java:116)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTest(PowerMockJUnit49RunnerDelegateImpl.java:77)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:284)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:209)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Progress? If I set it so on() calls a constructor that doesn't call another constructor this(), it doesn't give me this error.
Recently I had a similar issue trying to test my source code where static method from external class is used.
I solved this using EasyMock and PowerMock.
#RunWith(PowerMockRunner.class)
#PowerMockIgnore("javax.management.*")
#PrepareForTest({ManagementFactory.class, InstallerAppCheckerManagerImpl.class})
public class AppCheckerTester {
#Test
public void testBeanManager() throws Exception {
// this action is required by PowerMock
PowerMock.mockStatic(ManagementFactory.class);
// here is where a mock for static method is defined
MBeanServer server = PowerMock.createMock(MBeanServer.class);
EasyMock.expect(ManagementFactory.getPlatformMBeanServer()).andReturn(server);
// ...
PowerMock.replayAll();
/* some test logic between replay and verify. */
PowerMock.verifyAll();
}
}
#PowerMockIgnore defers the loading of a certain package to the parent classloader. Static method from javax.management is used in this case:
ManagementFactory.getPlatformMBeanServer()
#PrepareForTest is used to configure both your class and external class.
Hope this ideas help you in your test case.
I believe the error is in the line:
LogCommand mockLogCommand = mock(LogCommand.class);
which appears to calling the mock(Class) method from the Mockito class (due to a static import), when it should be from PowerMockito.
Your PowerMock setup seems to be incomplete.
Include the following three dependencies:
testCompile 'org.powermock:powermock-api-mockito:1.6.2'
testCompile 'org.powermock:powermock-module-junit4-rule:1.6.2'
testCompile 'org.powermock:powermock-classloading-xstream:1.6.2'
Add the following rule as a field to your unit test class:
#Rule public PowerMockRule rule = new PowerMockRule();
Additionally add the following annotation to your test class:
#PowerMockIgnore("org.mockito.*")
Then just follow the instructions on Mocking Static Methods.
MockitoAnnotations.initMocks(this);
do this on your setupMethod to enable anotations
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
I have a HiveStorageHandler if I do select * from myTable it returns all the rows in the underlying storage.
When I do something like select col1 from myTable the underlying mapreduce job throws an exception:
java.lang.RuntimeException: Error in configuring object
at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:109)
at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:75)
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:413)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:332)
at org.apache.hadoop.mapred.Child$4.run(Child.java:268)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1438)
at org.apache.hadoop.mapred.Child.main(Child.java:262)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:106)
... 9 more
Caused by: java.lang.RuntimeException: Error in configuring object
at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:109)
at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:75)
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
at org.apache.hadoop.mapred.MapRunner.configure(MapRunner.java:34)
... 14 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:106)
... 17 more
Caused by: java.lang.RuntimeException: Map operator initialization failed
at org.apache.hadoop.hive.ql.exec.ExecMapper.configure(ExecMapper.java:119)
... 22 more
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: org.apache.hadoop.hive.ql.metadata.HiveException: Configuration and input path are inconsistent
at org.apache.hadoop.hive.ql.exec.MapOperator.setChildren(MapOperator.java:526)
at org.apache.hadoop.hive.ql.exec.ExecMapper.configure(ExecMapper.java:90)
... 22 more
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Configuration and input path are inconsistent
at org.apache.hadoop.hive.ql.exec.MapOperator.setChildren(MapOperator.java:520)
... 23 more
2015-02-12 15:45:51,881 INFO org.apache.hadoop.mapred.Task: Runnning cleanup for the task
If I introduce a HiveMetaHook.preCreateTable and set the location to what my input-path on hdfs is then it works. But my path changes dynamically, and I can't constantly update this property:
#Override
public void preCreateTable(Table tbl) throws MetaException {
if (tbl.getSd().getLocation() != null) {
throw new MetaException("LOCATION should be null.");
}
tbl.getSd().setLocation(*hard-coded-input-path*);
}
I did this based on the following posting.
This was happening because I was changing the the mapred.input.dir on the fly to point to a particular file on hdfs. Now, once i'm finished with own calculations, I set the mapred.input.dir back to what hive had set it to.
I have my own Split for this InputFormat. So every-time FileSplit.getPath() is invoked I return what hive expects which is the original mapred.input.dir and now everything works.
class MySplit extends org.apache.hadoop.mapred.FileSplit {
public MySplit(InputSplit actualSplit, String hiveInputPath) {
super (new Path(hiveInputPath), 0,0, (String[]) null);
this.actualSplit = actualSplit;
}
//do not override getPath that way hiveInputPath is returned
InputSplit getActualSplit() {
return actualSplit;
}
....
}