For debugging purposes I need to keep track of a Class attributes changes.
For example consider the following class:
class Test {
int myInt;
String myString;
...
public void setMyInt(int a) ...
public void setMyString(String s) ...
public printDebugLog();
}
void main() {
Test t = new Test();
t.setMyInt(5);
t.setMyString("Hello");
t.printDebugLog();
}
I want to output to be something like:
myInt => 5
myString => Hello
The easy solution is to create logs instantly. i.e. adding a Log function as follow:
void Log(String s) {
System.out.println(s);
}
and then code the set functions like below:
void setMyString(String s) {
myString = s;
Log("myString => " + s);
}
this requires all the set functions to be written variously and I wonder if there are any better solution for such matter. For example it might be easier (if possible) to create a SetValue function which accepts two variables and set the first attribute to the value of the second object. or something like this.
Any idea?
To do this you should wrap your class with orthogonal code that performs logging.
Since your class does not implement interface you cannot use dynamic proxy, so you have to use one of solutions that use byte code engineering.
The strongest solution I know is AspectJ. But probably you even do not need it. You can use Javassist or CGLIb - the byte code engineering libraries that allow creating proxies that wrap classes, so you can add code that performs logging.
You can use AOP to intercept the setter methods and log when they are called. A quick google should give you a few examples.
If you debug via JPDA,
you can create a Breakpoint
on a field you like to watch.
Related
Service interface:
public interface UserInterface {
void present();
void onStart();
void onStop();
}
I have two implementations: TextUserInterface and GraphicalUserInterface.
How can I identify the one I want to use when I launch my program? Source
private static void main(String[] args) {
ServiceLoader<UserInterface> uiLoader = ServiceLoader.load(UserInterface.class);
UserInterface ui = uiLoader.? //what to do to identify the one I want to use?
}
I was thinking of introducing an enum with the type of UI, so I could just iterate through all services and pick the one I'd like to, but isn't this approach just a misuse of services? In this case when I want to pick GraphicalUserInterface I could just skip the ServiceLoader part and just instantiate one. The only difference I see is fact that without services, I'd have to require the GraphicalUserInterface module, which "kind of" breaks the encapsulation.
I don't actually think that it would be a misuse of it. As a matter of fact, what you get from ServiceLoader.load(...) method is an Iteratable object, and if you need for a specific service, you will have to iterate through all the available instances.
The idea of the enum is not that bad, but I suggest that you take advantage of the Java stream and filter for the instance you need. For example, you might have something like that:
enum UserInterfaceType {
TEXT_UI, GRAPH_UI;
}
public interface UserInterface {
UserInterfaceType getTypeUI();
...
}
// In your main method
ServiceLoader<UserInterface> uiLoader = ServiceLoader.load(UserInterface.class);
UserInterface ui = uiLoader.steam()
.filter(p -> p->getTypeUI() == <TypeUIyouNeed> )
.findFirst()
.get();
That is open to a number of possibilities, for example you can put this is a separated method, which receives in input a UserInterfaceType value, and it can retrieve the service implementation based on the type enum value you passed.
As I said, that is just the main idea, but definitely you are not doing any misuse of the ServiceLoader.
I had difficulties finding a relevant title since it is not a simple issue. I will try to explain. I have a class responsible of error reporting whose methods basically wrap multiple ways of reporting an error.
For example, I have a method failTest:
public static void failTest(Logger log, Exception e, String message, boolean reportToES, String esTestPath, String esTestSet, String esTestInstance)
{
log.error(e, message);
someExternalErrorReportingService(reportToES, esTestPath,esTestSet,esTestInstance);
Assert.fail(e,message);
}
And I call this error reporting method in many, many places and it doesn't seem a good practice (too many parameters, hard to follow their order etc.) to just call it with the es* parameters each and every time because they don't change very often so they could be set up once and then reused.
And I came up with this version
public static void failTest(Logger log, Exception e, String message)
{//same body
}
And then added method to set up es* parameters
setES(boolean reportToES, String esTestPath, String esTestSet, String esTestInstance)
{
this.reportToES = reportToES;
this.esTestPath = esTestPath;
this.esTestSet = esTestSet;
this.esTestInstance=esTestInstance;
}
and of course added these instance variables above.
And only now I can enunciate the issue:
now if I want to use this error reporting class I need to first instantiate it and set the es* fields. The issue is that I often need to use the error reporting in a utility class that could be static but now, with my change above, I have to instantiate it and set up the error reporting class in order to have the es* fields set before I call failTest().
To conclude, I don't like this solution either because I can't use static utility classes anymore and moreover some utility classes are already used in a static way so cannot be refactored to non-static and will end up being used sometimes static, sometimes instantiated.
So the question is, do you see a better solution in order to simplify the calling of failTest() in utility classes?
To give you an example, we have a client that
sets up the error reporting class and sets up its es* fields
This client calls utility method Utility.doSomething
public static doSomething(reportToES, esTestPath, esTestSet, esTestInstance)
{
try{
methodThatThrowsFatalException()
}
catch(Exception e){
failTest(log, e, "Some smart message",reportToES, esTestPath, esTestSet, esTestInstance);
}
}
Now, in order to reduce the number of parameters we can just add setErrorReportingInstance to the Utility class,
then in client instantiate the Utility, then utilityInstance. setErrorReportingInstance(configuredErrorReportingInstance). And doSomething becomes:
public static doSomethingRefactored()
{
try{
methodThatThrowsFatalException()
}
catch(Exception e){
errorReportingInstance.failTest(log, e, "Some smart message");
}
}
What is not ok, from my point of view, is that:
1. I have complicated the usage of Utility. Now I have to make sure it is instantiated before I use it. It's inconvenient when having a lot of Utility like classes.
2. I cannot make static methods in Utility if I have to do error reporting in their implementation.
3. The methods that are already used as static will remain with the es* parameters in their signature (due to backward compatibility). So I will have in the same class methods like doSomething and also methods like doSomethingRefactored.
4. I have created a dependency between utility classes and error reporting so I have an issue when I need to test the utility methods
The question is, how can I keep the simple design of utility classes as simple collection of static utility methods but in the same time use the error reporting class but without passing too many parameters since it is bad practice?
More details:
Actually the client is many TestNG test cases:
So first I had :
class TestClass1
{
static final boolean REPORT_TO_ES="true",
static final String ES_TEST_PATH="somePath", //and so on for the others
#Test
{
Utility1.doSomething(REPORT_TO_ES,ES_TEST_PATH,ES_TEST_SET,...
Utility2.doSomethingElse(REPORT_TO_ES,ES_TEST_PATH,ES_TEST_SET,...
Utility3.doSomethingMoreUseful(REPORT_TO_ES,ES_TEST_PATH,ES_TEST_SET,...
Utility4.doSomethingSomething(REPORT_TO_ES,ES_TEST_PATH,ES_TEST_SET,...
}
And then I would try to get rid of calling the doSomethings with the ES* values
by setting them once on the ErrorReporter instance (so I would also make ErrorReporter non-static).
class TestClass1
{
private ErrorReporter errorReporter = new ErrorReporter();
errorReporter.setReportToEs(true);
errorReporter.setEsTestPath("somePath");//and so on
Utility1 utility1Instance = new Utility1();
utility1Instance.setErrorReporter(errorReporter);
Utility2 utility1Instance = new Utility2();
utility2Instance.setErrorReporter(errorReporter);
#Test
{
utility1Instance.doSomething();
utility2Instance.doSomethingElse();
...
The title to your question should be "Static Mess".
Take a look at how real loggers work and you may get some ideas. Log4J and Slf4j are well respected ones. You need to control all of your static variables. You could create a Logger class that encapsulates the ES data and does the real work of logging:
// Does the real work of logging.
class Logger {
public Logger(all of your es data)
public fail(String msg) // Logs msg
}
Then you need a static collection of these Loggers referenced by name (I assume you have more than one set of es data). This gives you a central place to go get the loggers. Works if you're in a static method or somewhere else. The static collection goes inside the LogFactory object
class LogFactory {
private static Map<String, Logger> loggers ...
public static Logger get(String name) ...
}
Here is your static method using the new logger:
public static doSomething() {
try {
methodThatThrowsFatalException()
}
catch(Exception e){
LogFactory.get("Util").failTest(e, "Some smart message");
}
}
I would add a clear or reset method to LogFactory so that you have a chance of writing JUnit tests for your code. For the same reason I would write a NullLogger (in which case you might want to pull out an interface that the NullLogger and the EsLogger can both implement.
You need to decide how to add Loggers to LogFactory. I suggest doing it in your main class. Resist the temptation to do it in a static initializer.
LogFactory could also be written so it holds a collection and not a static collection. You then just keep a static reference (a Singleton) to it. Just keep in mind that you'll want a way to clear the Singleton to make unit testing possible.
Good luck.
I have a task to test a console application. I can access one method, but would also like to check that the string formatting is working correctly.
As this method does not return a string, but rather prints to the console, is there a way I can intercept the list printed line?
Does it even make sense to test this sort of thing?
Here is a sample how to catch output to the System.out:
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
System.setOut(new java.io.PrintStream(out));
System.out.println("Test output");
System.err.println("Out was: " + out.toString());
You can use System.setOut() to redirect the System.out.println writes to a PrintStream(OutputStream). Then you can write that OutputStream to a String and test it.
The way for testing this its make a good design with a "output" abstraction instead of print directly to "system.out". For example:
interface Output {
void print(String data);
}
Then you inject this dependency into the class that needs to send information to the output:
class MyProgram {
private Output out;
public MyProgram(Output output) {
this.out = output;
}
public doSomething() {
// do something
out.print("i do something!);
}
}
Then you can test easily with a mock (with mockito for example):
public void test_my_program() {
Output mockOutput = mock(Output.class);
MyProgram myProgram = new MyProgram(mockOutput);
myProgram.doSomething();
verity(mockOutput).print("do something!");
}
I don't verify the code but its more or less correct and i expect enough for you to get the idea. Always its the same, testing its not difficult, the difficult thing its design good testable code, here we are only using abstraction and dependency injection, two basic principles of OO.
The real advantage of this code its that now its not tied to "System.out", you can use this class in a web application for example if you want. For example making and output implementation that talks to the web client via websocket. This is another OO principle, your class is now "Open-Close", you can add functionality (websocket crazy example :P) without modify your actual code.
I have started reading the Spring in Action book.
I have no knowledge of JUnit which I think my doubt is about.
There is a code fragment where the author refers to and says that it is difficult to test:
package com.springinaction.knights;
public classDamselRescuingKnight implements Knight {
private RescueDamselQuest quest;
public DamselRescuingKnight() {
quest = new RescueDamselQuest();
}
public voidembarkOnQuest() throwsQuestException {
quest.embark();
}
}
The author says that:
It’d be terribly difficult to write a unit test for DamselRescuingKnight. In such a test, you’d like to be able to assert that the quest’s embark() method is called when the knight’s embarkOnQuest() is called. But there’s no clear way to accomplish that here. Unfortunately, DamselRescuingKnight will remain untested.
What does the author mean by this?
Why is the code difficult to test here?
My initial thought is that it is difficult to test because the "RescureDamselQuest" object is initialized in the constructor. This makes it difficult to for example insert a mock object. A mock object would help you test that the embark() method is called on the "RescueDamselQuest" object.
A better way to solve this can be to either include a parameter in the constructor (usually I prefer this method):
public DamselRescuingKnight(RescueDamselQuest quest){
this.quest = quest;
}
Or add a setter:
public void setDamselRescuingKnight(RescueDamselQuest quest){
this.quest = quest;
}
A common example I give is consider that you want to open a file, parse it, and get a data class out. Most will do something like:
Data openAndParse(String filename) {
...openFile
...parse
}
By doing it this way, the file open methodology and parse is highly coupled and difficult to test. If you have a problem in open and parse is it with the parse or the open?
By writing JUnit test, you are forced, for simplicity sake, to do something like...
BufferedReader openFile(String filename) {
...open file and return reader
}
Data parse(BufferedReader input) {
...parse and return data
}
JUnit leads us to a more cohesive solution. We write JUnit test simply by creating a string, constructing a StringReader, and then a BufferedReader. Well guess what? Very similarly we can now use parse to accept input from a variety of sources not just the file.
It's difficult to test because the quest implementation cannot be swapped out. Without byte code modification there's no trivial way to see if embark is called.
If you could set the quest implementation in a constructor or setter you could pass in an implementation that can spy on the call to embark.
One need to increase accessibility of fields and method of class to test. For example if one is testing a method which is package-private (default) then test cases which are generally in different package will not able to test this method. Therefore it is advised to to change in accessibility of fields to test the method. DamselRescuingKnight class can be tested which is not using DI by modifying the accessibility of RescueDamselQuest field from private to default. Then writing test case using mockito. Here is code for test case
#Test
public void knightShouldEmbarkOnQuest() throws QuestException {
DamselRescuingKnight knight = new DamselRescuingKnight();
RescueDamselQuest quest = mock(RescueDamselQuest.class);
knight.quest = quest;
knight.embarkOnQuest();
verify(quest, times(1)).embark();
}
And line which was changed in DamselRescuingKnight class to remove private accessibility
RescueDamselQuest quest;
The Java OpenGL GL interface contains about 2000 methods, for debugging purposes I would like to wrap an instance and delegate calls to it while doing some logging. The logging code can be pushed to the same method in each case, so the task of writing out the method implementations looks like it could be automated. An example of what I am trying to do:
import javax.media.opengl.GL;
public class GLErrorLogger implements GL {
private final GL backing;
public GLErrorLogger(GL delegateToMe) {
backing = delegateToMe;
}
private void checkErrorCode() {
// Log frame and thread details depending on gl state
}
/**
* Example of a method
*/
#Override
public int glGenLists(int arg0) {
checkErrorCode();
int retVal = backing.glGenLists(arg0);
checkErrorCode();
return retVal;
}
// rest of methods here...
}
In other words copy the method name and parameters (minus their types) into a call on the backing object, surround with calls to the logging method, and if there is a return type then assign the result to a variable of this type and return it at the end of the method.
I looked at creating a one shot eclipse code template to autogenerate the methods, but there wasn't an immediately obvious way to do pattern matching on the return type. Can anyone suggest a way to do this in Eclipse or any of its code generation tools to save me pulling out the regex toolkit?
You might want to use an Aspect to create the necessary bytecode for you instead of producing all the source code. Take a look at the Traceing Aspect example here: Traceing Aspect Example.
As an Alternative, you can create a Java Dynamic Proxy, if you do not want to use AspectJ as Thrid party Library. Please refer to Dynamic Proxy Tutorial
Use JDK proxies as suggested, or: use a Mock Framework like EasyMock or Mockito.
GL mock = EasyMock.createMock(GL.class);
EasyMock.expect(mock.someMethod()).andReturn(someValue);
// or, if you need to do more computing:
EasyMock.expect(mock.someOtherMethod()).andAnswer(new IAnswer<String>() {
public String answer() throws Throwable {
return "some value you calculate here";
}
});
EasyMock.replay(mock);
now you can use the mock Object for all methods you configured.
See the EasyMock readme for more info.