Shell-通过shell启动Java类中的main方法 + 通过Shell启动jar包

简介: Shell-通过shell启动Java类中的main方法 + 通过Shell启动jar包

概述


Java程序 运行在linux主机上, 通过shell脚本启动为进程。

Java程序中 通过定时任务,设置访问Hbase的时间间隔,设置告警规则,比如三次获取Hbase中的数据失败,则调用存过,遍历配置的告警号码,插入短信中间表,实现短信的发送。

项目结构如下


20151211031831654.png


shell启动Java类中的main方法

启动脚本分析

根据服务器上JDK 以及工程部署路径



20151211032002546.png


修改相应的#JDK所在路径 APP_HOME 启动入口类APP_MAINCLASS(需有main方法) 。注意CLASSPATH,务必正确export相应的jar包。

之前碰到了一个错误,应用启动时,hadoop会加载native文件,有两种解决方式:


第一种 在java虚拟机启动参数加入: -Djava.library.path=/home/aaaa/app/hadoop-2.3.0-cdh5.1.2/lib/native

第二种 export LD_LIBRARY_PATH=/home/aaaa/app/hadoop-2.3.0-cdh5.1.2/lib/native


我采用了第一种方式来加载对应的native。(找到主机native的安装路径指定即可)


应用中引用的hadoop相关的jar包(后面因报错,增加了commons-codec-1.10.jar 和 netty-3.6.6.Final.jar)


btw: 应用中的hadoop相关jar尽量和大数据平台的保持一致, 所以本应用的jar都是从大数据平台主机上down下来的 (@ο@)。


如不清楚jar包具体位置,


第一种方式 可以查看环境变量 通过env命令,查看 HADOOP_CLASSPATH 相关信息

第二种方式 cat /etc/profile 查看环境变量。 可以看到引入了

. /home/aisc/app/env.sh

env.sh ,so 进去瞅瞅相应的路径就ok了。


可以看到 $AISC_HOME/libjars/*.jar

for f in $AISC_HOME/libjars/*.jar; do CLASSPATH=${CLASSPATH}:$f; done
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$CLASSPATH

脚本启动方式 ./startup 【start | stop | info | status 】详见脚本

#!/bin/sh
#该脚本为Linux下启动java程序的通用脚本。即可以作为开机自启动service脚本被调用,
#也可以作为启动java程序的独立脚本来使用。
#
#Author: tudaxia.com, Date: 2011/6/7
#
#警告!!!:该脚本stop部分使用系统kill命令来强制终止指定的java程序进程。
#在杀死进程前,未作任何条件检查。在某些情况下,如程序正在进行文件或数据库写操作,
#可能会造成数据丢失或数据不完整。如果必须要考虑到这类情况,则需要改写此脚本,
#增加在执行kill命令前的一系列检查。
#
#
###################################
#环境变量及程序执行参数
#需要根据实际环境以及Java程序名称来修改这些参数
###################################
#JDK所在路径
JAVA_HOME="/usr/java/jdk1.7.0_60"
#执行程序启动所使用的系统用户,考虑到安全,推荐不使用root帐号 (本次我在下面的start和stop方法中,屏蔽了校验 忘记了xxx的密码了.... )
RUNNING_USER=xxx
#Java程序所在的目录(classes的上一级目录)
APP_HOME=/home/xxx/HbaseMonitor
#需要启动的Java主程序(main方法类)
APP_MAINCLASS=com.xxxxx.monitor.hbase.HbaseMonitor
#拼凑完整的classpath参数,包括指定lib目录下所有的jar
CLASSPATH=$APP_HOME/bin
for i in "$APP_HOME"/lib/*.jar; do
   CLASSPATH="$CLASSPATH":"$i"
done
#export  LD_LIBRARY_PATH=/home/aaaa/app/hadoop-2.3.0-cdh5.1.2/lib/native
#java虚拟机启动参数
JAVA_OPTS="-ms512m -mx512m -Xmn256m -Djava.awt.headless=true -XX:MaxPermSize=128m -Djava.library.path=/home/aaaa/app/hadoop-2.3.0-cdh5.1.2/lib/native" 
###################################
#(函数)判断程序是否已启动
#
#说明:
#使用JDK自带的JPS命令及grep命令组合,准确查找pid
#jps 加 l 参数,表示显示java的完整包路径
#使用awk,分割出pid ($1部分),及Java程序名称($2部分)
###################################
#初始化psid变量(全局)
psid=0
checkpid() {
   javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAINCLASS`
   if [ -n "$javaps" ]; then
      psid=`echo $javaps | awk '{print $1}'`
   else
      psid=0
   fi
}
###################################
#(函数)启动程序
#
#说明:
#1. 首先调用checkpid函数,刷新$psid全局变量
#2. 如果程序已经启动($psid不等于0),则提示程序已启动
#3. 如果程序没有被启动,则执行启动命令行
#4. 启动命令执行后,再次调用checkpid函数
#5. 如果步骤4的结果能够确认程序的pid,则打印[OK],否则打印[Failed]
#注意:echo -n 表示打印字符后,不换行
#注意: "nohup 某命令 >/dev/null 2>&1 &" 的用法
###################################
start() {
   checkpid
   if [ $psid -ne 0 ]; then
      echo "================================"
      echo "warn: $APP_MAINCLASS already started! (pid=$psid)"
      echo "================================"
   else
      echo -n "Starting $APP_MAINCLASS ..."
   # 设置推荐用户启动
    #  JAVA_CMD="nohup $JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS >/dev/null 2>&1 &"
    # su - $RUNNING_USER -c "$JAVA_CMD"
     nohup $JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS >/dev/null 2>&1 &
      checkpid
      if [ $psid -ne 0 ]; then
         echo "(pid=$psid) [OK]"
      else
         echo "[Failed]"
      fi
   fi
}
###################################
#(函数)停止程序
#
#说明:
#1. 首先调用checkpid函数,刷新$psid全局变量
#2. 如果程序已经启动($psid不等于0),则开始执行停止,否则,提示程序未运行
#3. 使用kill -9 pid命令进行强制杀死进程
#4. 执行kill命令行紧接其后,马上查看上一句命令的返回值: $?
#5. 如果步骤4的结果$?等于0,则打印[OK],否则打印[Failed]
#6. 为了防止java程序被启动多次,这里增加反复检查进程,反复杀死的处理(递归调用stop)。
#注意:echo -n 表示打印字符后,不换行
#注意: 在shell编程中,"$?" 表示上一句命令或者一个函数的返回值
###################################
stop() {
   checkpid
   if [ $psid -ne 0 ]; then
      echo -n "Stopping $APP_MAINCLASS ...(pid=$psid) "
    # 设置推荐用户停止
      #su - $RUNNING_USER -c "kill -9 $psid"
      #不校验用户直接kill
      kill -9 $psid
      if [ $? -eq 0 ]; then
         echo "[OK]"
      else
         echo "[Failed]"
      fi
      checkpid
      if [ $psid -ne 0 ]; then
         stop
      fi
   else
      echo "================================"
      echo "warn: $APP_MAINCLASS is not running"
      echo "================================"
   fi
}
###################################
#(函数)检查程序运行状态
#
#说明:
#1. 首先调用checkpid函数,刷新$psid全局变量
#2. 如果程序已经启动($psid不等于0),则提示正在运行并表示出pid
#3. 否则,提示程序未运行
###################################
status() {
   checkpid
   if [ $psid -ne 0 ];  then
      echo "$APP_MAINCLASS is running! (pid=$psid)"
   else
      echo "$APP_MAINCLASS is not running"
   fi
}
###################################
#(函数)打印系统环境参数
###################################
info() {
   echo "System Information:"
   echo "****************************"
   echo `head -n 1 /etc/issue`
   echo `uname -a`
   echo
   echo "JAVA_HOME=$JAVA_HOME"
   echo `$JAVA_HOME/bin/java -version`
    echo "CLASSPATH=${CLASSPATH}"
   echo
   echo "APP_HOME=$APP_HOME"
   echo "APP_MAINCLASS=$APP_MAINCLASS"
   echo "****************************"
}
###################################
#读取脚本的第一个参数($1),进行判断
#参数取值范围:{start|stop|restart|status|info}
#如参数不在指定范围之内,则打印帮助信息
###################################
case "$1" in
   'start')
      start
      ;;
   'stop')
     stop
     ;;
   'restart')
     stop
     start
     ;;
   'status')
     status
     ;;
   'info')
     info
     ;;
  *)
     echo "Usage: $0 {start|stop|restart|status|info}"
     exit 1
esac
exit 0


本来的思路是 通过连接hbase 创建表然后put几条数据进去的方式,如果成功,则说明连接OK。但是dont know why ,调整了很多次,已经是卡在 HBaseAdmin hBaseAdmin = new HBaseAdmin(configuration);

但是没有报错…


调整思路: 手工在hbase中建表,手工插入几条数据,然后让应用去获取数据,果然可以获取到,精神病人思路广啊…


通过hbase shell命令 进入 hbase,然后逐一执行以下脚本

主要是 建个表,然后写入几条模拟数据,让应用去获取一下。

create 'xxx_monitor','m_id','address','info'
put'xxx_monitor','monitor','info:age','24'
put'xxx_monitor','monitor','info:birthday','2015-12-09'
put'xxx_monitor','monitor','info:company','ccccc'
put'xxx_monitor','monitor','address:contry','china' 
put'xxx_monitor','monitor','address:province','aaaaaa' 
put'xxx_monitor','monitor','address:city','bbbbb' 


tableName : xxx_monitor

核心代码如下:

  /**
   * 显示所有数据
   */
  public static void QueryAll(String tableName) {
    logger.info( "开始显示所有数据");
    HTablePool pool = new HTablePool(configuration, 100);
    HTableInterface table = (HTableInterface) pool.getTable(tableName);
    try {
      ResultScanner rs = table.getScanner(new Scan());
      for (Result r : rs) {
        logger.info("获得到rowkey:" + new String(r.getRow()));
        for (KeyValue keyValue : r.raw()) {
          logger.info("列族:" + new String(keyValue.getFamily()) + " 列:" + new String(keyValue.getQualifier())
              + "====值:" + new String(keyValue.getValue()));
        }
      }
    } catch (IOException e) {
      deadTimes++;
      errInfo = e.getMessage();
      logger.info(e.getMessage(), e);
    }
    logger.info("**************************显示所有数据结束*******************************************");
  }



通过静态代码块 初始化Hbase连接信息,就不用加载hbase-site.xml等配置文件了。 通过连接zk,(三个节点),将hbase托管给zk去管理。

/**
   * 静态代码块,类初始化的时候,仅加载一次
   */
  static {
    logger.info("Hbase配置开始初始化........");
    configuration = HBaseConfiguration.create();
    configuration.set("hbase.zookeeper.quorum", "10.4.10.AAAA,10.4.10.BBBB,10.4.10.CCCCC");
    configuration.set("hbase.zookeeper.property.clientPort", "2181");
    logger.info("Hbase配置初始化成功........");
  }


定时任务是通过ScheduledExecutorService 实现

  public static void main(String[] args) {
    Runnable runnable = new Runnable() {
      public void run() {
        if (deadTimes < 3) {
          logger.info("开始检测....");
          // 建表
          // creatTable(tablename);
          // 添加数据
          // insertData(tablename);
          // 查询数据
          QueryAll(tablename);
        } else {
          // 发送短信 如果未恢复,肯定逼逼的又是一堆,如果恢复了,则正常。
          logger.info("超过三次-----" + deadTimes);
          WarnMessage.senMessage(errInfo);
          deadTimes = 0;
        }
      }
    };
    // 调度
    ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
    // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间 ,第四个参数为单位
    service.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.MINUTES);
  }



启动脚本

#!/bin/sh
#
#该脚本为Linux下启动java程序的通用脚本。即可以作为开机自启动service脚本被调用,
#也可以作为启动java程序的独立脚本来使用。
#
#Author: tudaxia.com, Date: 2011/6/7
#
#警告!!!:该脚本stop部分使用系统kill命令来强制终止指定的java程序进程。
#在杀死进程前,未作任何条件检查。在某些情况下,如程序正在进行文件或数据库写操作,
#可能会造成数据丢失或数据不完整。如果必须要考虑到这类情况,则需要改写此脚本,
#增加在执行kill命令前的一系列检查。
# 
###################################
# 以下这些注释设置可以被chkconfig命令读取 
# chkconfig: - 99 50 
# description: Java程序启动脚本 
# processname: test 
# config: 如果需要的话,可以配置 
################################### 
#
###################################
#环境变量及程序执行参数
#需要根据实际环境以及Java程序名称来修改这些参数
###################################
#JDK所在路径
JAVA_HOME="/usr/java/jdk"
#执行程序启动所使用的系统用户,考虑到安全,推荐不使用root帐号
RUNNING_USER=root
#Java程序所在的目录(classes的上一级目录)
APP_HOME=/opt/tudaxia/test/WEB-INF
#需要启动的Java主程序(main方法类)
APP_MAINCLASS=com.tudaxia.test.TestMain
#拼凑完整的classpath参数,包括指定lib目录下所有的jar
CLASSPATH=$APP_HOME/classes
for i in "$APP_HOME"/lib/*.jar; do
   CLASSPATH="$CLASSPATH":"$i"
done
#java虚拟机启动参数
JAVA_OPTS="-ms512m -mx512m -Xmn256m -Djava.awt.headless=true -XX:MaxPermSize=128m"
###################################
#(函数)判断程序是否已启动
#
#说明:
#使用JDK自带的JPS命令及grep命令组合,准确查找pid
#jps 加 l 参数,表示显示java的完整包路径
#使用awk,分割出pid ($1部分),及Java程序名称($2部分)
###################################
#初始化psid变量(全局)
psid=0
checkpid() {
   javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAINCLASS`
   if [ -n "$javaps" ]; then
      psid=`echo $javaps | awk '{print $1}'`
   else
      psid=0
   fi
}
###################################
#(函数)启动程序
#
#说明:
#1. 首先调用checkpid函数,刷新$psid全局变量
#2. 如果程序已经启动($psid不等于0),则提示程序已启动
#3. 如果程序没有被启动,则执行启动命令行
#4. 启动命令执行后,再次调用checkpid函数
#5. 如果步骤4的结果能够确认程序的pid,则打印[OK],否则打印[Failed]
#注意:echo -n 表示打印字符后,不换行
#注意: "nohup 某命令 >/dev/null 2>&1 &" 的用法
###################################
start() {
   checkpid
   if [ $psid -ne 0 ]; then
      echo "================================"
      echo "warn: $APP_MAINCLASS already started! (pid=$psid)"
      echo "================================"
   else
      echo -n "Starting $APP_MAINCLASS ..."
      JAVA_CMD="nohup $JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS >/dev/null 2>&1 &"
      su - $RUNNING_USER -c "$JAVA_CMD"
      checkpid
      if [ $psid -ne 0 ]; then
         echo "(pid=$psid) [OK]"
      else
         echo "[Failed]"
      fi
   fi
}
###################################
#(函数)停止程序
#
#说明:
#1. 首先调用checkpid函数,刷新$psid全局变量
#2. 如果程序已经启动($psid不等于0),则开始执行停止,否则,提示程序未运行
#3. 使用kill -9 pid命令进行强制杀死进程
#4. 执行kill命令行紧接其后,马上查看上一句命令的返回值: $?
#5. 如果步骤4的结果$?等于0,则打印[OK],否则打印[Failed]
#6. 为了防止java程序被启动多次,这里增加反复检查进程,反复杀死的处理(递归调用stop)。
#注意:echo -n 表示打印字符后,不换行
#注意: 在shell编程中,"$?" 表示上一句命令或者一个函数的返回值
###################################
stop() {
   checkpid
   if [ $psid -ne 0 ]; then
      echo -n "Stopping $APP_MAINCLASS ...(pid=$psid) "
      su - $RUNNING_USER -c "kill -9 $psid"
      if [ $? -eq 0 ]; then
         echo "[OK]"
      else
         echo "[Failed]"
      fi
      checkpid
      if [ $psid -ne 0 ]; then
         stop
      fi
   else
      echo "================================"
      echo "warn: $APP_MAINCLASS is not running"
      echo "================================"
   fi
}
###################################
#(函数)检查程序运行状态
#
#说明:
#1. 首先调用checkpid函数,刷新$psid全局变量
#2. 如果程序已经启动($psid不等于0),则提示正在运行并表示出pid
#3. 否则,提示程序未运行
###################################
status() {
   checkpid
   if [ $psid -ne 0 ];  then
      echo "$APP_MAINCLASS is running! (pid=$psid)"
   else
      echo "$APP_MAINCLASS is not running"
   fi
}
###################################
#(函数)打印系统环境参数
###################################
info() {
   echo "System Information:"
   echo "****************************"
   echo `head -n 1 /etc/issue`
   echo `uname -a`
   echo
   echo "JAVA_HOME=$JAVA_HOME"
   echo `$JAVA_HOME/bin/java -version`
   echo
   echo "APP_HOME=$APP_HOME"
   echo "APP_MAINCLASS=$APP_MAINCLASS"
   echo "****************************"
}
###################################
#读取脚本的第一个参数($1),进行判断
#参数取值范围:{start|stop|restart|status|info}
#如参数不在指定范围之内,则打印帮助信息
###################################
case "$1" in
   'start')
      start
      ;;
   'stop')
     stop
     ;;
   'restart')
     stop
     start
     ;;
   'status')
     status
     ;;
   'info')
     info
     ;;
  *)
     echo "Usage: $0 {start|stop|restart|status|info}"
     exit 1
esac
exit 0


shell启动jar包


2019-03更新


20190403094145860.png


脚本如下,修改Java路径和jar包路径即可

#!/bin/bash
# 修改1:设置自己的Java路径  或者 source某个外部文件 
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64/jre/bin/java
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
#修改2: 自己Jar包的路径  
APP_NAME=/root/artisan4Nginx-0.0.1-SNAPSHOT.jar
# 其余无需修改,直接用即可
#使用说明,用来提示输入参数
usage() {
echo "Usage: sh startup.sh [start|stop|restart|status]"
exit 1
}
#检查程序是否在运行
is_exist(){
pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
#如果不存在返回1,存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
#启动方法
start(){
is_exist
if [ $? -eq 0 ]; then
echo "${APP_NAME} is already running. pid=${pid}"
else
nohup java -jar ${APP_NAME} >startup.out 2>&1 &
echo "${APP_NAME} is started."
fi
}
#停止方法
stop(){
is_exist
if [ $? -eq "0" ]; then
kill -9 $pid
else
echo "${APP_NAME} is not running"
fi
}
#输出运行状态
status(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is running. Pid is ${pid}"
else
echo "${APP_NAME} is NOT running."
fi
}
#重启
restart(){
stop
sleep 5
start
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac



如果是通过yum安装的java,要找到具体的安装路径可以参考如下方式

[root@artisan ~]# whereis java
java: /usr/bin/java /usr/lib/java /etc/java /usr/share/java /usr/share/man/man1/java.1.gz
# 找到软连接
[root@artisan ~]# ls -ltr /usr/bin/java
lrwxrwxrwx. 1 root root 22 Apr  2 22:46 /usr/bin/java -> /etc/alternatives/java
# 安装路径
[root@artisan ~]# ls -ltr /etc/alternatives/java
lrwxrwxrwx. 1 root root 73 Apr  2 22:46 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64/jre/bin/java
[root@artisan ~]# 


然后再/etc/profile 添加

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64/jre/bin/java
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

最后记得 source /etc/profile 或者 . /etc/profile 使其生效【. 后面有空格,注意下】

记得给脚本赋予可执行的权限 chmod +x startup.sh

使用

[root@artisan ~]# ./startup.sh usage
Usage: sh startup.sh [start|stop|restart|status]
[root@artisan ~]# ./startup.sh start
/root/artisan4Nginx-0.0.1-SNAPSHOT.jar is started.
[root@artisan ~]# ./startup.sh status
/root/artisan4Nginx-0.0.1-SNAPSHOT.jar is running. Pid is 19180
[root@artisan ~]# ./startup.sh start
/root/artisan4Nginx-0.0.1-SNAPSHOT.jar is already running. pid=19180
[root@artisan ~]# ./startup.sh restart
/root/artisan4Nginx-0.0.1-SNAPSHOT.jar is started.
[root@artisan ~]# ./startup.sh stop
[root@artisan ~]# ./startup.sh status
/root/artisan4Nginx-0.0.1-SNAPSHOT.jar is NOT running.
[root@artisan ~]# 


相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
&nbsp; 相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情:&nbsp;https://cn.aliyun.com/product/hbase &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
17天前
|
Shell Linux 测试技术
6种方法打造出色的Shell脚本
6种方法打造出色的Shell脚本
38 2
6种方法打造出色的Shell脚本
|
10天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
45 4
|
20天前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
42 17
|
14天前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
23 2
|
18天前
|
数据采集 分布式计算 Java
Kettle的Java开发环境需要什么jar包?
【10月更文挑战第24天】Kettle的Java开发环境需要什么jar包?
62 2
|
22天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
15 2
|
22天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
15 1
|
16天前
|
Java Spring
JAVA获取重定向地址URL的两种方法
【10月更文挑战第17天】本文介绍了两种在Java中获取HTTP响应头中的Location字段的方法:一种是使用HttpURLConnection,另一种是使用Spring的RestTemplate。通过设置连接超时和禁用自动重定向,确保请求按预期执行。此外,还提供了一个自定义的`NoRedirectSimpleClientHttpRequestFactory`类,用于禁用RestTemplate的自动重定向功能。
|
1月前
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
75 1
|
3天前
|
XML JSON 监控
Shell脚本要点和难点以及具体应用和优缺点介绍
Shell脚本在系统管理和自动化任务中扮演着重要角色。尽管存在调试困难、可读性差等问题,但其简洁高效、易于学习和强大的功能使其在许多场景中不可或缺。通过掌握Shell脚本的基本语法、常用命令和函数,并了解其优缺点,开发者可以编写出高效的脚本来完成各种任务,提高工作效率。希望本文能为您在Shell脚本编写和应用中提供有价值的参考和指导。
12 1