maven项目编译漏掉src/main/java下的xml配置文件

本文介绍Spring与MyBatis框架整合过程中遇到的问题及解决方案,包括配置自动扫描、数据源设置、事务管理等内容,并解决了mapper接口绑定失败的错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在整合Spring + Mybatis框架的时候,自动扫描配置都已经配置好了。
配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
                        http://www.springframework.org/schema/context  
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd  
                        http://www.springframework.org/schema/mvc  
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <!-- 自动扫描 -->
    <context:component-scan base-package="com.aheizi" />
    <!-- 引入配置文件 -->
    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:properties/jdbc.properties" />
    </bean>
 
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="${initialSize}"></property>
        <!-- 连接池最大数量 -->
        <property name="maxActive" value="${maxActive}"></property>
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="${maxIdle}"></property>
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="${minIdle}"></property>
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="${maxWait}"></property>
    </bean>
 
    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 自动扫描mapping.xml文件 -->
        <property name="mapperLocations" value="classpath*:com/aheizi/mapping/*.xml"></property>
        <property name="typeAliasesPackage" value="com.aheizi.domain" />
    </bean>
    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.aheizi.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>
    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
</beans>

但是在install的时候报了如下错误:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.aheizi.dao.UserMapper.selectByUserId
    at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:184)
    at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:38)
    at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:49)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:42)
    at com.sun.proxy.$Proxy11.selectByUserId(Unknown Source)
    at com.aheizi.service.impl.UserServiceImpl.getUserById(UserServiceImpl.java:20)
    at com.aheizi.testmybatis.TestSpringDemo.test1(TestSpringDemo.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

显示绑定错误,分析可知应该是在UserMapper接口和SQL的隐射文件没有结合。
第一时间检查了mapper的namespace属性,确认没有错。
后来查看了target/classes/../mapping并不存在,也就是说mapper.xml文件并没有在编译的时候放进classes中。
那么接口当然绑定不了selectByUserId这个方法。
查资料得知,有两个解决办法:
1.在pom.xml中添加如下代码:

           <resources>  
            <!-- 编译之后包含xml   -->
            <resource>  
              <directory>src/main/java</directory>  
              <includes>  
                <include>**/*.xml</include>  
              </includes>  
              <filtering>true</filtering>  
            </resource>  
          </resources>  

2.将mapper.xml映射文件放到resources文件夹下。
文件目录如下:

运行就不会报错了,但是我看着还是有点别扭,就是看着不爽,等以后想到好办法之后再换吧。

我就纳了个闷了,maven这样限制xml文件的位置,即没让我觉得美观,也没有感到实用。


<think>好的,我现在需要解决用户在使用Maven打包时遇到的错误:“Error creating assembly archive win: archive cannot be empty”。首先,我需要理解这个错误的原因。根据经验,Maven Assembly插件在创建归档文件时,如果发现指定的文件或目录不存在或为空,就会抛出这个错误。用户可能在assembly配置文件中引用了不存在的文件或目录,或者构建过程中某些预期的输出文件没有被正确生成。 接下来,我需要回忆Maven Assembly插件的基本使用方式。通常,用户会在pom.xml中配置assembly插件,并指定一个描述符文件(通常是src/main/assembly/下的某个xml文件)。这个描述符定义了打包时要包含哪些文件和目录。如果配置错误,比如路径写错了,或者依赖项没有正确生成,就会导致最终要打包的内容为空。 然后,我应该检查可能的解决方案。首先,验证assembly描述符文件中的内容是否正确,特别是<fileSets>或<dependencySets>部分。例如,是否指定了正确的目录,比如${project.build.directory},这通常是target目录,里面应该有编译后的文件。如果用户的项目没有生成预期的jar文件,或者编译失败,也可能导致目录为空。 另外,检查Maven的生命周期阶段是否正确。比如,运行mvn clean package时,是否先执行了编译(compile)阶段,确保target目录中有内容。如果用户跳过了编译步骤,直接运行assembly:single,可能导致文件缺失。 还要考虑项目结构是否符合Maven标准。如果用户自定义了输出目录,而assembly插件仍然引用默认的target目录,那么就会找不到文件。需要确认路径配置是否一致。 此外,查看是否有依赖项未被正确包含。比如,如果使用了<dependencySet>但没有正确指定作用域(scope),可能漏掉某些必要的依赖。或者项目是多模块的,子模块的构建顺序或配置影响了主项目的打包。 最后,可能需要检查日志输出,确认在运行mvn命令时是否有其他错误或警告,比如编译错误导致没有生成class文件,进而导致打包时目录为空。用户需要运行mvn clean install并观察整个构建过程是否有问题,确保所有前置步骤都成功完成。 总结下来,解决步骤应该是:检查assembly描述符配置、确认构建输出目录有内容、验证项目结构和依赖设置、检查构建日志是否有其他错误。同时,参考引用中的Maven相关信息[^2],确保项目遵循POM标准,正确使用插件配置。</think>### 解决Maven Assembly插件报错"archive cannot be empty"的方法 #### 1. 检查Assembly描述符配置 在`src/main/assembly/`目录下的XML描述符文件中,确认`<fileSets>`或`<dependencySets>`配置引用了有效路径: ```xml <fileSet> <directory>${project.build.directory}</directory> <includes> <include>*.jar</include> </includes> </fileSet> ``` 如果`${project.build.directory}`(即`target/`目录)为空,说明编译产物未生成,需要先执行`mvn compile`。 #### 2. 验证文件生成路径 确保项目符合Maven标准结构: ``` src/ main/ java/ test/ java/ pom.xml ``` 通过以下命令强制清理并重新构建: ```bash mvn clean package ``` #### 3. 检查依赖项配置 如果使用`<dependencySets>`,需要显式包含依赖: ```xml <dependencySet> <useProjectArtifact>true</useProjectArtifact> <scope>runtime</scope> </dependencySet> ``` #### 4. 调试构建过程 添加调试参数查看详细错误: ```bash mvn -X clean package assembly:single ``` #### 5. 验证插件版本 在`pom.xml`中指定稳定版本: ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.6.0</version> </plugin> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值