zoukankan      html  css  js  c++  java
  • eclipse导出maven工程的可执行jar包

    一、eclipse导出maven工程的可执行jar包

    建立两个maven工程 ZKServer 和ZKClient

    注意:用maven进行开发管理的话,默认的打出来的jar包是不能运行的,需要在pom.xml文件中添加如下配置以生成可执行的jar包

    <build>
        <plugins>
          <plugin>
            <artifactId> maven-assembly-plugin </artifactId>
            <configuration>
              <descriptorRefs>
                <descriptorRef>zkServer</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.fanghao.AppServer</mainClass> 
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>

    而我们在eclipse中创建的工程默认的 JRE System Library 是 Java-SE-1.5 ,我们需要添加以下配置让其变成1.7或1.8,并且无论我们对该maven工程update多少次,都不会回到1.5

    <build>
        <plugins>

          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>

      </plugins>
    </build>

    ZKServer工程

    <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>com.fanghao</groupId>
      <artifactId>ZKServer</artifactId>
      <version>0.0.1-SNAPSHOT</version>

      <dependencies>
        <dependency>
          <groupId>org.apache.zookeeper</groupId>
          <artifactId>zookeeper</artifactId>
          <version>3.4.11</version>
        </dependency>
      </dependencies>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
          <plugin>
            <artifactId> maven-assembly-plugin </artifactId>
            <configuration>
              <descriptorRefs>
                <descriptorRef>zkServer</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.fanghao.AppServer</mainClass>
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </project>

    --------------------------------------------------------

    package com.fanghao;

    import java.util.concurrent.CountDownLatch;

    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.Watcher.Event.KeeperState;
    import org.apache.zookeeper.ZooDefs.Ids;

    /**
    * 某分布式系统中,主节点可以有多台,可以动态上下线;
    * 任意一台客户端都能实时感知到主节点服务器的上下线。
    */
    public class AppServer {
      private String groupNode = "sgroup";
      private String subNode = "sub";
      private CountDownLatch latch = new CountDownLatch(1);

      /**
      * 连接zookeeper
      * @param address server的地址
      */
      public void connectZookeeper(String address) throws Exception {
        ZooKeeper zk = new ZooKeeper("192.168.1.100:2181", 5000, new Watcher() {
          public void process(WatchedEvent event) {
            // 不做处理
            if(event.getState()==KeeperState.SyncConnected){
              latch.countDown();
            }
          }
        });
        // 在"/sgroup"下创建子节点
        // 子节点的类型设置为EPHEMERAL_SEQUENTIAL, 表明这是一个临时节点, 且在子节点的名称后面加上一串数字后缀
        // 将server的地址数据关联到新创建的子节点上
        latch.await();
        String createdPath = zk.create("/" + groupNode + "/" + subNode, address.getBytes("utf-8"),
            Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        System.out.println("create: " + createdPath);
      }

      /**
      * server的工作逻辑写在这个方法中
      * 此处不做任何处理, 只让server sleep
      */
      public void handle() throws InterruptedException {
        Thread.sleep(Long.MAX_VALUE);
      }

      public static void main(String[] args) {
        // 在参数中指定server的地址
        if (args.length == 0) {
          System.err.println("The first argument must be server address");
          System.exit(1);
        }

        AppServer as = new AppServer();
        try {
          as.connectZookeeper(args[0]);

          as.handle();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }

    ZKClient工程

    <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>com.fanghao</groupId>
      <artifactId>ZKClient</artifactId>
      <version>0.0.1-SNAPSHOT</version>

      <dependencies>
        <dependency>
          <groupId>org.apache.zookeeper</groupId>
          <artifactId>zookeeper</artifactId>
          <version>3.4.11</version>
        </dependency>
      </dependencies>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
          <plugin>
            <artifactId> maven-assembly-plugin </artifactId>
            <configuration>
              <descriptorRefs>
                <descriptorRef>zkClient</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.fanghao.AppClient</mainClass>
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </project>

    ------------------------------------------------------------------

    package com.fanghao;

    import java.util.ArrayList;
    import java.util.List;

    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.Watcher.Event.EventType;
    import org.apache.zookeeper.data.Stat;

    /**
    * 某分布式系统中,主节点可以有多台,可以动态上下线;
    * 任意一台客户端都能实时感知到主节点服务器的上下线。
    * Created by tianjun on 2016/12/19 0019.
    */
    public class AppClient {
      private String groupNode = "sgroup";
      private ZooKeeper zk;
      private Stat stat = new Stat();
      private volatile List<String> serverList;

      /**
      * 连接zookeeper
      */
      public void connectZookeeper() throws Exception {
        zk = new ZooKeeper("127.0.0.1:2181", 5000, new Watcher() {
            public void process(WatchedEvent event) {
              // 如果发生了"/sgroup"节点下的子节点变化事件, 更新server列表, 并重新注册监听
              if (event.getType() == EventType.NodeChildrenChanged
                  && ("/" + groupNode).equals(event.getPath())) {
                try {
                  updateServerList();
                } catch (Exception e) {
                  e.printStackTrace();
                }
              }
            }
        });

        updateServerList();
      }

      /**
      * 更新server列表
      */
      private void updateServerList() throws Exception {
        List<String> newServerList = new ArrayList<String>();

        // 获取并监听groupNode的子节点变化
        // watch参数为true, 表示监听子节点变化事件.
        // 每次都需要重新注册监听, 因为一次注册, 只能监听一次事件, 如果还想继续保持监听, 必须重新注册
        List<String> subList = zk.getChildren("/" + groupNode, true);
        for (String subNode : subList) {
          // 获取每个子节点下关联的server地址
          byte[] data = zk.getData("/" + groupNode + "/" + subNode, false, stat);
          newServerList.add(new String(data, "utf-8"));
        }

        // 替换server列表
        serverList = newServerList;

        System.out.println("server list updated: " + serverList);
      }

      /**
      * client的工作逻辑写在这个方法中
      * 此处不做任何处理, 只让client sleep
      */
      public void handle() throws InterruptedException {
        Thread.sleep(Long.MAX_VALUE);
      }

      public static void main(String[] args) throws Exception {
        AppClient ac = new AppClient();
        ac.connectZookeeper();

        ac.handle();
      }

    }

    右键待导出的maven工程-> Export -> Java -> Runnable JAR file,单击next

    注意:如果 Launch Configuration:下面没有工程对应的main方法所在的类或者什么都没有,说明该类没有在eclipse中执行过,只需要将该类执行一次即可;

              如果 Launch Configuration:下面的类太多了,可以将其清空,方法为删除当前workspace对应的目录下的 .metadata.pluginsorg.eclipse.debug.core.launches 目录下的内             容,注意是删除workspace对应的目录下的 .metadata.pluginsorg.eclipse.debug.core.launches 目录下的内容,不是删除该目录

    二、在Windows系统下执行可执行jar包

    打开cmd命令行窗口,切换到导出的可执行jar包所在的目录,执行命令  java -jar xxx.jar [arg0] [arg1] [...]

    其中 xxx.jar 是可执行jar包的名字,后面可传入零或多个参数

    三、在Linux系统下执行可执行jar包(亦可叫做启动或停止java应用程序)

     1、检查jdk是否已经安装在Ubuntu上

    打开终端,使用下面的命令:java -versio

    如果你看到像下面的输出,这就意味着你并没有安装过Jdk:

    The program ‘java’ can be found in the following packages:
    *default-jre
    * gcj-4.6-jre-headless
    * openjdk-6-jre-headless
    * gcj-4.5-jre-headless
    * openjdk-7-jre-headless
    Try: sudo apt-get install

    2、在Ubuntu上安装jdk

    (1)下载jdk-8u161-linux-x64.tar.gz,直接用鼠标拖放到Ubuntu的桌面文件夹里,然后复制到在/usr/soft(如果没有请新建)目录下,解压后删除jdk-8u161-linux-x64.tar.gz

    (2)配置java环境变量,配置在/etc/environment文件中

    执行命令 gedit /etc/environment 打开/etc/environment文件的编辑窗口,配置JAVA_HOME,CLASSPATH和PATH,如下

    JAVA_HOME="/usr/soft/jdk1.8.0_161"
    CLASSPATH=".:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar"
    PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:$JAVA_HOME/bin:$HADOOP_INSTALL/bin"

    (3)保存后执行 source  /etc/environment 使其立即生效,执行 java -version 命令检查配置是否成功

    3、执行可执行jar包

    将可执行jar包拖放到某个目录,然后切换到该目录,直接执行命令  java -jar xxx.jar [arg0] [arg1] [...]

    其中 xxx.jar 是可执行jar包的名字,后面可传入零或多个参数,也可编写启动停止的shell脚本,如下是一个通用shell脚本

    #!/bin/sh

    #JDK所在目录
    JAVA_HOME="/usr/soft/jdk1.8.0_161"


    #执行程序启动所使用的系统用户,考虑到安全,不推荐使用root用户
    RUNNING_USER=root


    #Java程序所在的目录(classes的上一级目录)
    APP_HOME=/opt/xxx/WEB-INF


    #需要启动的Java主程序(main方法所在类)
    APP_MAINCLASS=com.fanghao.Main


    #拼凑完整的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) [Successfully started]"
        else
          echo "[Failed to start]"
        fi
      fi
    }

    ########################################
    #(函数)停止程序
    #说明:
    #1、首先调用checkpid函数,刷新$psid全局变量
    #2、如果程序已经启动($psid不等于0),则开始执行停止,否则提示程序未运行
    #3、使用kill -9 pid命令强制杀死进程
    #4、执行kill命令后,马上查看上一句命令的返回值:$?
    #5、如果步骤4的结果$?等于0,则打印[Successfully stopped],否则打印[Failed to stop]
    #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 "[Successfully stopped]"
        else
          echo "[Failed to stop]"
        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,否则提示程序未运行
    ########################################
    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

  • 相关阅读:
    用Photoshop设计网站的70个教程
    反射引发的错误“reflection Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.”
    机械键盘理解的几个误区和保养方法
    Asp.Net MVC中不指定View Name时如何返回ActionResult的
    [通告]Nuget服务宕机,出现 503 Server Unavailable 错误无法编译及解决方法
    MVC标签链接切换帮助类: TabLink
    [Centos 6.2] centos 6.2(64位)网络配置
    Linux(Ubuntu)设置环境变量(转载)
    COPYONWRITE 原理
    [Linux 技巧] linux screen 命令详解
  • 原文地址:https://www.cnblogs.com/jiangwangxiang/p/8596785.html
Copyright © 2011-2022 走看看