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行

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

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

%JAVA% %JAVA_OPTS% -cp %CLASSPATH% org.logstash.Logstash %*
pause
echo %JAVA% >>a.txt
echo " " >>a.txt
echo %JAVA_OPTS%>>a.txt
echo " " >>a.txt
echo %CLASSPATH%>>a.txt
echo " " >>a.txt
echo %*>>a.txt
echo " " >>a.txt
echo "%CLASSPATH%" >>a.txt
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.

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

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

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

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

:concat
IF not defined CLASSPATH (
set CLASSPATH="%~1"
) ELSE (
set CLASSPATH=%CLASSPATH%;"%~1"
)

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

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

很容易懂的一个循环,对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. Oracle EBS 快捷键

    打开菜单 Help > Keyboard Help... 功能                         快捷键 =================================== 1 ...

  2. C#基础入门 八

    C#基础入门 八 泛型 C#中的泛型能够将类型作为参数来传递,即在创建类型时用一个特定的符号,如"T"来作为一个占位符,代替实际的类型,等待实例化时用一个实际的类型来代替. pub ...

  3. 七、linux目录结构知识---实战

    1.企业面试题:一个100M的磁盘分区,分别写入1k文件,及写入1M的文件,分别可以写多少个? 一块磁盘被分区格式化成系统文件后,有Inode和Block:一个文件一般占用一个Inode和一个Bloc ...

  4. kvm快照备份及常用命令

    转载自:http://www.myjishu.com/?p=431 好文章 kvm快照备份及常用命令 kvm快照,分两种: 1种lvm快照,如果分区是lvm,可以利用lvm进行kvm的快照备份 2种由 ...

  5. django 模型 使用 DateTimeFields 字段 auto_now_add 属性 实现 插入数据时 自动记录时间

    class MyModel(models.Model): user_name = models.CharField() created = models.DatedTimeField(auto_now ...

  6. Word2007文档中怎么输入上标下标

    1.Word中输出Z = X2 + Y2 此公式流程: 首先在Word中写入:Z = X2 + Y2: 方法1:选中X后面的2,再按组合键“Ctrl+Shift+加号键”即可,如此操作Y后面的2即可.

  7. 护网杯圆满结束,还不满足?不如来看看大佬的WP扩展思路~

    护网杯预选赛 WP转载自:https://qingchenldl.github.io/2018/10/13/%E6%8A%A4%E7%BD%91%E6%9D%AFWP-BitPwn/#more WEB ...

  8. 实时监测input输入变化 jQuery

    $('#production_name').on('input propertychange',function(){ alert('输入一个字弹一回'); });

  9. redis cluster 的ERR max number of clients reached 问题排查

    早上发现微服务连不上redis cluster了,看来下日志如下 [root@win-jrh378d7scu 7005]# bin/redis-cli -c -h 15.31.213.183 -p 7 ...

  10. 【JVM】jvm启动参数

    -server -Xmx2048m -Xms1500m -Xmn1024m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConc ...