YunaiV/ruoyi-vue-pro · critical · RuntimeException

AreaUtils 初始化失败

Error message

AreaUtils 初始化失败

What it means

AreaUtils is a static initializer that parses a CSV of Chinese administrative areas (area.csv), builds parent/child relationships, and fails fast with RuntimeException('AreaUtils 初始化失败') on any parse/assertion/IO error. The assert area != parent and parent null-deref are the most common sub-failures.

Source

Thrown at yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java:67

            // 从 csv 中加载数据
            List<CsvRow> rows = CsvUtil.getReader().read(ResourceUtil.getUtf8Reader("area.csv")).getRows();
            rows.remove(0); // 删除 header
            for (CsvRow row : rows) {
                Area area = new Area(Integer.valueOf(row.get(0)), row.get(1), Integer.valueOf(row.get(2)), null, new ArrayList<>());
                areas.put(area.getId(), area);
            }

            // 构建父子关系:因为 Area 中没有 parentId 字段,所以需要重复读取
            for (CsvRow row : rows) {
                Area area = areas.get(Integer.valueOf(row.get(0))); // 自己
                Area parent = areas.get(Integer.valueOf(row.get(3))); // 父
                Assert.isTrue(area != parent, "{}:父子节点相同", area.getName());
                area.setParent(parent);
                parent.getChildren().add(area);
            }
            log.info("启动加载 AreaUtils 成功,耗时 ({}) 毫秒", System.currentTimeMillis() - now);
        } catch (Exception e) {
            throw new RuntimeException("AreaUtils 初始化失败", e);
        }
    }

    /**
     * 获得指定编号对应的区域
     *
     * @param id 区域编号
     * @return 区域
     */
    public static Area getArea(Integer id) {
        return areas.get(id);
    }

    /**
     * 获得指定区域对应的编号
     *
     * @param pathStr 区域路径,例如说:河南省/石家庄市/新华区
     * @return 区域

View on GitHub (pinned to 0418084e22)

Solutions

  1. Inspect the caused-by exception: IOException -> missing/malformed resource; IllegalArgumentException -> assert area!=parent or duplicate id.
  2. Ensure area.csv is on the classpath (check the packaged jar).
  3. Fix the offending CSV row (ensure parentId differs from id and exists in the map).

Example fix

// before: row where id == parentId triggers Assert
// area.csv: 110000,北京市, ..., 110000
// after: set parent to the real parent id
// area.csv: 110000,北京市, ..., 100000
Defensive patterns

Strategy: try-catch

Validate before calling

if (getClass().getClassLoader().getResource("area.csv") == null)
    throw new IllegalStateException("area.csv missing from classpath");

Type guard

null

Try / catch

try { AreaUtils.getArea(id); }
catch (RuntimeException e) { if (e.getMessage().contains("AreaUtils")) { /* disable area features */ } throw e; }

Prevention

When it happens

Trigger: The bundled area.csv is missing from the classpath (shaded jar stripped it); a malformed CSV row (non-numeric id, missing parent column, a row whose id equals its parentId); duplicate ids; ResourceUtil.readFileAsString returns null.

Common situations: Building a fat/shaded jar that excludes the csv resource; upgrading the data-permission/ip module with a CSV format change; custom CSV with malformed rows.

Related errors


AI-assisted analysis of YunaiV/ruoyi-vue-pro@0418084e22 (2026-08-14). Data as JSON: /api/errors/97bc1e02f6905a12. Report an issue: GitHub.