Java EE7和Maven工程入门(1)

简介:

目录

  1. 一个简单Maven工程的结构

为什么?

在日常工作中,我经常需要解决许多简单的或者是复杂的Maven/Java EE工程结构的问题。为了找到解决办法,我经常要拿项目的结构做实验,在不同应用服务器上对部署进行测试并且调优。

对新手来说,Maven可能有一个很漫长的学习曲线。如果你参与进一个经常需要非常复杂的配置的现代化的JavaEE应用的时候,事情会变得更糟。在我的职业生涯中也曾见过:很多初级程序员,当他们参与到一个大的团队或者项目,很多时候,工程的结构已经被一些更高级的程序员调优和配置好了。他们会认为这是没问题的,并且也不会花时间来理解这些配置和结构。过去我也犯过这样的错误。他们被给予简单的编码任务,然后就一头扎进需求里面去了。很不幸,他们忽略了应用结构的学习。更高级的同僚们大多数时候因为时间限制也忘了在这个领域对他们进行培训。这会导致一些事故,因为之前没有经验,想让应用跑起来的时候,会把应用结构弄的一团糟。Maven和它的约定的目的是帮助构建通用的结构,然后对项目的结构应该是什么样子做了约定。但同样的,你需要理解这个工具和约定,然后才可以掌握你的配置。

经常会听到有人说“我在那里添加了一个lib,可以正常工作”。如果你回答“那里是什么意思?”,很可能会得到许多有意思的回复。碰巧或者是运气好的时候,应用确实能运行。但是,在一个复杂的多模块的应用里面,大多数时候,能运行说明不了什么——问题很快就会出现。

本系列的文章主要是针对Maven和JavaEE新手。如果你是一名高级程序员,欢迎分享或者把它当作一个示例。

我准备拿一个在我的日常工作中发现的有很多实际问题的例子开刀,尝试给出基本的解释或者是给出相关资源的连接。欢迎以一种干净的方式给出可操作或者可实现的建议、纠正或者是引用。学习Maven并且创建一个复杂但是却容易维护的应用,最好的方式是白手起家,从一个空的pom文件开始。

我想要向读者传达的主要意思是,*学习你的应用的结构,底层的构建工具也是你工作的一部分,永远不要假设总会有人会来处理。为了挑战更难的任务和改善作为Java开发者的技能,这也是很重要的一步。

用到的主要技术

  • 基于JavaEE7的应用
  • 应用会被打成WAR包
  • 应用由很多组件组成(wars、jars、ejbjars)
  • 用Java7进行编译
  • 用Maven3进行打包

我的示例ear应用

作为本文示例,我的应用最终会会是一个EAR包。里面包含2个顶级的模块,一个war包和一个ejb-jar。此外还包含了数据库领域模型(JPA实体)类的jar。后面的文章中我会扩展这个结构,增加更多的资源。

下面的一个抽象的图片展示了我们的ear包将包含哪些东西。将来,war模块会包含servlet或者是jsf组件。services模块会包含许多常用的无状态的会话Bean(或是消息驱动Bean)。domain工程会有普通的用JPA2注解标注的Java类。

用Maven构造我们应用的基本结构

为了构建上面说的ear,我们需要使用Maven定义模块和应用的组成部分,它是我们的构建、打包、配置工具。这只是众多步骤中的一步,但是如果你一开始就搞明白了,接下来就是一些简单的技术或配置。这里不是最终的解决方案,而是很多时候当你开始一个新的应用时,如何找到接近标准的问题解决方式。因此,这里没有华而不实的东西,让我们遵守标准,开始构建一个坚实的基础吧。

首先让我们忘掉上面的那幅图,然后想一下:在Maven中模块是什么,他们是如何进行定义的,怎么把他们联系起来,如何定义他们之间的依赖关系。注意:我提倡的工作方式是遵守标准,而不是最终的解决方案。也就是说,你可以定义更少的模块和依赖,然后把你的应用打包成ear。假设我要覆盖非常复杂的结构,所以我总是会遵守标准,定义一个通用的结构。

假设你已经了解了Maven的一些基本改变,至少你应该熟悉一些术语。如果不是的话,请先看这里

请记住,Maven是关于:根据定义良好的结构把你的文件放到正确的位置。定义Maven插件,插件是用来做诸如编译、打包、复制文件这样工作的工具。Maven内置了很多插件。所以,你需要用适当的配置在适当的地方来定义这些插件。不需要写make或者是ant脚本,只需要插入插件,然后让Maven按照定义的顺序来执行就可以了。

一个和我关系很好的前同事说过(最近的一封email里写道):在生活或者是编码中打破常规是很好的,但是在Maven中永远不要这么做。他是对的!

如果你不知道如何安装Maven,请看看这里(windows)这里(Mac)

我的Maven工程结构:抽象

我们正在使用Maven构建工程,所以需要考虑maven的pom和模块。为了能创建出我们需要的ear包(看上面),我们需要5个pom文件:

  • 一个pom,作为父pom
  • 一个pom,包含、定义最终的ear包,它负责给最终的包做配置。
  • 一个pom,包含、定义web应用的代码,也就是我们的war包。
  • 一个pom,包含、定义ejb模块的代码,用来打包我们的ejb的模块。
  • 一个pom,包含JPA(数据库实体)类。

正如你看到的那样,每一个模块都有自己的pom文件,一个父pom文件。很多人不在他们的结构中添加父pom文件,因为他们的工程很小,所以不需要。当更多的模块添加进来时,没有父pom就变得一团糟。所以请记住,拥有并配置父pom文件是一件非常好的事情。在它里面,你会定义你所有依赖的jar包的版本,配置maven的插件,所有的子pom文件都会继承父pom的配置。

我的Maven工程的结构:父pom文件

正如前面说过的那样,我们要白手起家。所以我要创建一个新的文件夹叫做“sample-parent”,在这个文件夹中,添加一个新的文件叫做“pom.xml”。

1
2
3
4
5
6
7
8
9
10
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
         < modelVersion >4.0.0</ modelVersion >
         < groupId >gr.javapapo</ groupId >
         < artifactId >sample-parent</ artifactId >
         < version >0.0.1-SNAPSHOT</ version >
         < packaging >pom</ packaging >
  
        
</ project >

是的,现在还没什么可兴奋的,仅仅是给值是pompackaging元素做了个记录。之所以称之为父pom,因为它会定义并管理子模块,这是在模块定义部分完成的。我们的初始的pom看起来就像下面这个样子。这意味着,我们必须在sample-parent下面创建相关的文件夹,然后给它们每一个都添加pom.xml.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
         < modelVersion >4.0.0</ modelVersion >
         < groupId >gr.javapapo</ groupId >
         < artifactId >sample-parent</ artifactId >
         < version >0.0.1-SNAPSHOT</ version >
         < packaging >pom</ packaging >
  
         < modules >
                 < module >sample-ear</ module >
                 < module >sample-web</ module >
                 < module >sample-services</ module >
                 < module >sample-domain</ module >
         </ modules >
        
</ project >

让我们继续添加一些配置……

这是很重要的部分,因为我们要定义下面的版本:

  • 需要使用和配置的Maven插件。
  • 所有的jar包:被其他的模块所引用和使用的依赖。
  • 其他的通用的属性,比如我们要编译的Java运行时的版本。
  • 源文件或其他资源的默认的编码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
< properties >
         <!--  encoding-->
         < project.build.sourceEncoding >UTF-8</ project.build.sourceEncoding >
         <!--java version -->
         < java-version >1.7</ java-version >
        
         <!-- plugin versions -->
         < ejb-plugin-version >2.3</ ejb-plugin-version >
         < war-plugin-version >2.4</ war-plugin-version >
         < ear-plugin-version >2.9</ ear-plugin-version >
         < compiler-plugin-version >3.1</ compiler-plugin-version >
  
         <!-- dependency versions -->
         < javaee-api-version >7.0</ javaee-api-version >
                
         <!-- EJB spec version -->
         < ejb-spec-version >3.2</ ejb-spec-version >
</ properties >

在properties部分之后,继续添加另一个重要的部分dependencyManagement。这里用来定义在应用的模块中可能会用到的依赖和各自的版本。在这一部分中,我们实际关注的是版本号,包含还是排除依赖是取决于子pom(也就是说它们是不会被自动添加到子pom中的)。它们的作用范围也是一样。所以DependencyManagement是一个集中控制版本号的地方。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
< dependencyManagement >
         < dependencies >
                 < dependency >
                         < groupId >javax</ groupId >
                         < artifactId >javaee-api</ artifactId >
                         < version >${javaee-api-version}</ version >
                 </ dependency >
                 < dependency >
                         < groupId >junit</ groupId >
                         < artifactId >junit</ artifactId >
                         < version >${junit-version}</ version >
                 </ dependency >
         </ dependencies >
</ dependencyManagement >

在我们的父pom中,跟dependencyManagemt相似的另一个重要的部分是pluginManagement。在这个部分定义所有maven插件的版本和通用的配置。这些插件在我们的应用配置和打包的过程中会被引用或者是使用到。下面的例子中,我定义了一个最基本的编译器插件。当然,我们还需要更多的插件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- Plugin management -->
< build >
   < pluginManagement >
      < plugins >
         <!-- compiler plugin -->
         < plugin >
           < groupId >org.apache.maven.plugins</ groupId >
           < artifactId >maven-compiler-plugin</ artifactId >
           < version >${compiler-plugin-version}</ version >
           < configuration >
             < source >${java-version}</ source >
             < target >${java-version}</ target >
             < encoding >${project.build.sourceEncoding}</ encoding >
          </ configuration >
       </ plugin >
    </ plugins >
   </ pluginManagement >
</ build >

让我们在pluginManagement部分添加更多以后会用到的的插件。定义ejb插件用老编译和打包我们的ejb,定义war插件用来打包我们的war。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!-- ejb plugin -->
< plugin >
         < groupId >org.apache.maven.plugins</ groupId >
         < artifactId >maven-ejb-plugin</ artifactId >
         < version >${ejb-plugin-version}</ version >
         < configuration >
                 < ejbVersion >${ejb-spec-version}</ ejbVersion >
         </ configuration >
</ plugin >
  
<!-- war plugin -skinny wars mode! -->
< plugin >
   < groupId >org.apache.maven.plugins</ groupId >
   < artifactId >maven-war-plugin</ artifactId >
   < version >${war-plugin-version}</ version >
   < configuration >
         < failOnMissingWebXml >false</ failOnMissingWebXml >
         < packagingExcludes >WEB-INF/lib/*.jar</ packagingExcludes >
         < archive >
                 < manifest >
                         < addClasspath >true</ addClasspath >
                         < classpathPrefix >lib/</ classpathPrefix >
                 </ manifest >
         </ archive >
         < webResources >
                 < resource >
                         < filtering >true</ filtering >
                         < directory >src/main/webapp</ directory >
                         < includes >
                                 < include >**/web.xml</ include >
                         </ includes >
                 </ resource >
         </ webResources >
   </ configuration >
</ plugin >

现在

你可以在这里(tag是post1,bitbucket)下载最小的示例。时光飞逝,看起来我们什么也还没完成。但是,一步一步的定义了一个干净并且具体的父pom文件,他将是我们在下篇文章中要做的剩余工作的基础。

学习的重点

  • 标准的maven工程布局。
  • 父pom文件。
  • dependencyManagement和pluginManagement的重要性。

资源

原文链接:  javacodegeeks  翻译:  ImportNew.com  miracle1919
译文链接:  http://www.importnew.com/12408.html
转载请保留原文出处、译者和译文链接。 ]
相关文章
|
11天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
27 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
15天前
|
XML Java 测试技术
从零开始学 Maven:简化 Java 项目的构建与管理
Maven 是一个由 Apache 软件基金会开发的项目管理和构建自动化工具。它主要用在 Java 项目中,但也可以用于其他类型的项目。
30 1
从零开始学 Maven:简化 Java 项目的构建与管理
|
7天前
|
监控 架构师 Java
Java虚拟机调优的艺术:从入门到精通####
本文作为一篇深入浅出的技术指南,旨在为Java开发者揭示JVM调优的神秘面纱,通过剖析其背后的原理、分享实战经验与最佳实践,引领读者踏上从调优新手到高手的进阶之路。不同于传统的摘要概述,本文将以一场虚拟的对话形式,模拟一位经验丰富的架构师向初学者传授JVM调优的心法,激发学习兴趣,同时概括性地介绍文章将探讨的核心议题——性能监控、垃圾回收优化、内存管理及常见问题解决策略。 ####
|
24天前
|
Java 测试技术 Maven
Maven clean 提示文件 java.io.IOException
在使用Maven进行项目打包时,遇到了`Failed to delete`错误,尝试手动删除目标文件也失败,提示`java.io.IOException`。经过分析,发现问题是由于`sys-info.log`文件被其他进程占用。解决方法是关闭IDEA和相关Java进程,清理隐藏的Java进程后重新尝试Maven clean操作。最终问题得以解决。总结:遇到此类问题时,可以通过任务管理器清理相关进程或重启电脑来解决。
|
26天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
1月前
|
Java 大数据 API
14天Java基础学习——第1天:Java入门和环境搭建
本文介绍了Java的基础知识,包括Java的简介、历史和应用领域。详细讲解了如何安装JDK并配置环境变量,以及如何使用IntelliJ IDEA创建和运行Java项目。通过示例代码“HelloWorld.java”,展示了从编写到运行的全过程。适合初学者快速入门Java编程。
|
1月前
|
安全 Java 调度
Java中的多线程编程入门
【10月更文挑战第29天】在Java的世界中,多线程就像是一场精心编排的交响乐。每个线程都是乐团中的一个乐手,他们各自演奏着自己的部分,却又和谐地共同完成整场演出。本文将带你走进Java多线程的世界,让你从零基础到能够编写基本的多线程程序。
34 1
|
20天前
|
Java 程序员 数据库连接
Java中的异常处理:从入门到精通
在Java编程的海洋中,异常处理是一艘不可或缺的救生艇。它不仅保护你的代码免受错误数据的侵袭,还能确保用户体验的平稳航行。本文将带你领略异常处理的风浪,让你学会如何在Java中捕捉、处理和预防异常,从而成为一名真正的Java航海家。
|
1月前
|
Java 持续交付 项目管理
使用Maven进行项目管理:提高Java Web开发的效率
Maven 是一款强大的项目管理和构建自动化工具,广泛应用于Java社区。它通过依赖管理、构建生命周期管理、插件机制和多模块项目支持等功能,简化了项目的构建过程,提高了开发效率。本文将介绍Maven的核心功能及其在Java Web开发中的应用。
59 0
|
29天前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
89 8