eclipse项目从编程到打jar包到编写BashShell执行

一、创建Java项目,并编写项目(带额外jar包)

二、打jar包

三、编写BashShell执行

其中一以及二可以参考我的博客

一、创建Java项目,并编写项目(带额外jar包)

项目目录如下所示:

代码如下所示:

我设计了三个类,分别是 PersonData.java、Data2Json.java以及 TestData2Json.java,具体代码如下所示:

PersonData.java是个人员数据类,主要存储人员数据的。

package com.zc.dataclass.main;

import java.io.Serializable;

public class PersonData implements Serializable {
private static final long serialVersionUID = 1L; private String xm; //姓名
private String xb; //性别
private String sr; //生日
public String getXm() {
return xm;
}
public void setXm(String xm) {
this.xm = xm;
}
public String getXb() {
return xb;
}
public void setXb(String xb) {
this.xb = xb;
}
public String getSr() {
return sr;
}
public void setSr(String sr) {
this.sr = sr;
} }

Data2Json.java 主要是将数据类转换成JSON

package com.zc.data2json.trans.main;

import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject; /**
* @author zhangchao
* @date 2018-08-22
* 将数据(类)转换成Json格式数据
*/
public class Data2Json {
/**
* 将 Object 转换成 JSONObject
* @param obj
* @return
*/
public JSONObject data2JsonObj(Object obj) {
JSONObject jsonObj = JSONObject.fromObject(obj);
return jsonObj;
} /* 错误的例子
public JSONObject data2JsonObj(List<Object> list) {
JSONObject jsonObj = JSONObject.fromObject(list);
return jsonObj;
}*/ /**
* 将 Object 转换成 JSONArray
* @param obj
* @return
*/
public JSONArray data2JsonArr(Object obj) {
JSONArray jsonArr = JSONArray.fromObject(obj);
return jsonArr;
} /**
* 将 List<Object> 转换成 JSONArray
* @param list
* @return
*/
public JSONArray data2JsonArr(List<Object> list) {
JSONArray jsonArr = JSONArray.fromObject(list);
return jsonArr;
} /*public JSONArray data2JsonArr2(List<Object> list) {
JSONArray json = new JSONArray();
for(Object pLog : list){
JSONObject jo = new JSONObject();
jo.put("id", pLog.getId());
jo.put("time", pLog.getBeginTime()); // 注意add和element的区别
json.add(jo);
}
return json;
}*/ /**
* 将数组转换成JSONArray
* @param arr
* @return
*/
public JSONArray data2JsonArr(Object[] arr) {
JSONArray jsonArr = JSONArray.fromObject(arr);
return jsonArr;
}
}

TestData2Json.java 测试

package com.zc.data2json.trans.test;

import java.util.ArrayList;
import java.util.List; import com.zc.data2json.trans.main.Data2Json;
import com.zc.dataclass.main.PersonData; import net.sf.json.JSONArray; public class TestData2Json { private final static long heartbeat = 10; // 设置心跳10s
static long i=1; public static void main(String[] args) {
while(true) {
PersonData pD = getPersonData();
Data2Json dcj = new Data2Json();
JSONArray jsonArr = dcj.data2JsonArr(pD);
System.out.println(jsonArr.toString());
try {
Thread.sleep(heartbeat*1000); //ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} /*
* 获取类数据
*/
public static PersonData getPersonData() {
PersonData pd1 = new PersonData();
pd1.setXm("张"+i++);
//(数据类型)(最小值+Math.random()*(最大值-最小值+1))
int sex = (int)(1+Math.random()*(2-1+1));
if(sex==1)
pd1.setXb("男");
else
pd1.setXb("女");
pd1.setSr("1991-01-12"); return pd1;
} /*
* 获取类数据
*/
public static List<PersonData> getPersonDataList() {
PersonData pd1 = new PersonData();
pd1.setXm("张"+i++);
pd1.setXb("男");
pd1.setSr("1991-01-12"); List<PersonData> pd = new ArrayList<PersonData>();
pd.add(pd1); return pd;
}
}

二、打jar包

参考我的博客 Eclipse用Runnable JAR file方式打jar包,并用该jar包进行二次开发

用第三种方式打jar包

三、编写BashShell执行

首先先创建一个名为ZcData2Json的文件夹,该文件夹如下所示:

bin:其中放着运行程序的脚本文件 data2json
conf:放着配置文件 data2json.conf
data2json:放着第二步生成的jar包以及lib包
lib:用于存放jar包,暂为空
logs:用于存储生成的日志文件
run:用于存储运行进程的pid文件 data2json.pid
data2json文件内容如下所示:

bin中 data2json 内容如下所示:
#!/usr/bin/env bash

# DATA2JSON, 参考neo4j

#版本号
DATA2JSON_VERSION="data2json version \"1.0\"" #获取该文件的名称
declare -r PROGRAM="$(basename "$")"
#echo $PROGRAM #获取该文件的路径
bin=`dirname "${BASH_SOURCE-$0}"`
bin=`cd "$bin"; pwd` # get arguments 获取参数
command=$
#echo ${command} # 获取用户名
#执行程序启动所使用的系统用户,考虑到安全,推荐不使用root帐号
#USERNAME=$(users)
USERNAME=$USER
#echo $USERNAME
# 获取主机名
HOSTNAME=$(hostname)
#echo $HOSTNAME set -o errexit -o nounset -o pipefail
[[ "${TRACE:-}" ]] && set -o xtrace # Callers may provide the following environment variables to customize this script:
# * JAVA_HOME
# * JAVA_OPTS
# * JAVA_CMD ###################################
#环境变量及程序执行参数
#需要根据实际环境以及Java程序名称来修改这些参数
###################################
#JDK所在路径
#JAVA_HOME=$JAVA_HOME
#JAVA_HOME="/usr/lib/jvm/java"
#echo $JAVA_HOME # 检测系统
function detect_os() {
if uname -s | grep -q Darwin; then
DIST_OS="macosx"
elif [[ -e /etc/gentoo-release ]]; then
DIST_OS="gentoo"
else
DIST_OS="other"
fi
}
#detect_os
#echo $DIST_OS # 检测java
function check_java() {
_find_java_cmd version_command=("${JAVA_CMD}" "-version")
[[ -n "${JAVA_MEMORY_OPTS:-}" ]] && version_command+=("${JAVA_MEMORY_OPTS[@]}") JAVA_VERSION=$("${version_command[@]}" >& | awk -F '"' '/version/ {print $2}')
if [[ "${JAVA_VERSION}" < "1.8" ]]; then
echo "ERROR! DATA2JSON cannot be started using java version ${JAVA_VERSION}. "
_show_java_help
exit
fi if ! ("${version_command[@]}" >& | egrep -q "(Java HotSpot\\(TM\\)|OpenJDK|IBM) (64-Bit Server|Server|Client|J9) VM"); then
echo "WARNING! You are using an unsupported Java runtime. "
_show_java_help
fi
} # 查找Java命令
function _find_java_cmd() {
[[ "${JAVA_CMD:-}" ]] && return
detect_os
_find_java_home if [[ "${JAVA_HOME:-}" ]] ; then
JAVA_CMD="${JAVA_HOME}/bin/java"
if [[ ! -f "${JAVA_CMD}" ]]; then
echo "ERROR: JAVA_HOME is incorrectly defined as ${JAVA_HOME} (the executable ${JAVA_CMD} does not exist)"
exit
fi
else
if [ "${DIST_OS}" != "macosx" ] ; then
# Don't use default java on Darwin because it displays a misleading dialog box
JAVA_CMD="$(which java || true)"
fi
fi if [[ ! "${JAVA_CMD:-}" ]]; then
echo "ERROR: Unable to find Java executable."
_show_java_help
exit
fi
} # 查找Java home目录
function _find_java_home() {
[[ "${JAVA_HOME:-}" ]] && return case "${DIST_OS}" in
"macosx")
JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"
;;
"gentoo")
JAVA_HOME="$(java-config --jre-home)"
;;
esac
} function _show_java_help() {
echo "* Please use Oracle(R) Java(TM) 8, OpenJDK(TM) or IBM J9 to run DATA2JSON."
} # 设置 CLASSPATH
function build_classpath() {
CLASSPATH="${DATA2JSON_HOME}:${DATA2JSON_CONF}:${DATA2JSON_LIB}" # augment with tools.jar, will need JDK
if [ "${JAVA_HOME:-}" ]; then
JAVA_TOOLS="${JAVA_HOME}/lib/tools.jar"
if [[ -e $JAVA_TOOLS ]]; then
CLASSPATH="${CLASSPATH}:${JAVA_TOOLS}"
fi
fi
} # 设置 JAVA_OPTS
function setup_java_opts() {
JAVA_OPTS=("-server")
JAVA_OPTS+=" -Xms512m -Xmx512m -Xmn256m -Djava.awt.headless=true -XX:MaxNewSize=256m"
} # Sets up the standard environment for running Neo4j shell scripts.
#
# Provides these environment variables:
# DATA2JSON_HOME
# DATA2JSON_CONF
# DATA2JSON_DATA
# DATA2JSON_LIB
# DATA2JSON_LOGS
# DATA2JSON_PIDFILE
# DATA2JSON_RUN
# DATA_START_WAIT
# one per config setting, with dots converted to underscores
# #usage="-e Usage: DATA2JSON\n\t
# [--config <conf-dir>] {start|stop|restart|status|version}\n\t
# [--version | version | -v]\n\t
# [--help | -help | help]"
usage="Usage: $PROGRAM { start | stop | restart | status | version | help }" # if no args specified, show usage
function print_usage() {
if [ $# -le ]; then
echo $usage
exit
fi
} #设置环境
function setup_environment() {
_setup_calculated_paths
#_read_config
_setup_configurable_paths
} # 设置HOME以及CONF目录
function _setup_calculated_paths() {
#echo "_setup_calculated_paths()"
if [[ -z "${DATA2JSON_HOME:-}" ]]; then
DATA2JSON_HOME="$(cd "$(dirname "$0")"/.. && pwd)"
fi
: "${DATA2JSON_CONF:="${DATA2JSON_HOME}/conf"}"
readonly DATA2JSON_HOME DATA2JSON_CONF
} # Resolve a path relative to $DATA2JSON_HOME. Don't resolve if
# the path is absolute.
function resolve_path() {
orig_filename=$
if [[ ${orig_filename} == /* ]]; then
filename="${orig_filename}"
else
filename="${DATA2JSON_HOME}/${orig_filename}"
fi
echo "${filename}"
} # 读取配置文件
function _read_config() {
# - plain key-value pairs become environment variables
# - keys have '.' chars changed to '_'
# - keys of the form KEY.# (where # is a number) are concatenated into a single environment variable named KEY
parse_line() {
line="$1"
if [[ "${line}" =~ ^([^#\s][^=]+)=(.+)$ ]]; then
key="${BASH_REMATCH[1]//./_}"
value="${BASH_REMATCH[2]}"
#echo "${key}=${value}"
if [[ "${key}" =~ ^(.*)_([0-9]+)$ ]]; then
key="${BASH_REMATCH[1]}"
fi
if [[ "${!key:-}" ]]; then
export ${key}="${!key} ${value}"
#echo "if ${key}"
else
export ${key}="${value}"
#echo "else $key"
fi
fi
} for file in "data2json.conf"; do
path="${DATA2JSON_CONF}/${file}"
echo $path
if [ -e "${path}" ]; then
while read line; do
parse_line "${line}"
done <"${path}"
fi
done
} #function _setup_configurable_paths() {
# DATA2JSON_LIB=$(resolve_path "$DATA2JSON_HOME/lib")
## get log directory
# if [ "$DATA2JSON_LOGS" = "" ]; then
# export DATA2JSON_LOGS="$DATA2JSON_HOME/logs"
# fi
# if [ ! -w "$DATA2JSON_LOGS" ] ; then
# mkdir -p "$DATA2JSON_LOGS"
# chown $USER $DATA2JSON_LOGS
# fi
# DATA2JSON_LOGS=$(resolve_path "$DATA2JSON_HOME/logs")
## get run directory
# if [ "$DATA2JSON_RUN" = "" ]; then
# export DATA2JSON_RUN="$DATA2JSON_HOME/run"
# fi
# if [ ! -w "$DATA2JSON_RUN" ] ; then
# mkdir -p "$DATA2JSON_RUN"
# chown $USER $DATA2JSON_RUN
# fi
# DATA2JSON_RUN=$(resolve_path "$DATA2JSON_HOME/run")
#
# readonly DATA2JSON_DATA DATA2JSON_LIB DATA2JSON_LOGS DATA2JSON_RUN
#} # 引入配置文件的设置
_setup_configurable_paths() {
DATA2JSON_LIB=$(resolve_path "${data2json_directories_lib:-lib}")
DATA2JSON_LOGS=$(resolve_path "${data2json_directories_logs:-logs}")
DATA2JSON_RUN=$(resolve_path "${data2json_directories_run:-run}") readonly DATA2JSON_LIB DATA2JSON_LOGS DATA2JSON_RUN
} function print_configurable_paths() {
cat <<EOF
Directories in use:
home: ${DATA2JSON_HOME}
config: ${DATA2JSON_CONF}
logs: ${DATA2JSON_LOGS}
run: ${DATA2JSON_RUN}
EOF
} function print_path() {
echo "home: $DATA2JSON_HOME"
echo "conf: $DATA2JSON_CONF"
echo "lib: $DATA2JSON_LIB"
echo "logs: $DATA2JSON_LOGS"
echo "run: $DATA2JSON_RUN"
} function check_status() {
if [ -e "${DATA2JSON_PIDFILE}" ] ; then
DATA2JSON_PID=$(cat "${DATA2JSON_PIDFILE}")
kill -0 "${DATA2JSON_PID}" 2>/dev/null || unset DATA2JSON_PID
fi
} function check_limits() {
detect_os
#echo "detect_os"
if [ "${DIST_OS}" != "macosx" ] ; then
ALLOWED_OPEN_FILES="$(ulimit -n)"
#echo ${ALLOWED_OPEN_FILES}
#echo ${MIN_ALLOWED_OPEN_FILES}
if [ "${ALLOWED_OPEN_FILES}" -lt "${MIN_ALLOWED_OPEN_FILES}" ]; then
echo "WARNING: Max ${ALLOWED_OPEN_FILES} open files allowed, minimum of ${MIN_ALLOWED_OPEN_FILES} recommended."
fi
fi
} function set_mainjar() {
if [ -f "$DATA2JSON_HOME/data2json/data2json.jar" ] ; then
MAIN_JAR="$DATA2JSON_HOME/data2json/data2json.jar"
else
echo "jarfile doesn't exist"
fi
} function assemble_command_line() {
#retval=("${JAVA_CMD}" "-jar" "${JAVA_OPTS[@]}" "-Dfile.encoding=UTF-8" "${MAIN_JAR}" \
#"--home-dir=${DATA2JSON_HOME}" "--config-dir=${DATA2JSON_CONF}")
retval=("${JAVA_CMD}" "-jar" "-Dfile.encoding=UTF-8" "${MAIN_JAR}")
} ###################################
#(函数)判断程序是否已启动
#
#说明:
#使用JDK自带的JPS命令及grep命令组合,准确查找pid
#jps 加 l 参数,表示显示java的完整包路径
#使用awk,分割出pid ($1部分),及Java程序名称($2部分)
###################################
#初始化psid变量(全局)
psid=0 function checkpid() {
javaps=`ps -ef | grep data2json.jar | grep -v "grep"`
echo $javaps
if [ -n "$javaps" ]; then
psid=`echo $javaps | awk '{print $2}'`
else
psid=0
fi
} # 启动程序
function do_start() {
check_status if [[ "${DATA2JSON_PID:-}" ]] ; then
echo "DATA2JSON is already running (pid ${DATA2JSON_PID})."
exit 0
fi echo "Starting DATA2JSON." #check_limits
build_classpath assemble_command_line
command_line=("${retval[@]}")
# 输出到日志文件
#nohup "${command_line[@]}">>"${DATA2JSON_LOG}" 2>&1 &
##nohup "${command_line[@]}">>"${DATA2JSON_LOG}" 2>&1 < /dev/null &
#显示该文件末尾10行的内容
#tailf ${DATA2JSON_LOG}
# 输出到终端
(${command_line[@]} &)
#echo "$!" >"${DATA2JSON_PIDFILE}"
checkpid
#echo $psid
echo $psid >${DATA2JSON_PIDFILE} : "${DATA_START_WAIT:=5}"
end="$((SECONDS+DATA_START_WAIT))"
while true; do
check_status if [[ "${DATA2JSON_PID:-}" ]]; then
break
fi if [[ "${SECONDS}" -ge "${end}" ]]; then
echo "Unable to start. See ${DATA2JSON_LOG} for details."
rm "${DATA2JSON_PIDFILE}"
return 1
fi sleep 1
done #print_start_message
#echo "See ${DATA2JSON_LOG} for current status."
} # 关闭程序
function do_stop() {
check_status if [[ ! "${DATA2JSON_PID:-}" ]] ; then
echo "data2json not running"
[ -e "${DATA2JSON_PIDFILE}" ] && rm "${DATA2JSON_PIDFILE}"
return 0
else
echo -n "Stopping data2json."
SHUTDOWN_TIMEOUT=20
end="$((SECONDS+SHUTDOWN_TIMEOUT))"
while true; do
check_status if [[ ! "${DATA2JSON_PID:-}" ]]; then
echo " stopped"
[ -e "${DATA2JSON_PIDFILE}" ] && rm "${DATA2JSON_PIDFILE}"
return 0
fi kill "${DATA2JSON_PID}" 2>/dev/null || true if [[ "${SECONDS}" -ge "${end}" ]]; then
echo " failed to stop"
echo "data2json (pid ${DATA2JSON_PID}) took more than ${SHUTDOWN_TIMEOUT} seconds to stop."
echo "Please see ${DATA2JSON_LOG} for details."
return 1
fi echo -n "."
sleep 1
done
fi
} function do_status() {
check_status
if [[ ! "${DATA2JSON_PID:-}" ]] ; then
echo "data2json is not running"
exit 3
else
echo "data2json is running at pid ${DATA2JSON_PID}"
fi
} function do_version() {
echo "${DATA2JSON_VERSION}"
} #function do_version() {
# build_classpath
#
# assemble_command_line
# command_line=("${retval[@]}" "--version")
# exec "${command_line[@]}"
#} function main() {
#print_usage
setup_environment
#print_path DATA2JSON_LOG="${DATA2JSON_LOGS}/data2json-$USER-$HOSTNAME.log"
DATA2JSON_PIDFILE="${DATA2JSON_RUN}/data2json.pid"
readonly DATA2JSON_LOG DATA2JSON_PIDFILE setup_java_opts
check_java
set_mainjar
#echo "end set_mainjar" case "${1:-}" in
start)
print_configurable_paths
do_start
;; stop)
do_stop
;; restart)
do_stop
do_start
;; status)
do_status
;; version|--version|-v)
do_version
;; help|--help|-help)
echo "Usage: ${PROGRAM} { start | stop | restart | status | version | help }"
;; *)
echo >&2 "Usage: ${PROGRAM} { start | stop | restart | status | version | help }"
exit 1
;;
esac
} #运行main函数
main "$@"

最后,运行,在命令行输入:

#启动,在data2json目录下
./data2json start
#关闭,在data2json目录下
./data2json stop

eclipse项目从编程到打jar包到编写BashShell执行的更多相关文章

  1. eclipse项目中引入shiro-freemarker-tags会jar包冲突

    maven项目中引入了这个依赖. <dependency> <groupId>net.mingsoft</groupId> <artifactId>sh ...

  2. eclipse项目(java project)如何导入jar包的解决方案列表?

    右键项目-properties-java build path(左侧菜单)-选择libraries 有两种方式,导入jar包实际上就是建立一种链接,并不是copy式的导入 一.导入外部包,add ex ...

  3. eclipse java项目中明明引入了jar包 为什么项目启动的时候不能找到jar包 项目中已经 引入了 com.branchitech.app 包 ,但时tomcat启动的时候还是报错? java.lang.ClassNotFoundException: com.branchitech.app.startup.AppStartupContextListener java.lang.ClassN

    eclipse java项目中明明引入了jar包 为什么项目启动的时候不能找到jar包 项目中已经 引入了 com.branchitech.app 包 ,但时tomcat启动的时候还是报错?java. ...

  4. Eclipse下新建Maven项目、自动打依赖jar包

    当我们无法从本地仓库找到需要的构件的时候,就会从远程仓库下载构件至本地仓库.一般地,对于每个人来说,书房只有一个,但外面的书店有很多,类似第,对于Maven来说,每个用户只有一个本地仓库,但可以配置访 ...

  5. Eclipse下Maven新建项目、自动打依赖jar包(包含普通项目和Web项目)

    不多说,直接上干货! 当我们无法从本地仓库找到需要的构件的时候,就会从远程仓库下载构件至本地仓库.一般地,对于每个人来说,书房只有一个,但外面的书店有很多,类似第,对于Maven来说,每个用户只有一个 ...

  6. eclipse maven项目如何将所有的jar包复制到lib目录下?

      1.情景展示 我们知道,maven项目的jar包并不存在于项目当中,项目所需的jar包都保存在本地仓库中,如果本地仓库没有,会从配置的中央仓库下载,如果中央仓库也没有就会报错: 如上图所示,我想将 ...

  7. 解决Eclipse发布到Tomcat丢失依赖jar包的问题

    解决Eclipse发布到Tomcat丢失依赖jar包的问题 如果jar文件是以外部依赖的形式导入的.Eclipse将web项目发布到Tomcat时,是不会自动发布这些依赖的. 可以通过Eclipse在 ...

  8. 02_MyBatis项目结构,所需jar包,ehcache.xml配置,log4j.properties,sqlMapConfig.xml配置,SqlMapGenerator.xml配置

     项目结构(所需jar包,配置文件) sqlMapConfig.xml的配置内容如下: <?xmlversion="1.0"encoding="UTF-8&qu ...

  9. 【Maven】【IDEA】在idea中开发web项目,解决maven的jar包冲突的方法

    在idea中开发web项目,解决maven的jar包冲突的方法 第一步: 先对项目进行 clean ,再进行install 第二步: 出现NoSuchMethodException,ClassNotF ...

随机推荐

  1. DDR硬件设计要点详解(包括电源部分)

    转自 http://www.fairchildic.org/module/forum/thread-658-1-1.html (原帖包括详细的附件内容) 1. 电源 DDR的电源可以分为三类A.主电源 ...

  2. some cmds,tools and utils man

    NAME stdbuf - Run COMMAND, with modified buffering operations for its standard streams. SYNOPSIS std ...

  3. bluedroid源代码分析之ACL包发送和接收(一)

    很多其它内容请參照我的个人网站: http://stackvoid.com/ ACL 链路在 Bluetooth 中很重要,一些重要的应用如 A2DP, 基于 RFCOMM 的应用,BNEP等都要建立 ...

  4. HTML5开发移动web应用—JQuery Mobile(1)

    JQuery Mobile是一个简单易用的web移动app开发框架.使用它就像使用jQuery一样,引入必要的文件就可以. 最基础的jQuery Mobile文件的结构代码例如以下: <body ...

  5. kubernetes集群管理之通过jq来截取属性

    系列目录 首先要声明,这里的jq并不是批前端框架里的jquery,而是一个处理json的命令行工具. jq工具相比yq,它更加成熟,功能也更加强大,主要表现在以下几个方面 支持递归查找(我点对我们平时 ...

  6. MVC入门——详细页

    添加Action ShowDetail using System; using System.Collections.Generic; using System.Linq; using System. ...

  7. 10个必需的iOS开发工具和资源

    本文转载至 http://mobile.51cto.com/iphone-418166.htm 界面总不是一件很容易事,尤其是iPhone/iPad的界面,做过iOS开发的程序员,一定会感到开发iPh ...

  8. Java多线程学习(吐血超详细总结)转自博主林炳文Evankaka

    文章由林炳文Evankaka原创.转载自http://blog.csdn.net/evankaka 写在前面的话:此文只能说是Java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果 ...

  9. asp.net mvc4 之Webapi之客户端或服务器端安全控制

    一.WebAPI的工作方式 WebAPI的工作方式:HTTP的请求最先是被传递到HOST中的,如果WebAPI是被寄宿在IIS上的,这个HOST就是IIS上,HOST是没有能力也没有必 要进行请求的处 ...

  10. 设置port转发来訪问Virtualbox里linux中的站点

    上一篇中我们讲到怎么设置virtuabox来通过SSH登录机器. 相同.我们也能够依照上一篇内容中的介绍,设置port转发,来訪问虚拟linux系统已经搭建的站点: 1.设置port转发: water ...