I have a method
import org.apache.logging.log4j.Logger;
public class SendEmail
{
Logger log = LogManager.getRootLogger();
public static String getStackTrace(final Throwable throwable)
{
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}
public static void main(String[] args)
{
try
{
//Some Code
}
catch (Exception e)
{
log.error(getStackTrace(e));
}
}
}
and I want to add getStackTrace() method to Logger by inheritance (Note : Logger is Interface not Class) so I can call it by log object so I can replace log.error(getStackTrace(e)) ; by log.error(log.getStackTrace(e)) ;
any help ?
The simple way is to use logger.error("message", exception) but if you want your custom method you will need create your own class and keep the original logger inside. There is an error and debug methods, but if you need others you will need to create by yourself (like warn).
public class MyLogger {
final Logger target;
public MyLogger(Logger target) {
this.target = target;
}
public void error(Object message) {
target.error(message);
}
public void debug(Object message) {
target.debug(message);
}
//...
public String getStackTrace(final Throwable throwable) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}
}
In another class:
private static final MyLogger logger = new MyLogger(LogManager.getRootLogger());
public void someMethod() {
try {
//
}
catch (Exception e) {
logger.error(logger.getStackTrace(e));
}
}
Related
I need to write a test to verify that when an IOException is thrown by the private method_C, Method_B returns True.
But
public final class A{
public static Boolean Method_B(){
try{
//call a private method C which throws IOException
Method_C
}
catch(final IOException e) {
return Boolean.True
}
}
private static Method_C() throws IOException {
return something;
}
What I tried:
#Test
public void testSomeExceptionOccured() throws IOException {
A Amock = mock(A.class);
doThrow(IOException.class).when(Amock.Method_C(any(),any(),any(),any()));
Boolean x = A.Method_B(some_inputs);
Assert.assertEquals(Boolean.TRUE, x);
}
I am getting compilation errors :
1.Cannot mock a final class
2. Method_C has private access in A
Any suggestions on how this can be rectified?
you are required to use finally in try catch
import java.io.*;
public class Test {
public static Boolean Method_B() {
try {
System.out.println("Main working going..");
File file = new File("./nofile.txt");
FileInputStream fis = new FileInputStream(file);
} catch (IOException e) {
// Exceptiona handling
System.out.println("No file found ");
} catch (Exception e) {
// Exceptiona handling
System.out.println(e);
} finally {
return true;
}
}
public static void main(String args[]) {
if (Test.Method_B()) {
System.out.println("Show true ans");
} else {
System.out.println("Sorry error occure");
}
}
}
Is there any way to implement AOP logging to public method of class that implements Runnable and ran by ExecutorService?
Thread class
#Component
#Scope("prototype")
public class FileProcessor implements Runnable {
private final LinkedBlockingQueue<File> filesQueue;
private final GiftCertificateMapper certificateMapper;
private final File errorFolder;
private static final ReentrantLock LOCK = new ReentrantLock();
private static final Logger LOGGER = LoggerFactory.getLogger(FileProcessor.class);
public FileProcessor(LinkedBlockingQueue<File> filesQueue, GiftCertificateMapper certificateMapper,
File errorFolder) {
this.filesQueue = filesQueue;
this.certificateMapper = certificateMapper;
this.errorFolder = errorFolder;
}
#Override
public void run() {
File file = null;
try {
while ((file = filesQueue.poll(100, TimeUnit.MILLISECONDS)) != null) {
processFile(file);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOGGER.warn("File thread was interrupted");
} catch (IOException e) {
LOGGER.error("Error processing file {} \n{}", file.getAbsolutePath(), e);
}
}
public void processFile(File file) throws IOException {
if (file != null) {
try {
ObjectMapper objectMapper = new ObjectMapper();
List<GiftCertificate> certificates = Arrays.asList(objectMapper.readValue(file, GiftCertificate[].class));
certificateMapper.insertList(certificates);
file.delete();
} catch (JsonParseException | UnrecognizedPropertyException | InvalidFormatException | DataIntegrityViolationException e) {
moveFileToErrorFolder(file);
}
}
}
private void moveFileToErrorFolder(File file) throws IOException {
try {
LOCK.lock();
Files.move(Paths.get(file.getAbsolutePath()), getPathForMovingFile(file), StandardCopyOption.ATOMIC_MOVE);
} finally {
LOCK.unlock();
}
}
private Path getPathForMovingFile(File fileForMove) {
File fileList[] = errorFolder.listFiles();
int filesWithSameNameCounter = 0;
if (fileList != null && fileList.length > 0) {
for (File file : fileList) {
if (file.getName().contains(fileForMove.getName())) {
filesWithSameNameCounter++;
}
}
}
return filesWithSameNameCounter > 0 ?
Paths.get(errorFolder.getAbsolutePath(), "(" + filesWithSameNameCounter + ")" + fileForMove.getName()) :
Paths.get(errorFolder.getAbsolutePath(), fileForMove.getName());
}
}
Aspect
#Aspect
#Component
#ConditionalOnProperty(
value = "file-processing.logging.enabled",
havingValue = "true",
matchIfMissing = true)
public class FileProcessingLoggingAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(FileProcessingLoggingAspect.class);
#Pointcut("execution(* com.epam.esm.processor.FileProcessor.processFile(java.io.File))")
public void processFilePointcut() {
}
#Around("processFilePointcut()")
public Object logFileProcessing(ProceedingJoinPoint joinPoint) throws Throwable {
// File file = (File) joinPoint.getArgs()[0];
// long time = System.currentTimeMillis();
Object object = joinPoint.proceed();
// long resultTime = System.currentTimeMillis() - time;
LOGGER.info("Processing of file took milliseconds");
return object;
}
}
In Spring AOP , internal method calls cannot be intercepted.
In the code shared , even though the method processFile() is public , it gets called from run(). This is a self reference / internal method call , which cannot be intercepted.
Details can be read in the documentation
Due to the proxy-based nature of Spring’s AOP framework, calls within
the target object are, by definition, not intercepted. For JDK
proxies, only public interface method calls on the proxy can be
intercepted
A pointcut expression to intercept all external method calls to a class implementing Runnable would be as follows
#Around("this(java.lang.Runnable) && within(com.epam.esm.processor..*)")
public Object logFileProcessing(ProceedingJoinPoint pjp) throws Throwable {
try {
return pjp.proceed();
} finally {
//log
System.out.println("****Logged");
}
}
Scoping designator within() limits the scope to apply the advice.
The point cut #Pointcut("execution(* com.epam.esm.processor.FileProcessor.processFile(java.io.File))") is valid and would work if an external method call happens to it.
Hope this helps.
I have a class Logger that uses 3 arraysas xhared variables
The arrays are initialized in the contructor
but when accessing them in any other method of the class, I get a
NullPointerException.
I need to know the reason and the solution.
Please see comments in the code.
file Logger.java
package logger_010.standard;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class Logger {
// declaration
private FileOutputStream[] files;
private PrintStream[] pss;
private String[] messages;
public Logger() {
// initialisation
try {
FileOutputStream[] files = {
new FileOutputStream("G:\\Users\\TarekEZZAT\\Documents\\logs\\logger0.log"),
new FileOutputStream("G:\\Users\\TarekEZZAT\\Documents\\logs\\logger1.log"),
new FileOutputStream("G:\\Users\\TarekEZZAT\\Documents\\logs\\logger2.log"),
};
PrintStream[] pss = {
new PrintStream(files[0]),
new PrintStream(files[1]),
new PrintStream(files[2]),
};
String[] messages = {
new String ("Write error message to log file 0"),
new String ("Write error message to log file 1 + user"),
new String ("Write error message to log file 2 + user+ email"),
};
// Arrays instanciation is OK
System.out.println(files[0].toString());
System.out.println(files[1].toString());
System.out.println(files[2].toString());
System.out.println(pss[0].toString());
System.out.println(pss[1].toString());
System.out.println(pss[2].toString());
System.out.println(messages[0].toString());
System.out.println(messages[1].toString());
System.out.println(messages[2].toString());
System.out.println("++++++++++++");
} catch (Exception e) {
System.out.println("Exception " + e.getMessage());
} finally {
}
}
public void LogMessage(int level) {
// Here I get a Null pointer exception
System.out.println(files[0].toString());
System.out.println(files[1].toString());
System.out.println(files[2].toString());
System.out.println(pss[0].toString());
System.out.println(pss[1].toString());
System.out.println(pss[2].toString());
System.out.println(messages[0].toString());
System.out.println(messages[1].toString());
System.out.println(messages[2].toString());
System.out.println("++++++++++++");
// PrintStream[] files = OpenFiles();
WriteLogMessage(this.getPss(), level);
CloseFiles(pss);
}
private void CloseFiles(PrintStream[] pss2) {
// TODO Auto-generated method stub
}
private PrintStream[] OpenFiles() {
// TODO Auto-generated method stub
return null;
}
private void WriteLogMessage(PrintStream[] files, int level) {
this.getPss()[level].println(messages[level]);
this.getPss()[level].flush();
}
public FileOutputStream[] getFiles() {
return files;
}
public void setFiles(FileOutputStream[] files) {
this.files = files;
}
public PrintStream[] getPss() {
return pss;
}
public void setPss(PrintStream[] pss) {
this.pss = pss;
}
public String[] getMessages() {
return messages;
}
public void setMessages(String[] messages) {
this.messages = messages;
}
}
this is the file containing the main function
package logger_010.standard;
public class Start {
public static void main(String[] args) {
// TODO Auto-generated method stub
Logger l = new Logger();
for (int i = 0; i < 15; i++) {
int level = i % 2;
l.LogMessage(level);
}
}
}
You are declare a new files, message, pss variable inside constructor instead of using the variable already created of class => when using in the LogMessage method, it use the variable not init => cause the error
You never actualy bind your class attribut with the object you define in your constructor.
By defining FileOutputStream[] files = ... instead of files = ..., which is your object attribut, you are just making a local variable whose scope is only inside the constructor.
Your constructor should be :
public Logger() {
// initialisation
try {
files = {
new FileOutputStream("G:\\Users\\TarekEZZAT\\Documents\\logs\\logger0.log"),
new FileOutputStream("G:\\Users\\TarekEZZAT\\Documents\\logs\\logger1.log"),
new FileOutputStream("G:\\Users\\TarekEZZAT\\Documents\\logs\\logger2.log"),
};
pss = {
new PrintStream(files[0]),
new PrintStream(files[1]),
new PrintStream(files[2]),
};
messages = {
new String ("Write error message to log file 0"),
new String ("Write error message to log file 1 + user"),
new String ("Write error message to log file 2 + user+ email"),
};
// Arrays instanciation is OK
System.out.println(files[0].toString());
System.out.println(files[1].toString());
System.out.println(files[2].toString());
System.out.println(pss[0].toString());
System.out.println(pss[1].toString());
System.out.println(pss[2].toString());
System.out.println(messages[0].toString());
System.out.println(messages[1].toString());
System.out.println(messages[2].toString());
System.out.println("++++++++++++");
} catch (Exception e) {
System.out.println("Exception " + e.getMessage());
} finally {
}
}
If I initialize the FileOutputStream array with a sub class of FileOutputStream and a constructor that throws a FileNotFoundException I get this compilation error
"Default constructor cannot handle exception type FileNotFoundException thrown by implicit super constructor. Must define an explicit constructor".
I finally solved the problem by using a function (makeFileOutputStream) and this function call the FileOutputStream constructor in a try/catch block
here is the code for my class Blogger
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class Logger {
// declarations
private FileOutputStream[] files = {
makeFileOutputStream("G:\\Users\\TarekEZZAT\\Documents\\logs\\logger0.log"),
makeFileOutputStream("G:\\Users\\TarekEZZAT\\Documents\\logs\\logger1.log"),
makeFileOutputStream("G:\\Users\\TarekEZZAT\\Documents\\logs\\logger2.log"),
};
private PrintStream[] pss = {
new PrintStream(files[0]),
new PrintStream(files[1]),
new PrintStream(files[2]),
};
private String[] messages = {
new String("Write error message to log file 0"),
new String("Write error message to log file 1 + user"),
new String("Write error message to log file 2 + user+ email"),
};
private FileOutputStream makeFileOutputStream(String string) {
// TODO Auto-generated method stub
FileOutputStream fos = null;
try {
fos = new FileOutputStream(string);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fos;
}
public void LogMessage(int level) {
WriteLogMessage(this.getPss(), level);
}
public void CloseFile(PrintStream[] files, int level){
// TODO Auto-generated method stub
this.getPss()[level].close();
}
private void WriteLogMessage(PrintStream[] files, int level) {
this.getPss()[level].println(messages[level]);
this.getPss()[level].flush();
}
// Getters and Setters
public FileOutputStream[] getFiles() {
return files;
}
public void setFiles(FileOutputStream[] files) {
this.files = files;
}
public PrintStream[] getPss() {
return pss;
}
public void setPss(PrintStream[] pss) {
this.pss = pss;
}
public String[] getMessages() {
return messages;
}
public void setMessages(String[] messages) {
this.messages = messages;
}
}
I am writing a JUnit for a method that uses FileInputStream and in the constructor only the file name is passed. The file is created as part of a servlet request and this file is not stored any where.
I am trying to Mock FileInputStream using PowerMockito so that it gives me a mocked file object. Unfortunately I get FileNotFoundException which is valid but I am not sure how to test this method then because the file doesn't exist.
Method under test:
public String viewReport() throws Exception {
this.inputStream = new FileInputStream(DOCUSIGN_REPORT_FILE);
try {
boolean returnReport = validateRequest();
if (returnReport) {
intgList = this.generateViewIntegrationReportData(getESignUIConfig());
this.createCSVFile(intgList, new FileWriter(DOCUSIGN_REPORT_FILE));
} else {
failureResponse(msgs, 400);
return null;
}
} catch (Exception e) {
e.printStackTrace();
msgs.add(new Message(ESignatureIntegrationMessageTypeEnum.MESSAGE_TYPE_ERROR,
UiIntegrationKeyConstants.UI_INTEGRATION_ERROR_CODE_500, UiIntegrationKeyConstants.UI_INTEGRATION_ERROR_TEXT_SERVICE_ERROR));
failureResponse(msgs, 500);
return null;
}
return UiIntegrationKeyConstants.REPORT_REPSONSE;
}
JUnit test so far.
#Test
public void testViewReport() throws Exception {
Map<String, Object> actionMap = new HashMap<>();
actionMap.put("application", "ESignatureIntegrationAction");
ActionContext.setContext(new ActionContext(actionMap));
FileInputStream inputStream = Mockito.mock(FileInputStream.class);
PowerMockito.whenNew(FileInputStream.class).withAnyArguments().thenReturn(inputStream);
action = new ESignatureIntegrationAction();
action.viewReport();
}
I get an exception when the code reaches to new FileInputStream(DOCUSIGN_REPORT_FILE);
Thanks for the help.
I would suggest to refactor your code in a way that allows testing without a mocking framework.
It could look somewhat like this:
public class YourClass {
// ...
public String viewReport() {
try {
boolean isValidRequest = validateRequest();
if (isValidRequest) {
IntegrationReportCsvFileHandler fileHandler = new IntegrationReportCsvFileHandler();
IntegrationReportData inputData = fileHandler.readData(new FileInputStream(DOCUSIGN_REPORT_FILE));
IntegrationReportGenerator generator = new IntegrationReportGenerator();
IntegrationReportData outputData = generator.processData(inputData, getESignUIConfig());
fileHandler.writeReport(outputData, new FileWriter(DOCUSIGN_REPORT_FILE));
} else {
failureResponse(msgs, 400);
return UiIntegrationKeyConstants.FAILURE_RESPONSE;
}
} catch (Exception e) {
e.printStackTrace();
msgs.add(new Message(ESignatureIntegrationMessageTypeEnum.MESSAGE_TYPE_ERROR,
UiIntegrationKeyConstants.UI_INTEGRATION_ERROR_CODE_500, UiIntegrationKeyConstants.UI_INTEGRATION_ERROR_TEXT_SERVICE_ERROR));
failureResponse(msgs, 500);
return UiIntegrationKeyConstants.FAILURE_RESPONSE;
}
return UiIntegrationKeyConstants.REPORT_RESPONSE;
}
// ...
}
public class IntegrationReportData {
// your custom data structure
// may as well just be a List<Data>
// may be different for input and output
}
public class IntegrationReportException extends Exception {
// your custom exception
public IntegrationReportException(String message) { super(exception); }
}
public class IntegrationReportGenerator {
public IntegrationReportData processData(IntegrationReportData data, ESignConfig config) throws IntegrationReportException {
// here's your logic that requires testing
}
}
public class IntegrationReportCsvFileHandler {
public IntegrationReportData readData(InputStream input) throws IOException {
// read data from given input stream
}
public void writeData(IntegrationReportData data, OutputStreamWriter outputWriter) throws IOException {
// write data to given output stream
}
}
That way the IntegrationReportGenerator would be easily testable.
I'm newly with Guice.
I want to use Guice for initializing object without writing new directly.
Here is my main():
public class VelocityParserTest {
public static void main(String[] args) throws IOException {
try {
PoenaRequestService poenaService = new PoenaRequestService();
System.out.println(poenaService.sendRequest("kbkCode"));
} catch (PoenaServiceException e) {
e.printStackTrace();
}
}
}
PoenaRequestService:
public class PoenaRequestService {
private static final String TEMPLATE_PATH = "resources/xml_messages/bp12/message01.xml";
public static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PoenaRequestService.class);
#Inject
#Named("poena_service")
private HttpService poenaService;
public String sendRequest(/*TaxPayer taxPayer,*/ String kbk) throws PoenaServiceException {
LOG.info(String.format("Generating poena message request for string: %s", kbk));
Map<String, String> replaceValues = new HashMap<>();
replaceValues.put("guid", "guid");
replaceValues.put("iinbin", "iinbin");
replaceValues.put("rnn", "rnn");
replaceValues.put("taxOrgCode", "taxOrgCode");
replaceValues.put("kbk", "kbk");
replaceValues.put("dateMessage", "dateMessage");
replaceValues.put("applyDate", "applyDate");
ServiceResponseMessage result;
try {
String template = IOUtils.readFileIntoString(TEMPLATE_PATH);
Document rq = XmlUtil.parseDocument(StringUtils.replaceValues(template, replaceValues));
result = poenaService.execute(HttpMethod.POST, null, rq);
} catch (IOException e) {
throw new PoenaServiceException("Unable to read template file: " + TEMPLATE_PATH, e);
} catch (SAXException e) {
throw new PoenaServiceException("Unable to parse result document, please check template file: " + TEMPLATE_PATH, e);
} catch (HttpServiceException e) {
throw new PoenaServiceException(e);
}
if (result.isSuccess()) {
return (String) result.getResult();
}
throw new PoenaServiceException("HTTP service error code '" + result.getStatusCode() + "', message: " + result.getStatusMessage());
}
}
When I tried to debug this I see next picture:
As e result I got NullPointerException.
I couldn't figure out this behavior. Why does this exactly happen?
Any suggestions?
It's not working because you're not actually using Guice. You need to create an injector and bind your dependencies to something. Something akin to this:
public class VelocityParserTest {
public static void main(String[] args) throws IOException {
Injector injector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
bind(PoenaRequestService.class).asEagerSingleton();
bind(HttpService.class)
.annotatedWith(Names.named("poena_service"))
.toInstance(...);
}
});
try {
PoenaRequestService poenaService = injector.getInstance(PoenaRequestService.class);
System.out.println(poenaService.sendRequest("kbkCode"));
} catch (PoenaServiceException e) {
e.printStackTrace();
}
}
}