启动Tomcat时遇到的 java.lang.IllegalArgumentException: Can't convert argument: null 异常

本文解决在Eclipse中重构JEE项目名导致的Tomcat启动异常问题,通过修改web.xml文件中的命名空间来解决。
Eclipse中工程重命名后,启动tomcat,出现异常:
Sep 8, 2011 1:41:52 PM org.apache.catalina.startup.ContextConfig parseWebXml
SEVERE: Parse error in application web.xml file at jndi:/localhost/gzpetro-portal/WEB-INF/web.xml
java.lang.IllegalArgumentException: Can't convert argument: null
at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:2687)
at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:2713)
at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:1060)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1543)


上述问题,是由于在Eclipse下重构JEE项目名时,Eclipse自动更新了部署文件web.xml,重新生成了xml文件的头部声明,新增加了javaee的命名空间。

<init-param>  
<javaee:param-name>debug</javaee:param-name>
<javaee:param-value>true</javaee:param-value>
</init-param>


将前面的javaee:去掉即可。
<think> 我们正在处理一个Java异常java.lang.IllegalArgumentException: can't parse argument number。 根据引用[1]和[3][4]的信息,这个错误通常发生在使用MessageFormat.format方法,格式字符串中包含了大括号{},而大括号在MessageFormat中用于表示参数占位符(如{0},{1}),如果格式字符串中需要显示大括号,必须进行转义。 引用[3]和[4]给出了解决方案:使用单引号(')来转义大括号。例如,如果要在字符串中显示大括号,应该写成'{'和'}',或者将整个不需要解析的部分用单引号括起来。 参考错误信息:姓名:{0},这里可能是想显示一个字符串"姓名:{0}",但是MessageFormat尝试解析{0}作为参数占位符,而实际提供的参数不够(这里只提供了一个参数,但占位符需要至少一个参数),或者格式不正确。 根据引用[2],IllegalArgumentException通常是因为传递了非法参数,这里具体指格式字符串中的占位符与参数不匹配,或者占位符本身格式错误(比如包含了无法解析的占位符)。 解决方案: 1. 转义大括号:在格式字符串中,将普通的大括号用单引号转义。例如: 原字符串: "姓名:{0}" 如果我们要原样显示大括号和其中的内容,而不是作为占位符,那么就需要转义。但是注意,这里{0}是占位符,如果我们要显示为"{0}",则应该写成:'{'0'}' 然而,实际上我们通常只需要转义左大括号,并且可以用一对单引号将需要原样输出的部分括起来。 例如: "姓名:'{'0'}'" -> 输出:姓名:{0} 或者更简单的:使用两个单引号来表示一个单引号,但这里我们主要是转义大括号。 引用[3]的例子: 原格式字符串:"The username cannot contain any of these characters: ()'{'}" 这里用单引号转义了左大括号,右大括号同理。 2. 检查占位符:确保占位符的编号从0开始连续,并且提供的参数数量与占位符数量一致。 根据引用[1]的报错信息,在Test.java的第10行使用了MessageFormat.format,格式字符串为"姓名:{0}",但是可能传递的参数数量不足(或者参数传递错误)。 具体步骤: - 查看代码中调用MessageFormat.format的地方,检查格式字符串中是否包含大括号,并且这些大括号是否被正确转义(如果不需要作为占位符)。 - 确保格式字符串中的占位符(如{0})的编号是连续的,并且从0开始,且提供的参数个数与占位符个数一致。 示例代码修正: 错误代码(如引用[1]所示): MessageFormat.format("姓名:{0}", ...); // 这里如果第二个参数没有提供,或者提供的是null,就会出错。 修正1:如果确实需要显示{0},而不是作为占位符,则转义: MessageFormat.format("姓名:'{'0'}'", null); // 这样就会输出:姓名:{0} 修正2:如果{0}确实是占位符,那么需要提供相应的参数: MessageFormat.format("姓名:{0}", "张三"); // 这样就会输出:姓名:张三 总结:根据实际需求决定是转义大括号还是提供正确的参数。 另外,引用[2]还提供了更通用的解决IllegalArgumentException的方法:代码审查、验证输入、使用断言。但针对这个具体的错误,主要是格式字符串的问题。 因此,解决步骤: 1. 定位到抛出异常的代码行(如Test.java的第10行)。 2. 检查该行MessageFormat.format的格式字符串,看大括号是否需要转义。 3. 检查参数个数是否匹配。 下面我们生成相关问题: </think> ### 解决 `java.lang.IllegalArgumentException: can't parse argument number` 的方法 该错误通常由 **`MessageFormat` 格式字符串中的大括号 `{}` 未正确转义**引起。以下是具体解决步骤: #### 1. **根本原因分析** - Java 的 `MessageFormat` 使用大括号 `{}` 作为参数占位符(如 `{0}` 表示第一个参数)。 - 若格式字符串中包含**普通大括号**(非占位符),需用单引号 `'` 转义,否则会触发解析错误[^1][^3][^4]。 - **示例错误代码**: ```java // 未转义大括号,导致报错 String msg = MessageFormat.format("错误信息: {错误代码}", null); ``` #### 2. **解决方法** **👉 方案:转义特殊字符** 用单引号 `'` 包裹需原样输出的大括号: ```java // 正确写法:用单引号转义大括号 String safeMsg = MessageFormat.format( "The username cannot contain any of these characters: ()'{'}'", // 转义 { null ); ``` - **效果**:输出 `The username cannot contain any of these characters: (){}`[^3][^4]。 - **关键规则**: - `'{'` → 转义左大括号 - `'}'` → 转义右大括号 - `''` → 表示单引号本身(如 `It''s OK`) #### 3. **预防措施** - **输入验证**:检查传入 `MessageFormat.format()` 的字符串是否包含未转义的 `{` 或 `}`[^2]。 - **占位符检查**:确保占位符索引连续(如 `{0}`, `{1}`),避免 `{1x}` 等非法格式[^1]。 - **单元测试**:覆盖特殊字符场景,例如: ```java @Test void testFormatWithSpecialChars() { String result = MessageFormat.format("{{ 转义示例: '{'0'}' }}", "test"); assertEquals("{ 转义示例: {0} }", result); } ``` #### 4. **错误排查流程** ```mermaid graph TD A[报错 can't parse argument number] --> B[定位调用MessageFormat.format的代码行] B --> C[检查格式字符串中的{ }] C --> D{是否存在未转义的大括号?} D -- 是 --> E[用单引号转义大括号] D -- 否 --> F[检查占位符索引是否连续] F --> G[修正占位符索引] ``` ### 相关问题 1. MessageFormat 中如何处理单引号嵌套(如 `It's fine`)? 2. 除了大括号,MessageFormat 还有哪些需要转义的特殊字符? 3. 如何动态生成带占位符的国际化消息(i18n)并避免此错误? 4. 其他常见的 `IllegalArgumentException` 场景有哪些(如负数参数、空集合操作)?[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值