I would like to determine whether the javadoc command that we issue from a makefile encounters any errors or warnings. Currently, I can see that we're encountering errors due to import statements that are not on the classpath that we specify to javadoc (but should be). I ultimately want to fix our javadoc invocation and content and then lock it down so that any error or warning will be caught by the makefile and stop the build. However, as far as I can tell, the documentation does not mention any return code values from the javadoc command. Note that we're using Java 7 and running javadoc from a command in a GNU makefile, not from Ant or Maven. What do you recommend that I do?
UPDATE: My command looks like this:
<path1>/javadoc -overview <path2>/overview.html -sourcepath <path3> <file1> <file2> <dir1> <dir2> -d <output_dir>
There's nothing I can see in that call that would cause errors to be treated as warnings.
Here's a fragment from the output that shows the error/warning messages I'm seeing:
....
Constructing Javadoc information...
../../../<path>/<filename>.java:5: error: package javax.servlet.http does not exist
import javax.servlet.http.HttpSessionBindingEvent;
....
The word "error" appears in them, but at the end, the output says only "50 warnings". If I add another issue (such as the #invalid tag suggested in one of the answers), I get 51 warnings.
I just tried from the commandline, when no errors are present, a value of zero is returned:
> javadoc my.package.name
> ....
> echo $?
> 0
After editing a javadoc command with:
/**
* #invalid
*/
and running the same javadoc command again, I get an error message and a return code of 1:
> javadoc my.package.name
> ....
> ./my/package/name/Coordinate.java:21: error: unknown tag: invalid
> * #invalid
> ^
> ....
> echo $?
> 1
So you just should check if the return value of javadoc is 0 or not. If you do not know how to check that return, read this SO question and answer
Even though javadoc 1.7 reports errors, it returns with a zero return value, so the build doesn't catch it. However, javadoc 1.8 returns with a nonzero return value, which the build does catch.
Related
I'm trying to use Apache Commons Exec to run a git command which uses a regex.
When I form my CommandLine and print it out it looks like this:
[git, --no-pager, grep, --line-number, --untracked, --extended-regexp, "^\s*public void\s+(testFindByAdAccount).*", --, *Test.java]
However when I execute this, git returns no results, resulting in an exit code 1.
When I run this command manually though, it returns plenty of results and succeeds. Changing the --extended-regexp argument to just a string like testFindByAdAccount does yield results when run via Exec, so I think Apache Commons is doing something to the regexp argument making it invalid. Any ideas what is going on?
EDIT: Adding a reproducible example
Clone https://github.com/ragurney/min-example
Run gradlew shadowJar to produce jar file for project
Run the app with java -jar app/build/libs/app-all.jar
Note the output which shows the command printed fails with an exit code 1 (because there are no results returned by the git command)
$ java -jar app/build/libs/app-all.jar
HELLOOOOOO
WD::: null
[git, --no-pager, grep, --line-number, --untracked, --extended-regexp, "^\s*public void\s+(testAppHasAGreeting)\(\).*", --, *Test.java]
WD::: /Users/rgurney/Src/personal/min-example
Exception in thread "main" java.lang.RuntimeException: org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)
at min.example.App.lambda$runCommand$1(App.java:74)
at io.vavr.control.Try.getOrElseThrow(Try.java:748)
Running the command manually does produce expected results:
$ git --no-pager grep --line-number --untracked --extended-regexp "^\s*public void\s+(testAppHasAGreeting)\(\).*" -- "*Test.java"
app/src/test/java/min/example/AppTest.java:11: public void testAppHasAGreeting() {
I got a clue as to what's going on here when the sample you provided worked just fine on my Windows laptop but failed on my Linux desktop.
Once I made sure the git version wasn't the culprit (tested several versions between 2.17 and 2.39 on both machines), I figured the difference must be in the way different shells handle quoting. Specifically, the only argument here that has any potential quoting issues is the regex ("^\s*public void\s+(testFindByAdAccount).*"), which is added to the command line by commandLine.addArgument(regex);.
addArgument may look innocuous, but under the hood, it allows the CommandLine to handle the quoting itself (i.e., addArgument(String argument) calls addArgument(String argument, true). Since you've handled the quoting yourself, you should not allow the CommandLine to handle the quoting, and should explicitly call it with the second argument false. i.e.:
public static List<String> grep(String regex, String filePattern, String wd) {
CommandLine commandLine = CommandLine.parse("git");
commandLine.addArgument("--no-pager");
commandLine.addArgument("grep");
commandLine.addArgument("--line-number");
commandLine.addArgument("--untracked");
commandLine.addArgument("--extended-regexp");
commandLine.addArgument(regex, false);
// Here -----------------------^
commandLine.addArgument("--");
commandLine.addArgument(filePattern);
System.out.println(commandLine);
return List.of(runCommand(commandLine, wd).split("\n"));
}
This takes the quote-handling logic away and ensures the same code runs smoothly both on Windows and Linux (at least those I've tested).
I am using the below piece of code to copy and filter the properties from the properties file and it is working fine.There are one variable which is not static and I need to pass as a paramter so it could work on correct file.I am using -Penv=test or -Penv=at but I am getting the error.
task createLocalProp(type:Copy) << {
from "templates/local.properties.template"
into ("$buildDir/properties")
def myProps = new Properties()
file("Properties/${env}/local_${env}.properties").withInputStream{
myProps.load(it);
}
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: myProps)
}
Error:
C:\GRADLE_WORK\XXXX-GRADLE>gradle -b build_localprop.gradle createLocalProp -Pen
v=test
FAILURE: Build failed with an exception.
* Where:
Build file 'C:\GRADLE_WORK\XXX-GRADLE\build_localprop.gradle' line: 37
* What went wrong:
Could not compile build file 'C:\GRADLE_WORK\XXXX-GRADLE\build_localprop.gradle'
.
> startup failed:
build file 'C:\GRADLE_WORK\XXX-GRADLE\build_localprop.gradle': 37: expecting
EOF, found '<<' # line 37, column 33.
task createLocalProp(type:Copy) << {
^
1 error
I'm not sure right now why the compiler error happens, but you should not configure the task in execution phase, but in configuration phase. << syntax is a shortcut for doLast and thus even if it would compile it would probably not work as expected. Remove the << and probably everything is ok.
I ran into a similar error reporting the bottom of my gradle file had an error. In reality it was a missing closing bracket in the middle of the file that I missed when doing a diff merge conflict.
Platform: Windows 7 x64
JDK version: 7.0.25 x64 or 7.0.45 x64
JDK installation path:
C:\Java\jdk725 or default c:\Program Files\Java\jdk1.7.0_25\
Spring Framework Release: 3.2.4 or 3.2.5
UAC: enabled or disabled
gradlew build (after gradlew):
:referenceHtmlMulti FAILED
FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':referenceHtmlMulti'.
Failed to compile stylesheet. 59 errors detected.
Try:
Run with --info or --debug option to get more log output.
Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':referen
ceHtmlMulti'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecuteActions(ExecuteActionsTaskExecuter.java:69)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecute(ExecuteActionsTaskExecuter.java:46)
..
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:130)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:48)
Caused by: javax.xml.transform.TransformerConfigurationException: Failed to comp
ile stylesheet. 59 errors detected.
at com.icl.saxon.PreparedStyleSheet.prepare(PreparedStyleSheet.java:136)
at com.icl.saxon.TransformerFactoryImpl.newTemplates(TransformerFactoryI
mpl.java:127)
at com.icl.saxon.TransformerFactoryImpl.newTransformer(TransformerFactor
yImpl.java:79)
..
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecuteAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecuteActions(ExecuteActionsTaskExecuter.java:61)
... 70 more
BUILD FAILED
My question is: why did my build fail?
The problem happens when :referenceHtmlMulti task is executing.
If we look in groovy class we will see that XSLT transformation is used to create docbook-reference. Despite the fact, that Saxon is used (TransformerFactoryImpl is selected) the choosen SAXParserFactory is org.apache.xerces.jaxp.SAXParserFactoryImpl (I wonder why not to use com.icl.saxon.aelfred.SAXParserFactoryImpl).
IF we look what implementation of xerces is used by gradle we will see xercesImpl-2.9.1.jar, which is old enough.
Now let's find class URI in xerces sources. It represents a Uniform Resource Identifier (URI). On line 1134 we can find
else if (!isURICharacter(testChar)) {
throw new MalformedURIException(
"Opaque part contains invalid character: " + testChar);
}
Now let's look how this function works:
private static boolean isURICharacter (char p_char) {
return (p_char <= '~' && (fgLookupTable[p_char] & MASK_URI_CHARACTER) != 0);
}
We can see that function will return true if char comparision will return true also. But that means rather close limits of chars (from code 0 - 126 (~)). But what about non US-ASCII character set?
Let's read RFC 2396 about non us-ascii characters (that can exist in your windows path, representing your local language or can be found in account name, under which gradle unpacks itself and works): other catagory - The Unicode characters that are not in the US-ASCII character set, are not control characters (according to the Character.isISOControl method), and are not space characters (according to the Character.isSpaceChar method) (Deviation from RFC 2396, which is limited to US-ASCII). The set of all legal URI characters consists of the unreserved, reserved, escaped, and other characters.
So. URI identification fails. And that is the place where build code fails.
There are 2 solutions:
To make your account name or path consist only of US-ASCII characters.
To patch URI class (for example, by rewriting function isURICharacter)
In memory I build this string:
package consume;
public class Consumer {
public void consume(String message){
System.out.println(new produce.Producer().produce(message));
}
}
On my filesystem I have C:\Users\hooch\Desktop\produce\Producer.class built from this source:
package produce;
public class Producer {
public String produce(String message){
return "THIS IS THE MESSAGE: " + message;
}
}
I use org.eclipse.jdt.internal.compiler.tool.EclipseCompiler and pass these options:
Arrays.asList(new String[] {"-cp", "C:\\Users\\hooch\\Desktop"});
I try to compile it but get this error
1. ERROR in \Consumer.java (at line 4)
System.out.println(new produce.Producer().produce(message));
^^^^^^^
produce cannot be resolved to a type
If I have the class produce.Producer inside the project which calls the EclipseCompiler, it works. (I do not need to specify the classpath in the options then) Now the question is: how do I correctly specify the classpath so that the in-memory code can access external classes?
If I add -verbose to options, I get
[parsing \Consumer.java - #1/1]
[reading java/lang/Object.class]
[reading java/lang/String.class]
[analyzing \Consumer.java - #1/1]
[reading java/lang/System.class]
[reading java/io/PrintStream.class]
[reading java/io/FilterOutputStream.class]
[reading java/io/OutputStream.class]
[reading java/io/Flushable.class]
[reading java/io/Closeable.class]
[reading java/lang/AutoCloseable.class]
----------
1. ERROR in \Consumer.java (at line 4)
System.out.println(new produce.Producer().produce(message));
^^^^^^^
produce cannot be resolved to a type
----------
[completed \Consumer.java - #1/1]
[1 unit compiled]
1 problem (1 error)Exception in thread "main" java.lang.NullPointerException
at impl.SimpleTestCompiler.executeCode(SimpleTestCompiler.java:137)
at impl.SimpleTestCompiler.main(SimpleTestCompiler.java:155)
Ok, now I'm sure it must have to do with the classpath option because I swapped EclipseCompiler for javax.tools.ToolProvider.getSystemJavaCompiler() and I get the same error about the package not being resolved.
This should work (if you double the backslashes in the String which I assume you did because you would get compile errors in the code which invokes the compiler).
Try to add -verbose to the compiler options to see which files it tries to access.
[EDIT] As the next steps:
Try to run the compiler from the command line.
If that doesn't work, get the sources and try to debug it. There is probably something wrong with passing the classpath to the compiler.
I'm a little bit worried by the path of the source file (\Consumer.java). Try to create a correct package path when passing this virtual file to the compiler.
In the http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html
echo Main-Class: oata.HelloWorld>myManifest
md build\jar
jar cfm build\jar\HelloWorld.jar myManifest -C build\classes .
java -jar build\jar\HelloWorld.jar
Note: Do not have blanks around the >-sign in the echo Main-Class instruction because it would falsify it!
Anyone know why there is such Note. I do not see any difference when we hae balnks around >-sign.
You are correct, it makes no difference. Not sure what the message on the tutorial means.
Just a guess.
It probably meant to stress the need for getting the line correctly copied. Main-Class attribute
Any value other than 'Main-Class:' will fail the jar creation.
With a white space after - Main - Class or
just before : 'Main-Class : gives the error invalid header field name: ..