logstash 启动报无法找到主类解决方案

Zparkle 关注

2018.03.08 22:04* 字数 2051 阅读 1评论 0喜欢 0

当logstash启动时,首先要注意正确配置java

并且最近版本的logstash要求java8

在搞定以上后确认环境变量没有问题

再确认logstash所在的目录 不存在含有空格的文件夹名称

在这所有所有之后还是会报错:找不到或无法加载主类 (乱序地址)

解决方案

废话不多说:找到logstash/bin目录下的logstash.bat
打开编辑,找到如下行
%JAVA% %JAVA_OPTS% -cp "%CLASSPATH%" org.logstash.Logstash %*
这行与你的应该有所区别,没错

将%CLASSPATH%改为"%CLASSPATH%"即可解决

让我学习一下批处理写法 理解一下这行为什么这样,之后,有空再解释原因


2018年3月9日17:19:19更新

产生原因

PS G:\Users\XXX\Desktop> ./logstash.bat
错误: 找不到或无法加载主类 Files\Java\jdk1.8.0_161\lib;G:"Program

以上是错误命令运行的输出 可以看到 找不到或无法加载主类,而后跟着的目录为

Files\Java\jdk1.8.0_161\lib;G:"Program

因为我的jdk 放在G:\Program Files\java\jdk1.8.0_161\lib下了,因此一开始百思不得其解,什么错误会产生位置字符串中间截断然后颠倒这种迷之错误。

因为logstash启动文件是个批处理,这样调试起来就很方便在,在各行插入pause语句调试,最后将错误定位到52行

  1. %JAVA% %JAVA_OPTS% -cp %CLASSPATH% org.logstash.Logstash %*

今天学习了一下批处理语法,这一句无非是将一些变量组合成为新的语句再执行而已,那么错误不在批处理程序,因为自己再写批处理的话难保拿到的变量与运行时完全一样所以直接在logstash.bat中插入了一些语句将其输出(因为没那么多时间阅读全文,前面已经提到了直接定位到了出错是这一句)

  1. %JAVA% %JAVA_OPTS% -cp %CLASSPATH% org.logstash.Logstash %*
  2. pause
  3. echo %JAVA% >>a.txt
  4. echo " " >>a.txt
  5. echo %JAVA_OPTS%>>a.txt
  6. echo " " >>a.txt
  7. echo %CLASSPATH%>>a.txt
  8. echo " " >>a.txt
  9. echo %*>>a.txt
  10. echo " " >>a.txt
  11. echo "%CLASSPATH%" >>a.txt
  12. pause

将上面的语句改写成这样,将变量全部输出到a.txt,检查该文件

"G:\Program Files\Java\jdk1.8.0_161\bin\java.exe"

-Xms1------很长的字符串------/urandom

.;G:\Program Files\Java\jdk1.8.0_161\lib;G:\Program Files\Java\jdk1.8.0_161\lib\tools.jar;"E:\logstash-6.2.2\logstash-core\lib\jars\animal-sniffer-annotations-1.14.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\commons-compiler-3.0.8.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\error_prone_annotations-2.0.18.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\google-java-format-1.5.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\guava-22.0.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\j2objc-annotations-1.1.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\jackson-annotations-2.9.1.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\jackson-core-2.9.1.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\jackson-databind-2.9.1.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\jackson-dataformat-cbor-2.9.1.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\janino-3.0.8.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\javac-shaded-9-dev-r4023-3.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\jruby-complete-9.1.13.0.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\jsr305-1.3.9.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\log4j-api-2.9.1.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\log4j-core-2.9.1.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\log4j-slf4j-impl-2.9.1.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\logstash-core.jar";"E:\logstash-6.2.2\logstash-core\lib\jars\slf4j-api-1.7.25.jar"

-f ../config/pipeline.conf

抱歉我知道上面这坨太冗杂了但是相信我,比较重要吧。
观察上面这些输出,再结合logstash.bat中的实际语序,可以发现这实际上是一句简单的java程序启动的cmd.

  1. java -opt1 -opt2 -cp "classpath" org.logstash.Logstash -f ../config/pipeline.conf

那么到这一步 再结合错误输出为找不到或无法加载主类,可以猜测是-cp 之后的classpath出现了问题。
仔细观察classpath,发现一些问题,该字符串明显为拼接字符串,然而有些地址用双引号("")括起来了,有些没有。再观察,可以发现括起来的为logstash自己的jar包,没有的则为系统本身的CLASSPATH环境变量的值。

猜测由双引号引起该问题,再加上前面的解决方案是在整个%CLASSPATH%变量外面加 "" 可以猜测为系统本身的CLASSPATH没有加上双引号引起的,按照他的style将双引号加在每个地址上,问题解决

继续研究。回到logstash/bat文件,发现

  1. :concat
  2. IF not defined CLASSPATH (
  3. set CLASSPATH="%~1"
  4. ) ELSE (
  5. set CLASSPATH=%CLASSPATH%;"%~1"
  6. )

很明显 该代码段产生了整个批处理文件中实际调用的CLASSPATH
调用该代码段的地方是

  1. for %%i in ("%LS_HOME%\logstash-core\lib\jars\*.jar") do (
  2. call :concat "%%i"
  3. )

很容易懂的一个循环,对logstash目录下的\logstash-core\lib\jars\下的所有jar包循环,将包名作为参数执行上上的那个代码段,即
将logstash jar包目录下的所有jar包的所在路径连接到系统本身的CLASSPATH路径之后
那么到此CLASSPATH的产生方式已经很明显了,错误也很明显了,产生CLASSPATH时,因为系统中有CLASSPATH变量因此直接执行ELSE部分,将系统变量通过 "%CLASSPATH%" 的方式直接读取,在之后加上;"%~1"
这里%~1的作用是取第一个参数并去掉双引号,第一个参数是循环的当时系数,而去掉双引号之后又加上了双引号所以最后的结果是有双引号的,这也就是我们看到的 调用的CLASSPATH后面的logstash的包都有双引号的原因。而在循环第一次执行的时候,直接用了系统的%CLASSPATH%这里是没有双引号的,因此结果也没有(不能在这里加双引号,因为随着循环,引号会被递归加上,整个路径会乱掉

这里有一个另外的思考,前面的输出a.txt文件可以看到,直接用%JAVA%输出的java.exe所在目录实际上竟然是有双引号的,而我自己写了个批处理 "echo %JAVA%显示的是echo 开关状态,证明找不到JAVA这个系统变量,这是显然的,但是我在logstash.bat中竟然没有找到对变量JAVA的set操作,也就是说找不到这个JAVA地址是在何处获得并赋值的,也就无法研究java.exe的路径为何是有双引号的。

重要的解释

我认为还需要解释一下为什么不加引号就会炸,大家还记得最开始的错误输出吧

PS G:\Users\XXX\Desktop> ./logstash.bat
错误: 找不到或无法加载主类 Files\Java\jdk1.8.0_161\lib;G:"Program

这其实并不是地址断掉了或者说倒置了,而是Program FIile 中间有一个空格,批处理文件以空格作为分格符,由于我的jdk放置在系统盘的program file文件夹下,因此我的环境变量的classpath中有两个包含空格的路径,批处理命令将第一个空格前的内容作为java -cp命令中的classpath地址传入, 后两个空格间的"Files\Java\jdk1.8.0_161\lib;G:"Program"自然就作为主类传入了,因此产生了如此奇怪的输出。而解决空格的方法就是:

logstash 启动报找不主类或无法加载 java的更多相关文章

  1. SpringBoot项目找不到主类或无法加载主类

    问题描述 启动springboot项目的时候发现启动失败,查看日志发现因为找不到主类或无法加载主类. 解决 我这个项目是拉取的别人git上的项目,看了一下目录结构发现没有编译后的文件(target目录 ...

  2. java -jar jar包,运行报错没有主清单和无法加载主类

    jar: 包名(class 文件) META-INF(MANIFEST.MF ) .classpath 1.从eclipse直接导出的jar包: 2.修改MANIFEST.MF文件:

  3. Java_类文件及加载机制

    类文件及类加载机制 标签(空格分隔): Java 本篇博客的重点是分析JVM是如何进行类的加载的,但同时我们会捎带着说一下Class类文件结构,以便对类加载机制有更深的理解. 类文件结构 平台无关性 ...

  4. Java类编译、加载、和执行机制

    Java类编译.加载.和执行机制 标签: java 类加载 类编译 类执行 机制 0.前言 个人认为,对于JVM的理解,主要是两大方面内容: Java类的编译.加载和执行. JVM的内存管理和垃圾回收 ...

  5. 《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?

    Java虚拟机是如何加载Java类的?  这个问题也就是面试常问到的Java类加载机制.在年初面试百战之后,菜鸟喜鹊也是能把这流程倒背如流啊!但是,也只是字面上的背诵,根本就是像上学时背书考试一样. ...

  6. JAVA类的静态加载和动态加载以及NoClassDefFoundError和ClassNotFoundException

    我们都知道Java初始化一个类的时候可以用new 操作符来初始化, 也可通过Class.forName()的方式来得到一个Class类型的实例,然后通过这个Class类型的实例的newInstance ...

  7. Yaf零基础学习总结5-Yaf类的自动加载

    Yaf零基础学习总结5-Yaf类的自动加载 框架的一个重要功能就是类的自动加载了,在第一个demo的时候我们就约定自己的项目的目录结构,框架就基于这个目录结构来自动加载需要的类文件. Yaf在自启动的 ...

  8. java动态编译类文件并加载到内存中

    如果你想在动态编译并加载了class后,能够用hibernate的数据访问接口以面向对象的方式来操作该class类,请参考这篇博文-http://www.cnblogs.com/anai/p/4270 ...

  9. java动态加载类和静态加载类笔记

    JAVA中的静态加载类是编译时刻加载类  动态加载类指的是运行时刻加载类 二者有什么区别呢 举一个例子  现在我创建了一个类  实现的功能假设为通过传入的参数调用具体的类和方法 class offic ...

随机推荐

  1. C#基础入门 五

    C#基础入门 五 递归 递归调用:一个方法直接或间接地调用了它本身,就称为方法的递归调用. 递归方法:在方法体内调用该方法本身. 递归示例 public long Fib(int n) { if(n= ...

  2. 转载:oracle 自定义类型 type / create type

    标签:type create oracle object record 一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarc ...

  3. Spring学习(六)——集成memcached客户端

    memcached是高性能的分布式内存缓存服务器.许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示. 但随着数据量的增大.访问的集中,就会出现RDBMS的负担加重.数据 ...

  4. C#——做一个简单代理IP池

    一.缘由. 抓取数据时,有一些网站 设置了一些反爬虫设置,进而将自己本地 IP 地址拉入系统黑名单.从而达到禁止本地 IP 访问数据的请求. 二.思路. 根据其他 代理 IP 网站,进行一个免费的代理 ...

  5. js实现window.open不被拦截的解决方法汇总

    一.问题: 今天在处理页面ajax请求过程中,想实现请求后打开新页面,就想到通过 js window.open 来实现,但是最终都被浏览器拦截了. 二.分析: 在谷歌搜索有没有解决方法,有些说可以通过 ...

  6. 如何进入PageAdmin CMS 安装界面

    一般下面几个应用场景如第一次使用PageAdmin配置参数.服务器迁移.主域名更换.忘记超级管理员密码等都可以在安装界面进行设置. 下面为PageAdmin安装步骤 1.地址栏输入:http://您的 ...

  7. 1270: Wooden Sticks [贪心]

    点击打开链接 1270: Wooden Sticks [贪心] 时间限制: 1 Sec 内存限制: 128 MB 提交: 31 解决: 11 统计 题目描述 Lialosiu要制作木棍,给n根作为原料 ...

  8. 常见的vue面试题

    001.v-show与v-if的区别v-show:操作的是元素的display属性 v-if:操作的是元素的创建和插入相比较而言v-show的性能要高 002.methods.computed.wat ...

  9. 《快学Scala》第三章 数组相关操作

  10. linux中rc.d目录下的文件

    参考 http://blog.sina.com.cn/s/blog_414d78870102vqj5.html http://www.360doc.com/content/12/0820/17/933 ...