最新消息:

eclipse/sts开发应用程序发布jar文件读取外部配置文件方法实践

其他分类 luther 1951浏览 0评论

我们开发java应用程序后,发布为jar可执行文件时,会把resources里的配置文件一同发布到jar文件里,不利于将来的配置修改,下面是我的jar读起外部配置文件的方法:

适用范围:eclipse或者sts创建的普通maven应用程序,不是web项目,也不是spring项目。

jar文件和resources配置文件夹在同一个目录下;不在同一个目录则程序代码做响应的修改;

步骤:

创建项目

file–new–Maven Project,maven-archetype-quickstart…

项目目录结构如图:

项目涉及读取的配置文件有log4j.properties:log4j日志功能的配置文件;

redis.properties:redis缓存功能的配置文件;

dbconfigration.xml:mysql数据库/mybatis持久层框架的配置文件;

还有就是应用程序的项目信息配置文件;

而model下的member.xml则是的mapper配置文件;

下面是应用程序发布成jar文件后的目录结构:

就是有一个jar文件和一个resources文件夹,resources里面是之前的配置文件,当然,这个resources文件夹是手动copy过来跟.jar文件同一个目录的。

为了能在jar运行后能够读起它外部resources里的配置文件,我要在程序上做处理:

首先处理log4j配置文件的的读取,为了能够让log4j引用外部resources里的配置文件,我们要在应用程序运行初期指定log4j配置文件路径,如在main里指定log4j的配置文件路径:

String userdir = MyPath.getProjectPath();//获取应用程序的根路径,重点

String logconfigfile = userdir + File.separatorChar + “resources” + File.separatorChar+ “log4j.properties”;//获取配置文件的物理路径,这就是外部路径

try {

File file = new File(“log4j.properties”);//读起配置文件

if (!file.exists()) {

file = new File(logconfigfile);

if (file.exists())

// 配置文件初始化

PropertyConfigurator.configure(logconfigfile);

else {

logconfigfile = userdir + File.separatorChar + “src” + File.separator + “main” + File.separator

+ “resources” + File.separatorChar + “log4j.properties”;//这是内部路径,为了在开发工具(sts/eclipse)里能够运行

file = new File(logconfigfile);

if (file.exists())

// 配置文件初始化

PropertyConfigurator.configure(logconfigfile);

}

System.out.println(“configfile log4j complete:” + logconfigfile);

}

catch (Exception e) {

System.out.println(“configfile log4j fail”);

}

这样就完成了log4j的配置文件指定;

下面贴出

MyPath类的实现代码(转载+测试):

publicclass MyPath {

publicstatic String getProjectPath() {

java.net.URL url = MyPath.class.getProtectionDomain().getCodeSource().getLocation();

String filePath = null;

try {

filePath = java.net.URLDecoder.decode(url.getPath(), “utf-8”);

catch (Exception e) {

e.printStackTrace();

}

if (filePath.endsWith(“.jar”))

filePath = filePath.substring(0, filePath.lastIndexOf(“/”) + 1);

java.io.File file = new java.io.File(filePath);

filePath = file.getAbsolutePath();

return filePath;

}

publicstatic String getRealPath() {

String realPath =“”;

try

{

realPath = MyPath.class.getClassLoader().getResource(“”).getFile();

}

catch(Exception ec)

{

returnnull;

}

java.io.File file = new java.io.File(realPath);

realPath = file.getAbsolutePath();

try {

realPath = java.net.URLDecoder.decode(realPath, “utf-8”);

catch (Exception e) {

e.printStackTrace();

}

return realPath;

}

publicstatic String getAppPath(Class<?> cls) {

// 检查用户传入的参数是否为空

if (cls == null)

thrownew java.lang.IllegalArgumentException(“参数不能为空!”);

ClassLoader loader = cls.getClassLoader();

// 获得类的全名,包括包名

String clsName = cls.getName();

// 此处简单判定是否是Java基础类库,防止用户传入JDK内置的类库

if (clsName.startsWith(“java.”) || clsName.startsWith(“javax.”)) {

thrownew java.lang.IllegalArgumentException(“不要传送系统类!”);

}

// 将类的class文件全名改为路径形式

String clsPath = clsName.replace(“.”, “/”) + “.class”;

// 调用ClassLoader的getResource方法,传入包含路径信息的类文件名

java.net.URL url = loader.getResource(clsPath);

// 从URL对象中获取路径信息

String realPath = url.getPath();

// 去掉路径信息中的协议名”file:”

int pos = realPath.indexOf(“file:”);

if (pos > -1) {

realPath = realPath.substring(pos + 5);

}

// 去掉路径信息最后包含类文件信息的部分,得到类所在的路径

pos = realPath.indexOf(clsPath);

realPath = realPath.substring(0, pos – 1);

// 如果类文件被打包到JAR等文件中时,去掉对应的JAR等打包文件名

if (realPath.endsWith(“!”)) {

realPath = realPath.substring(0, realPath.lastIndexOf(“/”));

}

java.io.File file = new java.io.File(realPath);

realPath = file.getAbsolutePath();

try {

realPath = java.net.URLDecoder.decode(realPath, “utf-8”);

catch (Exception e) {

thrownew RuntimeException(e);

}

return realPath;

}// getAppPath定义结束

}

其中,getRealPath的

realPath = MyPath.class.getClassLoader().getResource(“”).getFile();

在执行java -jar xxx.jar时将出错,也就是说这个方法在本案中不可用。

下面讲一下读起mybatis的配置文件dbconfiguration.xml的方法:

static {

try {

String dbconfigfile = “dbconfigration.xml”;

File file = new File(dbconfigfile);

if (file.exists() && !file.isDirectory())

reader = new FileReader(dbconfigfile);//开发环境运行

// Resources.getResourceAsReader(dbconfigfile);

else {

String userdir = MyPath.getProjectPath();

//发布后环境运行读取路径

dbconfigfile = userdir + File.separatorChar + “resources” + File.separatorChar + dbconfigfile;

System.out.println(“dbconfig.xml filepath:” + dbconfigfile);

file = new File(dbconfigfile);

if (file.exists() && !file.isDirectory())

reader = new FileReader(dbconfigfile);

else

{

//开发环境运行路径

dbconfigfile = userdir + File.separatorChar + “src” + File.separator + “main” + File.separator+ “resources” + File.separatorChar + dbconfigfile;

System.out.println(“dbconfig.xml filepath:” + dbconfigfile);

file = new File(dbconfigfile);

if (file.exists() && !file.isDirectory())

reader = new FileReader(dbconfigfile);

else

{

System.out.println(“dbconfile is no found”);

}

}

}

if (reader != null)

sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

else {

System.out.println(“dbconfig reader is null”);

}

catch (IOException e) {

e.printStackTrace();

}

}

上面的程序的作用就是获得mybatis配置文件xml的正确的reader,从而通过sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);来初始化mybatis的session;

我们来看看dbconfigration.xml的内容,

<?xml version=“1.0” encoding=“UTF-8” ?>

<!DOCTYPE configuration

PUBLIC “-//mybatis.org//DTD Config 3.0//EN”

mybatis.org/dtd/mybatis”>

<configuration>

<!–如果在mapper中进行配置了,此处可以省略配置 –>

<!–<typeAliases> –>

<!–<typeAlias alias=”User” type=”com.demo.bean.model.User”/> –>

<!–</typeAliases> –>

<!– 和spring整合后 environments配置将废除 –>

<environments default=“development”>

<environment id=“development”>

<!– 使用jdbc事务管理 –>

<transactionManager type=“JDBC” />

<!– 数据库连接池 –>

<dataSource type=“POOLED”>

<property name=“driver” value=“com.mysql.cj.jdbc.Driver” />

<property name=“url”

value=“jdbc:mysql://localhost:3306/dbname?characterEncoding=utf-8&amp;useSSL=true” />

<property name=“username” value=“root” />

<property name=“password” value=“123456” />

</dataSource>

</environment>

</environments>

<mappers>

<mapper resource=“com/baidu/monkey/model/member.xml” />

</mappers>

</configuration>

其中<mapper>这里用”resource”指向member.xml文件,这在.jar发布后,将无法读起,其实mapper还有可以以url的方式配置mapper配置文件:

<mappers>

<mapper url=”file:/Users/username/Desktop/mydevelop/java/monkey/resources/Member.xml” />

</mappers>

这里file就可以根据实际路径进行配置了。

这样,mybatis的配置和映射配置就没有问题了;

下面我们来看一下读取外部普通.properties配置文件的方法

读取配置文件,可以通过获取文件的inputstream流,我们首先写一个通用的类来获取正确的配置文件的inoutstream流,其主要方法如下:

publicstatic InputStream getConfigStream(String filename)

{

// 配置文件初始化

//PropertyConfigurator.configure(filepath);

InputStream inputStream = null;

try {

inputStream = Config.class.getClassLoader().getResourceAsStream(filename);//为了开发环境能够运行

if (inputStream ==null)

{

String userdir = MyPath.getProjectPath();

String configfile = userdir + File.separatorChar + “resources” +File.separatorChar+filename;//获取外部配置文件路径

System.out.println(“getConfigProperties configfilepath:” + configfile);

inputStream = new FileInputStream(configfile);//获取配置文件的流

if (inputStream ==null )

{

System.out.println(“tc.properties is not found”);

}

}

catch (Exception e) {

e.printStackTrace();

}

return inputStream;

}

有了正确的配置文件的inputstream后,就可以用property来读取这个流了;

String tcconfigfile = “cofig.properties”;

InputStream in = getConfigStream(tcconfigfile);//获取正确的流

if (in != null) {

Properties property = new Properties();

property.load(in);

String configPort = property.getProperty(“socket.port”);

in.close(); in=null;

if (configPort != null && configPort != “”) {

System.out.println(“socket.port:” + configPort);

port = Integer.parseInt(configPort);

else

{

System.out.println(“server port readfail!”);

}

else {

port = 5880;

}

注意:jar文件和resources配置文件夹在同一个目录下;不在同一个目录则程序代码做响应的修改;

补充:jar的导出方法,右键项目--export--java(Runnable JAR file)–lanuch configuration选择你的项目,再Export destination设置你的jar导出路径,Library handing:选extract required libraries into generation JAR–Finish , 完成;

执行jar: java -jar /jarfilepath/jarfilename.jar

如果你的jar是一个服务,要让他在后台运行,那么,可以用下面的脚本(linux和mac里可用):

#! /bin/sh

#启动方法

start(){

now=`date “+%Y%m%d%H%M%S”`

exec java -Xms128m -Xmx2048m -jar /Users/username/Desktop/java/20170318/jarfile.jar >’log/tclog/’”$now”_bidcheck.log &

}

#停止方法

stop(){

ps -ef|grep java|awk ‘{print $2}’|while read pid

do

kill -9 $pid

done

}

case “$1” in

start)

start

;;

stop)

stop

;;

restart)

stop

start

;;

*)

printf ‘Usage: %s {start|stop|restart}\n’ “$prog”

exit 1

;;

esac

把上面的脚本保存成servcejar.sh,启动方法就是:

sh servcejar.sh start

还有

sh servcejar.sh restart

sh servcejar.sh stop

本文完;

原创文章,转载请注明: 转载自职道

本文链接地址: eclipse/sts开发应用程序发布jar文件读取外部配置文件方法实践

文章的脚注信息由WordPress的wp-posturl插件自动生成

转载请注明:职道 » eclipse/sts开发应用程序发布jar文件读取外部配置文件方法实践

您必须 登录 才能发表评论!