简体   繁体   English

Java应用程序在Eclipse上工作正常,但在部署为可运行的jar后它无法正常工作

[英]a Java application works fine on Eclipse but it doesn't work properly after being deployed as a runnable jar

Like the tile said, my Java application doesn't work as it works fine while developing on Eclipse. 就像瓷砖说的那样,我的Java应用程序不起作用,因为它在Eclipse上开发时工作正常。

I finished to build and test my application on Eclipse. 我完成了在Eclipse上构建和测试我的应用程序。 It works fine as I expected. 它按照我的预期正常工作。 I needed to deploy it as a runnable jar so that my client can't use it on their system. 我需要将其部署为可运行的jar,以便我的客户端无法在其系统上使用它。 I made it a runnable jar through exporting it on Eclipse. 我通过在Eclipse上导出它使它成为一个可运行的jar。 When I run the runnable jar, the application starts to work fine for a while and stops on file reading. 当我运行可运行的jar时,应用程序开始正常工作一段时间并停止文件读取。 I haven't had any problem with it on the same code on Eclipse. 我对Eclipse上的相同代码没有任何问题。

The source snippet that seems not to work is the following. 似乎不起作用的源代码段如下。

            sfis = new SmbFileInputStream(sFile);
            in = new BufferedInputStream(sfis);

            byte buf[] = new byte[(int)sFile.length()];
            int pos = 0;
            int size = 10;
            int temp;

            while((size=in.read(buf, pos, size)) > 0){
                pos += size; 
                temp = buf.length - pos;
                if(temp < 10){
                    size = temp;
                }
            }

On Eclipse it doesn't cause any problem. 在Eclipse上它不会导致任何问题。 It perfectly reads data from SMB connection and finishes its job. 它完美地从SMB连接读取数据并完成其工作。 But from the jar application, it seems to stop reading from inputstream inside while loop at some point. 但是从jar应用程序中,似乎在某些时候停止从输入流内部读取循环。 This is a very strange case that I have never experienced before. 这是一个我从未经历过的非常奇怪的案例。 And I can't find any solution for this. 我找不到任何解决方案。

Is this because of my code or the jar file that might be wrongly made by Eclipse? 这是因为我的代码还是可能由Eclipse错误制作的jar文件?

---------- additional info ------------------- - - - - - 附加信息 - - - - - - - - - -

With a big help from Edmondo1984, I find out where the jar program stops. 在Edmondo1984的大力帮助下,我找到了jar程序停止的位置。 When it goes to inputstream from SmbFile, a new thread jcifs.util.transport.Transport is created and the thread is simply blocked and the application creates another jcifs.util.transport.Transport, and so on. 当它从SmbFile转到inputstream时,会创建一个新线程jcifs.util.transport.Transport,并且只是阻塞该线程,并且应用程序会创建另一个jcifs.util.transport.Transport,依此类推。 After creating 8 or 9 jcifs.util.transport.Transport thread, it is being stuck and doing nothing. 在创建8或9个jcifs.util.transport.Transport线程后,它被卡住并且什么都不做。

The same code, the same jcifs library. 相同的代码,相同的jcifs库。 But works differently between running on Eclipse and on local machine as a runnable jar. 但在Eclipse和本地机器上运行作为可运行的jar之间的工作方式不同。 I have no idea why this is happening. 我不知道为什么会这样。

The return value for "there is nothing more on the stream" is -1 (see Javadoc ). “流上没有其他内容”的返回值为-1 (请参阅Javadoc )。

Imagine what happens if you try to in.read(buf, pos, size) but the underlying is still not available. 想象一下如果你尝试in.read(buf, pos, size)会发生什么in.read(buf, pos, size)但底层仍然不可用。 Then the call immediately returns with a return value of 0 (zero). 然后调用立即返回,返回值为0 (零)。 This way, the loop condition evaluates to false and the loop is exited. 这样,循环条件的计算结果为false,并退出循环。 So I think you should compare against != -1 . 所以我认为你应该比较!= -1

Another possible issue: You may also consider what happens if size = 0 (eg due to above scenario) and temp >= 10 . 另一个可能的问题:您还可以考虑如果size = 0 (例如由于上述情况)和temp >= 10会发生什么。 Because you directly feed back the value of size to in.read(buf, pos, size) as the maximum number of bytes to read, you could end up in an infinite loop, assuming you have already corrected the comparison to != -1 . 因为您直接将in.read(buf, pos, size)size值作为要读取的最大字节数反馈,所以假设您已经将比较更正为!= -1 ,则最终可能会进入无限循环!= -1

When meddling with streams, those kind of behaviors are frequent. 当干扰流时,这种行为是经常发生的。 Small algorithmic incorrections may cause different symptoms in different environments. 小算法不正确可能会在不同的环境中导致不同的症状。

You could print "debug" information to the console to better understand where and why is your code stalling. 您可以将“调试”信息打印到控制台,以便更好地了解代码停止的位置和原因。 I'm pretty sure its on the read method. 我很确定它的读取方法。

There are several things wrong with your code, the most notorious is the block: 您的代码有几个问题,最臭名昭着的是块:

temp = buf.length - pos;
if(temp < 10){
  size = temp;
}

Why? 为什么? When there are 10 or less bytes left you'll try to read them in the next read(), otherwise you'll potentially try to read too much (the whole file size again). 当剩下10个或更少的字节时,你会尝试在下一个read()中读取它们,否则你可能会尝试读取太多(再次调整整个文件大小)。 Running in Eclipse, the file is probably being read in the first read(), out of Eclipse apparently not. 在Eclipse中运行,文件可能正在第一次读取()中读取,而Eclipse中显然没有读取。 Try to change your code to something like this: 尝试将您的代码更改为以下内容:

FileInputStream sfis = new FileInputStream(sFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[4096];
int read = sfis.read(buf);
while(read>0){
  baos.write(buf, 0, read);
  read = sfis.read(buf);
}
sfis.close();

Also consider to use Apache's Java IO utilities code instead of always writing this type of code. 还要考虑使用Apache的Java IO实用程序代码,而不是总是编写这种类型的代码。 IO in Java needs a lot of boilerplate, and a good programmer has better things to do. Java中的IO需要很多样板,而优秀的程序员有更好的事情要做。

On a side-note: reading a file to memory is usually a bad idea. 旁注:将文件读入内存通常是个坏主意。 Unless you're going to transform its data as a whole in some way, streaming is always better. 除非你要以某种方式整体转换其数据,否则流式传输总是更好。 I don't know what is your program for but please keep this in mind: what happens if you try to read a 10GB file? 我不知道您的程序是什么,但请记住:如果您尝试读取10GB文件会发生什么? or several? 还是几个?

Happy coding, 快乐的编码,

Java is capital letter sensitive in evry way. Java以大写字母敏感。 For example if you have file named image.PNG and in your code you set location to "/image.png" (instead of "/image.PNG") it will work fine in eclipse, but after exporting runnable jar file java VM will be not able to find that file. 例如,如果您有名为image.PNG的文件,并且在您的代码中将位置设置为“/image.png”(而不是“/image.PNG”)它将在eclipse中正常工作,但在导出runnable jar文件之后java VM将无法找到该文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在运行时编译Java文件可在Eclipse上运行,但不能从导出的可运行jar文件中运行 - Compiling java file at runtime works on eclipse but doesn't work from an exported runnable jar file Java打开文件-在Eclipse上有效,在可运行的JAR / exe中不起作用 - Java opening files - works from Eclipse, doesn't work in runnable JAR/exe 在Eclipse中播放视频效果很好,但是当将Java项目导出为可运行的JAR文件时,它不再起作用 - Playing videos works fine in Eclipse but when exporting the java project as an runnable JAR file it doesnt work anymore 可运行的Jar文件不起作用,但是源代码可以正常工作。 Maven项目JavaFX - Runnable Jar file doesn't work but the source code works fine. Maven Project JavaFX Eclipse Java-程序可以在Eclipse中运行,但不能作为可运行的jar - Eclipse Java - Program works in eclipse but not as runnable jar 当导出可运行的jar程序不起作用时的Eclipse - Eclipse when export runnable jar program doesn't work 为什么从Eclipse导出的可运行JAR不起作用? - Why doesn't a runnable JAR exported from Eclipse work? 在Eclipse中导出后,可运行的JAR文件未运行 - Runnable JAR file doesn't run after export in Eclipse 从Java杀死Linux进程在Runnable JAR中不起作用 - Killing linux process from java doesn't work in Runnable JAR 在可运行的jar中导出图像不起作用 - Exporting image in runnable jar doesn't work
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM