java - 仅具有通用 "fix"的 Java 代码库的自动化 `catch (Exception e)`

标签 java exception automated-refactoring

我有一个很大的代码库,里面有很多很多

try {
   // attempt to do something important
} catch (Exception e) {
   // do something lame
}

反模式。大约 700 个实例。我想知道是否有一种工具(例如,IDE 或其他东西)可以神奇地大规模地用下一层的专用 catch block 替换所有这些东西。类似于 IntelliJ 或 Eclipse 的 "wrap with try/catch" 应用大规模重构的东西以如下所示的方式。注意:我并不是说所有 700 个都是已知的 IOException;这只是一个示例,假设在特定情况下抛出的唯一异常类型是 IOException)。

我正在寻求的重构是对 try{} block 进行相同的语义分析,IntelliJ/Eclipse 为提供“wrap with catch”或“add to throws clause”所做的语义分析快速修复:

try {
   // attempt to do something important
   // where an IOException is thrown
} catch (IOException e) {
   // still do something lame
}

我知道这并不能“解决”问题,但它可以节省一些逐步的手动考古工作。

想法?

关于detecting general exception catch antipattern的相关问题.

最佳答案

鉴于问题是:

查找以下形式的所有 block :

 try { ... }
 catch (Exception e) { ... }

 try { ... }
 catch ( T1 e ) { ... }
 ....
 catch ( Tn e ) { ... }

对于所有 T1,... Tn e,一个可以进行代码更改并推断抛出的异常的程序转换系统似乎是一种解决方案。

我们的 DMS Software Reengineering Toolkit与其 Java Front End可能会这样做。

您需要一个分析器来计算从主 block 内部抛出的异常集。您可能也想根据对象层次结构对这些异常进行分类;如果 Tm 是 Tn 的特化,您可能希望为 Tm 和 Tn 生成处理程序作为嵌套尝试。 DMS 具有完整的类型分析,因此它可以确定代码中的类型,并由代码块抛出。必须编写自定义 DMS 代码来计算异常的对象层次结构。

您需要一个调用图,以便可以将调用图中发现的异常传播到 try 站点。我们有,但它需要为 Java 1.7 做一些工作。

您需要一个转换应用程序来修改代码。我认为您需要担心链式捕获来处理一般情况。使用 DMS,它应该看起来像:

rule specialize_catch(b_try: block,
      E: qualifed_identifer, e: IDENTIFIER, b_recover: block,
      c_pre: catches, c_post: catches):
   statement -> statement
 " try { \b_try } 
   \c_pre
   catch ( \E \e ) { \b_recover }
   \c_post "
 -> 
  " try { \b_try }
    \c_pre 
    catch ( \least_specialized\(\E\,\b_try\,\c_pre\) \e ) { \b_recover }
    catch ( \E e ) { \b_recover }
    \c_post "
    if exists_specialized_exception(E,b_try,c_pre);

要转换的语法是 *meta*quotes "..."中的代码,以将其与重写规则的语法分开。重写规则有许多部分。它指定一个名称(我们通常有数百个)。它提供了一组命名占位符(b_try、E、b_recover、...),代表目标语言(在本例中为 Java)中的特定命名句法形式,并以元引号和转义(反斜杠)形式之外的裸形式编写在元引号内。 c_pre 是一系列 catch 结构的名称;我们可以这样做是因为“catches”在抽象中形成了一个关联列表,对于 c_post 也是如此。它提供元函数调用(例如,least_specialized、exists_specialized_exception),可以调用自定义 DMS 机制来计算结果( boolean 值或新语法 [树])。您会注意到对 least_specialized 的元函数调用甚至对元函数调用的语法进行了转义(例如,逗号和圆括号),因为它们不是 Java 语言的一部分;在 Java 代码之外,这样的元函数调用不需要转义。最重要的是,它有左侧(“匹配此”,绑定(bind)元变量)和右侧(如果规则条件为真,则“用此替换”。

元函数 least_specialized 和 exists_specialized 将计算主代码块 b_try 可能抛出的异常,以及由现有捕获 c_pre 处理的异常,以及当前异常类型 E,c_pre 之上和 E 之下的最普遍异常,以及插入一个新的 catch block 。如果不存在,则 if 失败并且不再进行异常插入。您可能需要额外的转换来反克隆复制的 b_recover block 。

我显然还没有实现这个,也可能没有完全考虑清楚。但我可以将此视为可能解决方案的途径。 YMMV.

我会说 700 个实例,使用 DMS 执行此操作可能非常微不足道。如果您个人每人花费 10 分钟(编辑、编译、糟糕...),那就是 7000 分钟或 ~~ 100 小时,大约 2 周。我怀疑您是否可以配置 DMS 来如此快速地执行此操作,尤其是以前从未这样做过。 (我公司有专业的 DMS 用户,这可能是一个可行的时间范围)。

但声称可能确实存在一种工具。

关于java - 仅具有通用 "fix"的 Java 代码库的自动化 `catch (Exception e)`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9915013/

相关文章:

java - 仅当 Mustache Java 中的 Map 中存在值时才打印列表

java - IntelliJ JBoss 插件 - 如何在 Debug模式下启动

java - KafkaAvroDeserializer-NoClassDefFoundError : io/confluent/common/config/ConfigException

java - 在 Eclipse 中重构或重命名类导入

typescript - 以编程方式应用 Typescript 重构

java - 获取节点原始文本

Java:如何输出所有可能的二进制组合(256个不同的序列)?

java - 抛出异常会改变它的状态吗?

java - 在 Play Framework 2 上进行单元测试时出现错误

python - PyCharm:这种自动签名重构可能吗?