Я долгое время читатель, но первый писатель.Ошибка Java PrintWriter
В настоящее время я пытаюсь внедрить регистратор с AspectJ в нашей кодовой базе. AspectJ, похоже, работает хорошо, но я встречаю чрезвычайно странные ошибки Java. Я давний разработчик C++ и .NET, который все еще адаптируется к миру Java, поэтому я извиняюсь, если это глупый вопрос.
Мой код пытается уловить исключения и зарегистрировать соответствующую информацию в текстовом файле. Улавливание работает отлично, но я заметил, что когда я развернусь, я не получаю никаких данных. Я открыл файл класса в декомпиляторе Java и заметил, что PrintWriter, похоже, генерирует ошибку. Я никогда не видел такой проблемы, поэтому я надеюсь, что у вас может быть какое-то понимание.
package mil.uscg.c3cen.vic.aspect;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.JoinPoint;
@Aspect
public class LoggingAspect
{
private final String LOG_FILE = "aspectLog.txt";
private final File file = new File(LOG_FILE);
private LoggingAspect()
{
}
private void logException(String msg)
{
try
{
if(!file.exists())
file.createNewFile();
}
catch(IOException e)
{
}
try (FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw))
{
pw.println(msg);
}
catch(IOException e)
{
}
}
private String getSimpleFunctionInfo(String className, String function, Object[] args)
{
StringBuilder builder = new StringBuilder();
builder.append(". Method: ");
builder.append(className);
builder.append(".");
builder.append(function);
if(args.length == 0)
{
builder.append("()");
return builder.toString();
}
builder.append("(");
for(Object o : args)
{
builder.append(o.toString());
builder.append(",");
}
// Replace the comma for the last param with a closing parenthesis
int len = builder.length();
builder.replace(len -1, len, ")");
return builder.toString();
}
// Returns a formatted exception. "Exception.ErrorMessage"
private String getSimpleExceptionInfo(String name, String msg)
{
StringBuilder builder = new StringBuilder();
builder.append("Exception caught: ");
builder.append(name);
builder.append(". Message: ");
builder.append(msg);
return builder.toString();
}
@AfterThrowing(pointcut = "execution(* mil.uscg.c3cen.*.*.*(..)) "
//+ "&& !within(mil.uscg.c3cen.vic.aspect.*) "
, throwing = "excep")
public void afterThrowing(JoinPoint jp, Throwable excep) throws Throwable
{
String ex = getSimpleExceptionInfo(excep.getClass().getSimpleName(),
excep.getMessage());
String name = getSimpleFunctionInfo(jp.getSignature().getDeclaringType().getSimpleName(),
jp.getSignature().getName(),
jp.getArgs());
StringBuilder builder = new StringBuilder();
builder.append(ex);
builder.append(name);
logException(builder.toString());
}
}
Все выглядит так, как вы ожидали бы в файле класса, за исключением функции logException.
/* Error */
private void logException(String msg)
{
// Byte code:
// 0: aload_0
// 1: getfield 25 mil/uscg/c3cen/vic/aspect/LoggingAspect:file Ljava/io/File;
// 4: invokevirtual 32 java/io/File:exists()Z
// 7: ifne +15 -> 22
// 10: aload_0
// 11: getfield 25 mil/uscg/c3cen/vic/aspect/LoggingAspect:file Ljava/io/File;
// 14: invokevirtual 36 java/io/File:createNewFile ()Z
// 17: pop
// 18: goto +4 -> 22
// 21: pop
// 22: aconst_null
// 23: astore_2
// 24: aconst_null
// 25: astore_3
// 26: new 39 java/io/FileWriter
// 29: dup
// 30: aload_0
// 31: getfield 25 mil/uscg/c3cen/vic/aspect/LoggingAspect:file Ljava/io/File;
// 34: invokespecial 41 java/io/FileWriter:<init> (Ljava/io/File;)V
// 37: astore 4
// 39: new 44 java/io/BufferedWriter
// 42: dup
// 43: aload 4
// 45: invokespecial 46 java/io/BufferedWriter:<init> (Ljava/io/Writer;)V
// 48: astore 5
// 50: new 49 java/io/PrintWriter
// 53: dup
// 54: aload 5
// 56: invokespecial 51 java/io/PrintWriter:<init> (Ljava/io/Writer;)V
// 59: astore 6
// 61: aload 6
// 63: aload_1
// 64: invokevirtual 52 java/io/PrintWriter:println (Ljava/lang/String;)V
// 67: aload 6
// 69: ifnull +24 -> 93
// 72: aload 6
// 74: invokevirtual 55 java/io/PrintWriter:close ()V
// 77: goto +16 -> 93
// 80: astore_2
// 81: aload 6
// 83: ifnull +8 -> 91
// 86: aload 6
// 88: invokevirtual 55 java/io/PrintWriter:close ()V
// 91: aload_2
// 92: athrow
// 93: aload 5
// 95: ifnull +43 -> 138
// 98: aload 5
// 100: invokevirtual 58 java/io/BufferedWriter:close ()V
// 103: goto +35 -> 138
// 106: astore_3
// 107: aload_2
// 108: ifnonnull +8 -> 116
// 111: aload_3
// 112: astore_2
// 113: goto +13 -> 126
// 116: aload_2
// 117: aload_3
// 118: if_acmpeq +8 -> 126
// 121: aload_2
// 122: aload_3
// 123: invokevirtual 59 java/lang/Throwable:addSuppressed (Ljava/lang/Throwable;)V
// 126: aload 5
// 128: ifnull +8 -> 136
// 131: aload 5
// 133: invokevirtual 58 java/io/BufferedWriter:close ()V
// 136: aload_2
// 137: athrow
// 138: aload 4
// 140: ifnull +66 -> 206
// 143: aload 4
// 145: invokevirtual 65 java/io/FileWriter:close ()V
// 148: goto +58 -> 206
// 151: astore_3
// 152: aload_2
// 153: ifnonnull +8 -> 161
// 156: aload_3
// 157: astore_2
// 158: goto +13 -> 171
// 161: aload_2
// 162: aload_3
// 163: if_acmpeq +8 -> 171
// 166: aload_2
// 167: aload_3
// 168: invokevirtual 59 java/lang/Throwable:addSuppressed (Ljava/lang/Throwable;)V
// 171: aload 4
// 173: ifnull +8 -> 181
// 176: aload 4
// 178: invokevirtual 65 java/io/FileWriter:close ()V
// 181: aload_2
// 182: athrow
// 183: astore_3
// 184: aload_2
// 185: ifnonnull +8 -> 193
// 188: aload_3
// 189: astore_2
// 190: goto +13 -> 203
// 193: aload_2
// 194: aload_3
// 195: if_acmpeq +8 -> 203
// 198: aload_2
// 199: aload_3
// 200: invokevirtual 59 java/lang/Throwable:addSuppressed (Ljava/lang/Throwable;)V
// 203: aload_2
// 204: athrow
// 205: pop
// 206: return
// Line number table:
// Java source line #28 -> byte code offset #0
// Java source line #29 -> byte code offset #10
// Java source line #30 -> byte code offset #18
// Java source line #31 -> byte code offset #21
// Java source line #36 -> byte code offset #22
// Java source line #36 -> byte code offset #26
// Java source line #37 -> byte code offset #39
// Java source line #38 -> byte code offset #50
// Java source line #40 -> byte code offset #61
// Java source line #41 -> byte code offset #67
// Java source line #42 -> byte code offset #205
// Java source line #46 -> byte code offset #206
// Local variable table:
// start length slot name signature
// 0 207 0 this LoggingAspect
// 0 207 1 msg String
// 23 1 2 localObject1 Object
// 80 28 2 localObject2 Object
// 112 92 2 localObject3 Object
// 25 1 3 localObject4 Object
// 106 17 3 localThrowable1 Throwable
// 151 17 3 localThrowable2 Throwable
// 183 17 3 localThrowable3 Throwable
// 37 140 4 fw java.io.FileWriter
// 48 84 5 bw java.io.BufferedWriter
// 59 28 6 pw java.io.PrintWriter
// 21 1 12 localIOException1 java.io.IOException
// 205 1 13 localIOException2 java.io.IOException
// Exception table:
// from to target type
// 0 18 21 java/io/IOException
// 61 67 80 finally
// 50 93 106 finally
// 39 138 151 finally
// 26 183 183 finally
// 22 205 205 java/io/IOException
}
Это действительно сильно меня озадачило, поэтому любая информация будет чрезвычайно оценена. Благодаря!
Я подумал, что было правильный синтаксис для использования автоматизированного управления ресурсами в Java. Я понял, что это эквивалент использования функции на C#, где ресурсы гарантируются для закрытия, как это обычно делается в блоке finally. – FretlessMayhem
@CalvinP. Эти строки находятся в круглых скобках, потому что они используют оператор try-with-resources. Пожалуйста, посмотрите здесь, чтобы раскрыть его код, если вы не знаете, что это значит [link] (https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) – angryip
Ах, только что увидел javadocs, и вы правы. Оператор try должен быть успешным, если вы используете Java SE 7 или новее. @angryip буквально просто посмотрел, что до того, как вы предоставили ссылку, но спасибо. –