FindBugs command line: how to specify the project to be analyzed? - java

I tried to run FindBugs in command line and had troubles when specifying the project to be analyzed. I understand FindBugs works on bytecode (.jar, .class), so I wrote a HelloWorld program and made sure that it had some messy code that would be detected by FindBugs.
Then I tried:
java -jar D:/findbugs-2.0.3/lib/findbugs.jar -project HelloWorld/bin
which threw an exception:
java.lang.IllegalArgumentException: Can't read project from HelloWorld/bin
at edu.umd.cs.findbugs.Project.readProject(Project.java:774)
I also tried .class and .jar files, but nothing showed up:
java -jar D:/findbugs-2.0.3/lib/findbugs.jar -project HelloWorld/bin/Main.class
java -jar D:/findbugs-2.0.3/lib/findbugs.jar -project HelloWorld.jar
I checked the FindBugs manual about the command line option "-project", it says
The project file you specify should be one that was created using the GUI interface. It will typically end in the extension .fb or .fbp
I don't understand this. Does it mean that some pre-processing is required and FindBugs cannot check arbitrary .jar or .class or project directly? How can I get this .fb or .fbp extension?
Thanks.

The procedure is described on the FindBugs website:
Make sure you download the FindBugs distribution which includes the GUI (called Swing interface).
Extract your downloaded ZIP and add its bin folder to your PATH.
Type findbugs to open the GUI, then click New Project
In the dialog:
Enter a project name, say HelloWorld.
Where it says Classpath for analysis, give it the Jar with your .class files or a directory where the .class files are (such as build/classes/main or whatever; the package structure must start in this directory).
Where it says Auxiliary classpath, list any libraries required to load your classes.
Source directories works just like Classpath for analysis, but for .java files. FindBugs uses this to show you where in the code your issues are.
You can select (cloud disabled) as bug store.
Click Analyze.
Now you can save the project configuration as a .fbp project file.
Next time, you can start the analysis by running
java -jar D:/findbugs-2.0.3/lib/findbugs.jar -project HelloWorld.fbp
If you don't want to or cannot use the GUI, you can get the text-only version by adding the -textui option as first option after findbugs.jar. Output formats and behavior are configured via additional command line options.
However, most people use FindBugs integrated with their IDEs, or as part of a build process. Neither use case should require the GUI or command line versions. Take a look at the plugins for your IDE, it may save you a lot of time and they are really easy to use.

Related

Can javac process/include `.properties` files so that they appear in the output?

Currently I'm building a small personal project in Java which is a simple file server. I've implemented basic internationalization with usage of ResourceBundle. I'm using .properties files to store messages in different languages.
Till now I was using Vscode built-in java compilation process which was copying .properties files into its corresponding directory in the output. However now I'd like to write a build script for that project.
My command looks like this:
javac -d ./bin -cp ./src ./src/**/*.java.
This command however doesn't take .properties files into account. I searched web whether javac has ability to somehow process/include this files into output but found no answer. I know I can use Maven or Ant, but I'd like to make this project without usage of additional tools.
Answering to my own question, but maybe someone will find this useful one day. In short javac always compiles .java files producing .class files. There is no way that it could process some other file (source:
How to set the output files when compiling with javac).
Long story short if you want to include resources, images, text files, anything that is not .java file in your output, and don't want to use build tools, you have to copy it manually or use cp command in your build script.

JAVA, Batch file errors

I have an existing Java project that compiles and runs properly through Eclipse. I have created the following .bat file to run the program sans Eclipse:
java -classpath jflashplayer.jar;bin TestProgram
The file is saved within the project folder, but not within the bin folder (located in same directory as bin). When I try to run the batch, I am met with a large number of runtime errors, the first being
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/apache/commons/io/FileUtils
I'm not sure why I get this error when it compiles and runs properly via Eclipse. I have the commons-io jar files linked to the project within Eclipse as libraries, and the jar files are themselves located in the project file (same directory as the batch file and the bin folder).
Also, I'm not entirely sure what the -classpath jflashplayer.jar bit of the batch file is doing. I am using the jflashlayer.jar library (also linked to the project within Eclipse and in the same location as the other jar files), but I am not sure why it would appear in the batch file. I edited an existing batch file from a similar project that uses the jflashplayer.jar files, and it has worked previously to leave that part in.
When I write code in Java, I rarely require it to compile/run outside of the IDE, so I usually have troubles when it comes to this part. Perhaps there is a more robust and foolproof method to run the program outside of the IDE other than the batch file method.
The batch file method is fine, but you have to specify all the libraries you're using on the classpath, just like the jflashplayer.jar.
In this case, the error you're getting is because the Apache commons-io library is not specified on the classpath. Your command would have to look something like:
java -classpath jflashplayer.jar;commons-io.jar;<other jars ...>;bin TestProgram
Alternatively, you can create a runnable jar from Eclipse as described here. When you select a library handling strategy, choose the option Extract required libraries into generated JAR. This will make it so that all the library classes you're using are packaged into your application's jar file, and you can just execute it by invoking java -jar my_application.jar.

java.lang.NoClassDefFoundError. Class not found during runtime.

I am working on eclipse, and I have the need to use external library's. For example Jsoup and JXL.
Now what I have done so far is: First created a "lib" folder in my project folder. Afterwards in eclipse, click on project properties, Libraries tab, add external jar and added the jar in the lib folder.
So this solve my compilation issue. Now, when I run the program (I go to project/bin and in the console execute: java ProgramName ; I get
java.lang.NoClassDefFoundError:
Now to testing, I added the Jar file to the folder where Main.java is and Now, I have been able to run the program doing the following:
javac -classpath ./path/to/jar Main.java
java -classpath ./path/to/jar:. Main
And this works.
So the first thing that comes to mind is that I have to tell java where to find the respective libraries. If this is correct? How do I do it?
java -cp ???(dont know what to put here)
But moreover. I have another issue. I am writing this program in a computer, but I am going to use it in other which probably don't have those libraries. How do I solve this issue?
I like to use something like the following:
java -cp myjar.jar;lib/*.jar com.foo.bar.MyClass
This adds not only my jar to the classpath but those in the lib directory as well.
If you want to run your jar on another computer, you will need those jars as well, you cant just have your jar. Why not just also package your lib directory along with it?
To get your program to run you have two paths to worry about
The path to the jar files that are your applications dependencies (like jsoup.jar) (lets call this lib)
The path to the directory containing the classes of your app (lets call this classes)
The general form of the command line you need is:
java -cp lib/jsoup.jar:classes Main
If you have more libs
java -cp lib/jsoup.jar:lib/jxl.jar:classes Main
A general note on packaging your app for release to other computers. You might want to consider making a jar of your own app, probably best done using http://ant.apache.org/manual/Tasks/jar.html
Another option is to produce a "one jar", which makes one large jar, bundling in all the classes you need from your libs and all the classes in your app. You can then make the jar executable for a nice out of the box solution. Have a look at http://one-jar.sourceforge.net/ and https://code.google.com/p/jarjar/
if you have this structure:
project folder
... code
... libs
then from the code folder:
javac -cp .;../libs/*.jar yourmainclass.java
java -cp .;../libs/*.jar yourmainclass
When you need to compile and run this project, take all the folder and do the same in other machine.

Compiling Java package throws errors for external Jars

Pretty basic problem here. So I have a Java package that I have created that has three classes (one has the main method). I am trying to use a few Apache Jars, and have added these to my build path in Eclipse. However Eclipse wont let me build and run it properly, so I am trying the command line. I have added the env var CLASSPATH and pointed it to my lib directory which hold the Apache Jars. However, when I try to use javac I get a bunch of errors:
package org.apache.xmlrpc does not exist
import org.apache.xmlrpc.client.XmlRpcClient;
I was reading the man page for javac and it said that:
If neither CLASSPATH, -cp nor -classpath is specified, the user class path consists of the current directory.
So I tried copying the Jars to the same location as my three source files, but no change.
Can someone please tell me what I'm doing wrong?
Thanks.
Classpath variable (or command line option of javac) must contain all jars explicitly. It cannot go through jar files stored in specified directory.
You can compile this by specifying the option -cp on the command line:
javac -cp foo.jar:bar.jar foo/bar/Baz.java
You then run it with the same option:
java -cp foo.jar:bar.jar foo.bar.Baz
It sounds like you've just set the classpath to the directory containing the jar files. You need to set it to the individual jar files, or use java.ext.dirs to set an "extension" directory containing jar files. I'd recommend using the specific jar files. Something like:
// Assuming Windows...
CLASSPATH = c:\libs\foo.jar;c:\libs\bar.jar
I'd also personally recommend specifying the classpath on the command line instead of using an environment variable - the latter will work, but it ends up being a bit more fiddly if you want to compile different projects against different libraries.
However, I'd actually recommend getting Eclipse working first, rather than retreating to the command line. It should be fine - if you could give us more information about what's failing in Eclipse, we may be able to help you with that instead.
The jar files in the current directory are not automatically included; that only refers to .class files in normal package/directory hierarchy. Jar files must be added either explicitly, or via a wildcard like javac -cp ./* (Assuming JDK6+)
(Some OSes may require an escape of the * to avoid globbing; OSX does not.)
I agree with previous answers, but I would also recommend to use proper java build tool - like ant (perceived easier to use, but not necessary) or maven ( perceived more difficult to use, but really worth learning )

How to run examples of an API (which is already having workspace) using eclipse IDE

I am new to Java and I am not sure how apt is my question title. Please suggest any better title.
I have got a Java API which has many executable modules which do various things related to parsing MS Outlook's .pst files. And my problem is that I am getting this exception when I run the execute command to execute a .class file of one module of the API(java -classpath /opt/Java/libs/JPST/lib/jpst.jar /opt/Java/libs/JPST/examples/GetInboxMessages/bin/Example)-
Exception in thread "main" java.lang.NoClassDefFoundError: /opt/Java/libs/JPST/examples/GetInboxMessages/bin/Example
Caused by: java.lang.ClassNotFoundException: .opt.Java.libs.JPST.examples.GetInboxMessages.bin.Example
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: /opt/Java/libs/JPST/examples/GetInboxMessages/bin/Example. Program will exit.
So far ...
You can check my previous question where I concluded that I was correctly running the compile and execute commands. But I am still getting the above mentioned `exception.
I asked the API's developer who says that I should get Eclipse or Netbeans IDE. He said that the
examples folder inside the API's
folder structure is entire Eclipse
workspace.
and also said that
It is easier to compile and run all
examples.
And now ...
So, I have setup Eclipse Helios for Java. Can anyone tell me how is it easy to compile and run all the examples (I think the modules inside the examples folder) using the IDE. I have earlier worked with Eclipse for PHP but never for Java.
Folder structure of the API
I need to execute a .class file of one of those modules (many module folders are present inside examples directory). There are many such modules present inside the examples folder of the API. Each of these modules folders contain a bin folder (containing .class file) and src folder (containing .java file) . I need to execute one such .class file.
There is a lib directory containing a .jar file (which is needed to be referenced by my target .class file). The lib directory is at the same level as the examples directory.
Solution
I have verified that the solution given by Jonathan works (verified only without-using-elipse case). To make it more clear the classpath needs to include all the class locations in both compile and execute commands. So, if you need to compile and execute an Example.java file with a dependency Parent.jar do this:-
Compile
javac -classpath /path/to/Parent.jar/file/Parent.jar:/path/to/Example.java/file/ Example.java
Execute
java -classpath /path/to/Parent.jar/file/Parent.jar:/path/to/Example.class/file Example
And note the separator - should be : for linux and ; for windows.
Thanks,
Sandeepan
When Eclipse starts it should ask you which workspace to use. Select the examples folder and, if it really is an eclipse workspace, you should see all the projects already set up (it may take some time to build everything depending on the size of the projects and the speed of your machine). Then simply find the class you want and run it. If everything is set up correctly it should just work. If not you may have to go back to the developer for more details.
But I don't think you need Eclipse to run that one class. Looking at the stacktrace you provided at the beginning of your question it looks like it failed to run because you haven't set your classpath properly. Try:
java -classpath /opt/Java/libs/JPST/lib/jpst.jar:/opt/Java/libs/JPST/examples/GetInboxMessages/bin Example
To very briefly explain: The classpath lists the places where Java looks for the classes it needs. You specify the class to run relative to the classpath, not as a file path. Since the class you are trying to run in in the folder "/opt/Java/libs/JPST/examples/GetInboxMessages/bin" this folder must be on the classpath (note, I am assuming a unix based system, if you are using windows use ';' to separate entries not ':'). Then simply specify the class to run by itself relative to the classpath (which in this case is just the class name by itself).
Please be aware this is a very basic overview, things get a more complex if you start using packages (folders that would appear below the bin folder). This is one advantage of using a program like Eclipse since it will handle a lot of this for you.
Sounds like a classpath issue.
Right click on your project in eclipse.
Go to buildPath > configure build path
Make sure the jar file is referenced in the libraries tab and if it isn't add it.

Categories