I want to use ASM to verify how often certain methods are called and what their arguments and result is. However, at runtime it ends with a java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader): attempted duplicate class definition for name: "com/foo/bar/DefaultType".
For that reason I want to ensure that it is not an ASM (Objectweb) problem, so it tried to just pass the bytes without any modification with the following code:
#Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer)
throws IllegalClassFormatException {
byte[] result;
if(className.startsWith("com/foo/bar"))
{
ClassReader reader = new ClassReader(classfileBuffer);
try
{
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
reader.accept(writer, 0);
result = writer.toByteArray();
}
catch(Exception e)
{
result = null;
}
}
else
{
// do nothing
result = null;
}
return result;
}
But even after this modification I get the same Error. Any hints what I should change to get this code working?
Late answer to an old question.
One way these errors can occur is due to how the COMPUTE_FRAMES option of ClassWriter is implemented. In particular, the frame computation will sometimes need to figure out a common superclass for two given classes; to do this, it will load the classes it is interested in using Class.forName. If your codebase uses a non-trivial class loading setup, it may happen that a class gets loaded in an unpexected class loader this way (I can't recall the precise conditions, but I have had this happen to me). The solution is to override the getCommonSuperclass method of ClassWriter to perform the same computation in a safer way.
Related
I have this TestNG test method code:
#InjectMocks
private FilmeService filmeService = new FilmeServiceImpl();
#Mock
private FilmeDAO filmeDao;
#BeforeMethod(alwaysRun=true)
public void injectDao() {
MockitoAnnotations.initMocks(this);
}
//... another tests here
#Test
public void getRandomEnqueteFilmes() {
#SuppressWarnings("unchecked")
List<Filme> listaFilmes = mock(List.class);
when(listaFilmes.get(anyInt())).thenReturn(any(Filme.class));
when(filmeDao.listAll()).thenReturn(listaFilmes);
List<Filme> filmes = filmeService.getRandomEnqueteFilmes();
assertNotNull(filmes, "Lista de filmes retornou vazia");
assertEquals(filmes.size(), 2, "Lista não retornou com 2 filmes");
}
And I'm getting a "org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 1 recorded:" in the call of listAll() method in this code:
#Override
public List<Filme> getRandomEnqueteFilmes() {
int indice1, indice2 = 0;
List<Filme> filmesExibir = new ArrayList<Filme>();
List<Filme> filmes = dao.listAll();
Random randomGenerator = new Random();
indice1 = randomGenerator.nextInt(5);
do {
indice2 = randomGenerator.nextInt(5);
} while(indice1 == indice2);
filmesExibir.add(filmes.get(indice1));
filmesExibir.add(filmes.get(indice2));
return filmesExibir;
}
I'm prety sure I'm missing something here but I don't know what it is! Someone help?
when(listaFilmes.get(anyInt())).thenReturn(any(Filme.class));
There's your problem. You can't use any in a return value. any is a Matcher—it's used to match parameter values for stubbing and verification—and doesn't make sense in defining a return value for a call. You'll need to explicitly return a Filme instance, or leave it null (which is the default behavior, which would defeat the point of stubbing).
I should note that it's often a good idea to use a real List instead of a mock List. Unlike custom code you've developed, List implementations are well-defined and well-tested, and unlike mock Lists a real List is very unlikely to break if you refactor your system under test to call different methods. It's a matter of style and testing philosophy, but you may find it advantageous just to use a real List here.
Why would the above rule cause that exception? Well, this explanation breaks some of Mockito's abstractions, but matchers don't behave like you think they might—they record a value onto a secret ThreadLocal stack of ArgumentMatcher objects and return null or some other dummy value, and in the call to when or verify Mockito sees a non-empty stack and knows to use those Matchers in preference to actual argument values. As far as Mockito and the Java evaluation order are concerned, your code looks like the following:
when(listaFilmes.get(anyInt())).thenReturn(null);
when(filmeDao.listAll(any())).thenReturn(listaFilmes); // nonsense
Naturally Mockito sees an any matcher, and listAll doesn't take an argument, so there are 0 matchers expected, 1 recorded.
I'm using a Calendar object to determine whether or not to increase the workload of a system based on current day/hour values. Given that this object uses static methods, I'm using PowerMock to mock the static methods with the following annotations:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ Calendar.class })
The code under test is pretty simple (though my logic needs work, I know):
public void determineDefaultMaximumScans() throws ParseException{
parseTime();
Calendar cal = Calendar.getInstance();
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
System.out.println(cal.get(Calendar.DAY_OF_WEEK));
if(dayOfWeek == (Calendar.SATURDAY) || dayOfWeek == (Calendar.SUNDAY)){
setDefaultMax(calculateNewDefaultMax(getDefaultMax()));
System.out.println("defaultMax increased by 20%");
} else {
if(currentTime.after(afterHoursBegin) && currentTime.before(afterHoursEnd)){
System.out.println("Not afterhours. Maintaining current maximum.");
setDefaultMax(defaultMax);
System.out.println("Current Maximum number of scans: " + getDefaultMax());
}
}
}
My test case reads as follows:
#SuppressWarnings("static-access")
#Test
public void testDetermineMaximumScans() throws ParseException{
PowerMock.mockStatic(Calendar.class);
String beginningTime = "18:00";
String endingTime = "05:00";
mockAfterHoursBegin = parser.parse(beginningTime);
mockAfterHoursEnd = parser.parse(endingTime);
mockCurrentTime = parser.parse(parser.format(new Date()));
EasyMock.expect(Calendar.getInstance()).andReturn(mockCalendar);
EasyMock.expect(mockCalendar.get(Calendar.DAY_OF_WEEK)).andReturn(6);
EasyMock.replay(mocks);
offHourMaximumCalculator.determineDefaultMaximumScans();
EasyMock.verify(mocks);
}
As of now, all of my attempts to return a specific value result in the following assertion error. Now I vaguely understand why it's returning the default but I do not see why I can't force the value or how to get around this expectation. Mocks in general are still a frustrating mystery to me. What am I missing?
java.lang.AssertionError:
Expectation failure on verify:
Calendar.get(7): expected: 1, actual: 0
Mocks are fairly simple. But wanting to mock static methods is a big running after complexity. I generally do not recommend to mock something like a Calendar. If you do weird and complex thing with it, just encapsulate in something you can test and mock easily.
And in fact, we pretty much never use Calendar.getInstance(). It returns something according to the locale. But it's rare that you don't want a specific calendar i.e. GregorianCalendar. So just do new GregorianCalendar.
But anyway, add a protected method doing
protected Calendar newCalendar() {
return Calendar.getInstance(); // or new GregorianCalendar()
}
will take 2 minutes and then a simple partial mock will do the trick.
Finally, I also don't recommend to use Calendar. You have a much nicer API in java.util.date in Java 8.
All this said, here is how you should do it. Calendar is a system class, so you need to follow a real specific path which is explained here.
#RunWith(PowerMockRunner.class)
#PrepareForTest(Calendar.class)
public class MyTest {
#Test
public void testDetermineMaximumScans() throws ParseException {
PowerMock.mockStatic(Calendar.class);
Calendar calendar = mock(Calendar.class);
EasyMock.expect(Calendar.getInstance()).andReturn(calendar);
EasyMock.expect(calendar.get(Calendar.DAY_OF_WEEK)).andReturn(6);
// really important to replayAll to replay the static expectation
PowerMock.replayAll(calendar);
assertThat(Calendar.getInstance().get(Calendar.DAY_OF_WEEK)).isEqualTo(6);
// and verifyAll is you want to verify that the static call actually happened
PowerMock.verifyAll();
}
}
what is the absolute minimal mocking that must be done to pass this test?
code:
class PrivateStaticFinal {
private static final Integer variable = 0;
public static Integer method() { return variable + 1; }
}
test:
#RunWith(PowerMockRunner.class)
#PrepareForTest(PrivateStaticFinal.class)
class PrivateStaticFinalTest {
#Test
public void testMethod() {
//TODO PrivateStaticFinal.variable = 100
assertEquals(PrivateStaticFinal.method(), 101);
}
}
related: Mock private static final variables in the testing class (no clear answer)
Disclaimer: After a lot of hunting around on various threads I have found an answer. It can be done, but the general concensus is that it is not very safe but seeing as how you are doing this ONLY IN UNIT TESTS, I think you accept those risks :)
The answer is not Mocking, since most Mocking does not allow you to hack into a final. The answer is a little more "hacky", where you are actually modifying the private field when Java is calling is core java.lang.reflect.Field and java.lang.reflect.Modifier classes (reflection). Looking at this answer I was able to piece together the rest of your test, without the need for mocking that solves your problem.
The problem with that answer is I was running into NoSuchFieldException when trying to modify the variable. The help for that lay in another post on how to access a field that was private and not public.
Reflection/Field Manipulation Explained:
Since Mocking cannot handle final, instead what we end up doing is hacking into the root of the field itself. When we use the Field manipulations (reflection), we are looking for the specific variable inside of a class/object. Once Java finds it we get the "modifiers" of it, which tell the variable what restrictions/rules it has like final, static, private, public, etc. We find the right variable, and then tell the code that it is accessible which allows us to change these modifiers. Once we have changed the "access" at the root to allow us to manipulate it, we are toggling off the "final" part of it. We then can change the value and set it to whatever we need.
To put it simply, we are modifying the variable to allow us to change its properties, removing the propety for final, and then changing the value since it is no longer final. For more info on this, check out the post where the idea came from.
So step by step we pass in the variable we want to manipulate and...
// Mark the field as public so we can toy with it
field.setAccessible(true);
// Get the Modifiers for the Fields
Field modifiersField = Field.class.getDeclaredField("modifiers");
// Allow us to change the modifiers
modifiersField.setAccessible(true);
// Remove final modifier from field by blanking out the bit that says "FINAL" in the Modifiers
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
// Set new value
field.set(null, newValue);
Combining this all into a new SUPER ANSWER you get.
#RunWith(PowerMockRunner.class)
#PrepareForTest()
class PrivateStaticFinalTest {
#Test
public void testMethod(){
try {
setFinalStatic(PrivateStaticFinal.class.getDeclaredField("variable"), Integer.valueOf(100));
}
catch (SecurityException e) {fail();}
catch (NoSuchFieldException e) {fail();}
catch (Exception e) {fail();}
assertEquals(PrivateStaticFinal.method(), Integer.valueOf(101));
}
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
// remove final modifier from field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
}
Update
The above solution will work only for those constants which is initialized in static block.When declaring and initializing the constant at the same time, it can happen that the compiler inlines it, at which point any change to the original value is ignored.
I've got a question concerning code duplication and refactoring, hope it's not too general. Say you've got a rather small piece of code (~5 lines) which is a sequence of function invocations that is - not a very low level. This code is repeated in several places, so it would probably be a good idea to extract a method here. However, in this particular example, this new function would suffer from low cohesion (which manifests itself, among others, by having a hard time finding a good name for the function). The reason for that is probably because this repeated code is just a part of a bigger algorithm - and it's difficult to divide it into well named steps.
What would you suggest in such scenario?
Edit:
I wanted to keep the question on a general level, so that more people can potentially find it useful, but obviously it would be best to back it up with some code sample. The example might not be the best one ever (it smells in quite a few ways), but I hope it does its job:
class SocketAction {
private static class AlwaysCreateSessionLoginHandler extends LoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
private static class AutoConnectAnyDeviceLoginHandler extends LoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
if (Server.isUserRegistered(socketAction._sess.getUserLogin())) {
Log.logSysInfo("Session autoconnect - acquiring list of action threads...");
String[] sa = Server.getSessionList(socketAction._sess.getUserID());
Log.logSysInfo("Session autoconnect - list of action threads acquired.");
for (int i = 0; i < sa.length; i += 7) {
socketAction.abandonCommThreads();
Server.attachSocketToSession(sa[i + 1], socketAction._commSendThread.getSock());
return;
}
}
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
private static class OnlyNewSessionLoginHandler extends LoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
socketAction.killOldSessionsForUser();
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
}
Question is too general to really say, but as an exercise:
Suppose you abstract it. Think about what the likely reasons are for wanting to change the resulting 5-line function. Would you want likely make changes that apply to all users, or would you end up having to write a new function that's slightly different from the old one, each time some caller has reason to want a change?
If you would want to change it for all users, it's a viable abstraction. Give it a poor name now, you might think of a better one later.
If you're going to end up splitting this function off into lots of similar versions as your code evolves in future, it's probably not a viable abstraction. You could still write the function, but it's more of a code-saving "helper function" than it is part of your formal model of the problem. This isn't very satisfactory: the repetition of this amount of code is a bit worrying, because it suggests there should be a viable abstraction in there somewhere.
Maybe 4 of the 5 lines could be abstracted out, since they're more cohesive, and the fifth line just so happens to be hanging around with them at the moment. Then you could write 2 new functions: one which is this new abstraction, and the other is just a helper that calls the new function and then executes line 5. One of these functions might then have a longer expected useful life than the other...
To me, the litmus test is: if I need to make a change to this sequence of code in one place, (e.g. add a line, change the order), would I need to make the same change in other locations?
If the answer is yes, then it is a logical, "atomic" entity and should be refactored. If the answer is no, then it's a sequence of operations that happen to work in more than one situation - and if refactored, will likely cause you more trouble in the future.
I was thinking about this lately and I understand exactly what you're getting at. It occurs to me that this is an implementation abstraction more than anything, and is thus more palatable if you can avoid changing an interface. For instance, in C++ I might extract the function into the cpp without touching the header. This somewhat lessens the requirement for the function abstraction to be well-formed and meaningful to the class user since it's invisible to them until they really need it (when adding to the implementation).
For me the operative word is "threshold". Another word for this would probably be "smell".
Things are always in a balance. It sounds like (in this case) like the center of balance is in cohesiveness (cool); and as you've only got a small number of duplicates it's not hard to manage.
If you had some major "event" occur and you went to "1000" duplicates then the balance would have shiftyed and so might you're approach.
To me, a few managable duplicates isn't a signal to refactor (yet); but I'd keep an eye on it.
Inheritance is Your friend!
Don't duplicate code. Even if a single line of code is very long or difficult, refactor it to a separate method with a distinctive name. Think of it like someone who will read Your code in a year. If You name this function "blabla", will the next guy know what this function does without reading it's code? If not, You need to change the name. After a week of thinking like that You'll get used to it and Your code will be 12% more readable! ;)
class SocketAction {
private static abstract class CreateSessionLoginHandler extends LoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
Server.checkAllowedDeviceCount(socketAction._sess.getDeviceID());
socketAction.registerSession();
socketAction._sess.runApplication();
}
}
private static class AlwaysCreateSessionLoginHandler extends CreateSessionLoginHandler;
private static class AutoConnectAnyDeviceLoginHandler extends CreateSessionLoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
if (Server.isUserRegistered(socketAction._sess.getUserLogin())) {
Log.logSysInfo("Session autoconnect - acquiring list of action threads...");
String[] sa = Server.getSessionList(socketAction._sess.getUserID());
Log.logSysInfo("Session autoconnect - list of action threads acquired.");
for (int i = 0; i < sa.length; i += 7) {
socketAction.abandonCommThreads();
Server.attachSocketToSession(sa[i + 1], socketAction._commSendThread.getSock());
return;
}
}
super.onLoginCorrect(socketAction);
}
}
private static class OnlyNewSessionLoginHandler extends CreateSessionLoginHandler {
#Override
protected void onLoginCorrect(SocketAction socketAction) throws IllegalAccessException, IOException {
socketAction.killOldSessionsForUser();
super.onLoginCorrect(socketAction);
}
}
}
I know that this type of question has been asked over and over again, however, I have yet to find a definitive answer for the problem I am looking into.
From all the content on exception handling that I have read it appears that the general concensus is that exceptions should only be used for exceptional circumstances. I've also read in many places that one should use, where possible, return values to indicate problems or failures (such as login failure, validation failure of some sort). My problem is, when using these return values, how does one communicate the contextual information of the problem? With exceptions, one can add the contextual information to the exception and allow that to bubble up. Let me try and use a code example to explain:
Let's say we have a basic abstract class (I've left out some of the details) which represents some kind of format definition for a String. This class essentially dictates how the format of a given string should be.
public abstract class ADataEntryDefinition
{
public boolean isValid(String data);
}
let's say I extend this to perform some security validation on the string:
public class SecureDataEntryDefinition extends ADataEntryDefinition
{
public boolean isValid(String data)
{
//do some security checks on the format of the data
}
}
The validate method will take in a String and return true if the string matches the data definition defined by the class.
Moving along, let's say I have a class which manages several of these data definitions, and this class' responsibility is to validate each entry in a comma separated String against one of the data definitions it maintains.
public class DataSetDefinitions
{
private List<ADataEntryDefinition> dataDefinitions = ...
public boolean isValid(String dataValues)
{
//obtain each string in dataValues delimited by a ',' into String[]
//called dataEntryValues
int i=0;
for (ADataEntryDefinition dataEntry : dataDefinitions)
{
if (!dataEntry.isValid(dataEntryValues[i++])
{
return false;
}
}
return true;
}
}
Now, to me these methods seem way to general to throw exceptions in the event of invalid data (for one, invalid data may be expected in some cases). In this case, I like the approach of returning true/false to indicate validation failure and subsequently allowing the caller to judge how serious it is. So the caller does the following:
boolean success = false;
success = dataSetDefinitions.isValid(someString);
Suppose a specific caller like the above deems the failed validation to be critical, and hence, must subsequently throw an exception to prevent processing from continuing; where should it obtain the contextual information it needs to convey the problem... how should it know that 2 layers (calls) down the validation actually failed due to security problems in the SecureDataEntryDefinition class (or any other subclass for that matter).
I guess I could add a method like so:
public class DataSetDefinitions
{
private List<ADataEntryDefinition> dataDefinitions = ...
public boolean isValid(String dataValues)
{
....
}
public String getValidationErrorMsg() {...}
}
which would return the error message of the last failed validation. Then, the following could be done by the caller upon failed validation:
success = dataSetDefinitions.isValid(someString);
if (!success)
throw new SomeException(dataSetDefinitions.getValidationErrorMsg());
But to me this just seems like having the class (DataSetDefinitions in this case) know or maintain state about the previous validation which it shouldn't. Taking into account that this class may perform validation of several different, independent strings, it seems wrong having it maintain state about the validation of any given one of them.
I guess this question is essentially asking how one designs methods to be general - not taking the law into their own hands by throwing exceptions unnecessarily, but allowing callers to decide on the severity - but still allowing the callers to obtain detailed contextual information in the event that the caller needs to communicate the problem. Is there a better way of doing the above?
Apologies if this was very long-winded :/ Any responses will be appreciated.
Ciao.
Don't return a bool. Return a class that encapsulates the success/failure state, plus the associated information. That way, you can do something like:
DataEntryStatus status = isValid(...);
if (!status.isValid()) {
throw status.generateStatusException();
}
and the status object itself generates the appropriate exception, thus maintaining encapsulation.
You could return a user defined class instead of a simple bool in order to provide more contextual information.
It would be something similar to the strategy used with events. We have a EventArgs class from which other classes derive in order to provide more contextual information for a given type of event.
The way i solve it most of the time is defining several class constants and return these. Then in the business logic of my controllers i would just check against these values statically.
<?php
class Test
{
const SUCCESS = 1000;
const EMAIL_FAIL = 2001;
const SAVE_FAIL = 2002;
...
public function save($value)
{
if (!$this->writetodb($value)
return self::SAVE_FAIL;
elseif(!$this->sendMailToAdmin())
return self::EMAIL_FAIL;
else
return self::SUCCESS;
}
}
$test = new Test();
$result = $test->save('my value');
switch ($result) {
case Test::SUCCESS:
echo 'Yay!';
break;
case Test::SAVE_FAIL:
echo 'Error saving!';
break;
case Test::EMAIL_FAIL:
echo 'Error sending email!';
break;
}