I'm running
java -cp some:jars:out \
-agentlib:hprof=cpu=times,format=a,file=java.hprof.txt,lineno=y,doe=y com.foo.Benchmark \
< /dev/null
and in the output I get stack frames without line numbers
THREAD START (obj=50000150, id = 200002, name="HPROF gc_finish watcher", group="system")
THREAD START (obj=50000151, id = 200001, name="main", group="main")
THREAD START (obj=50000281, id = 200003, name="Thread-1", group="main")
THREAD END (id = 200003)
THREAD END (id = 200001)
THREAD START (obj=500002a5, id = 200004, name="DestroyJavaVM", group="main")
THREAD END (id = 200004)
TRACE 307081:
com.foo.Benchmark.methodName(Benchmark.java:Unknown line)
com.foo.Benchmark.anotherMethodName(Benchmark.java:Unknown line)
...
If I change lineno=y to lineno=n I still get Unknown line.
I compiled the classes with -g. My javac looks like
javac -g -Xlint -encoding UTF-8 -source 1.5 -d out -classpath ... src/main/com/foo/*.java
I checked the .class files to make sure they have line numbers:
javap -classpath out -c -l com.foo.Benchmark
shows plenty of things like
LineNumberTable:
line 1077: 0
line 1078: 8
line 1079: 14
line 1080: 21
line 1082: 23
line 1083: 31
line 1084: 43
Am I using some flag combination that prevents line number output?
I faced exactly the same problem, but compiling the source with -g helped. After compiling with -g, I see the line numbers like this (which I don't see otherwise, without -g option) -
LineNumberTable:
line 16: 0
line 17: 8
line 18: 12
line 19: 20
line 18: 29
line 21: 35
Now, if I run this -
java -cp "./build/classes" -agentlib:hprof=heap=sites,depth=20 org.sample.welcome.Main a b c
I do get the line numbers for the user-defined classes. Even though I am not sure what's going wrong in your case, these are my observations -
Using javac without -g: If I have -lineno (default y) set to y, I still don't see the line numbers for most of the classes except for the user-defined classes (Main in the above case). If I've set -lineno to n, then I won't see line numbers for any of the classes anyway.
Using javac with -g: If I have -lineno set to y, I can see the line numbers for all the classes (not sure what's going wrong in your case).
The only documentation I could find for HPROF doesn't say anything beyond this. I think one option would be to try with fewer optional arguments and see the results.
Note: I'm using JDK 1.6 in the above example
Related
Recently I posted a question about some basic scala code. I got some useful responses that emphasized that scala2 and and scala3 are very different programming languages. Since I have scala3, I was careful enough to work out only scala3 examples, such as this one:
#main def happyBirthday(age: Int, name: String, others: String*) =
val suffix =
age % 100 match
case 11 | 12 | 13 => "th"
case _ =>
age % 10 match
case 1 => "st"
case 2 => "nd"
case 3 => "rd"
case _ => "th"
val bldr = new StringBuilder(s"Happy $age$suffix birthday, $name")
for other <- others do bldr.append(" and ").append(other)
bldr.toString
I compile it as scalac happyBirthday.scala and run as scala happyBirthday 23 Lisa Peter
Illegal command line: java.lang.NumberFormatException: For input
string: "happyBirthday"`
This reminded me very much the issue observed in a comment to this post. #LuisMiguelMejíaSuárez suggested that a workaround could be to compile to jar. I did exactly that using this recipe
scalac happyBirthday.scala -d happyBirthday.jar
and run
java -jar happyBirthday.jar 23 Lisa Peter
Error: A JNI error has occurred, please check your installation and
try again Exception in thread "main" java.lang.NoClassDefFoundError: scala/util/CommandLineParser$ParseError
I wonder what's wrong with this code? Notice that "#main methods are the recommended scheme to generate programs that can be invoked from the command line in Scala 3." according to this reference.
I have some issues with getting the java version out as a string.
In a batch script I have done it like this:
for /f tokens^=2-5^ delims^=.-_^" %%j in ('%EXTRACTPATH%\Java\jdk_extract\bin\java -fullversion 2^>^&1') do set "JAVAVER=%%j.%%k.%%l_%%m"
The output is: 1.8.0_121
Now I want to do this for PowerShell, but my output is: 1.8.0_12, I miss one "1" in the end Now I have tried it with trim and split but nothing gives me the right output can someone help me out?
This is what I've got so var with PowerShell
$javaVersion = (& $extractPath\Java\jdk_extract\bin\java.exe -fullversion 2>&1)
$javaVersion = "$javaVersion".Trim("java full version """).TrimEnd("-b13")
The full output is: java full version "1.8.0_121-b13"
TrimEnd() works a little different, than you might expect:
'1.8.0_191-b12'.TrimEnd('-b12')
results in: 1.8.0_19 and so does:
'1.8.0_191-b12'.TrimEnd('1-b2')
The reason is, that TrimEnd() removes a trailing set of characters, not a substring. So .TrimEnd('-b12') means: remove all occurrences of any character of the set '-b12' from the end of the string. And that includes the last '1' before the '-'.
A better solution in your case would be -replace:
'java full version "1.8.0_191-b12"' -replace 'java full version "(.+)-b\d+"','$1'
Use a regular expression for matching and extracting the version number:
$javaVersion = if (& java -fullversion 2>&1) -match '\d+\.\d+\.\d+_\d+') {
$matches[0]
}
or
$javaVersion = (& java -fullversion 2>&1 | Select-String '\d+\.\d+\.\d+_\d+').Matches[0].Groups[0].Value
I'm trying to test BeanShell's command line interpreter in how it processes basic Java commands and syntax on my machine, and see if I can customise its behavior in any way. I've installed version 2.0b4 on my machine running OS X 10.10.1 (the JAR file is in /Library/Java/Extensions as per the instructions).
It's the closest thing to what I've been looking for, an interactive Java interpreter, but it doesn't have some standard features which a good interpreter should have.
I'd like to be able to use the Up arrow key to reuse a previous command, but at the moment it doesn't recognise it, it just shows a control sequence. Is there a way to customise this for BeanShell?
Is there a way to get BeanShell to print out the value of a variable if I've created it beforehand, just by naming it, like
String s = new String( "Hello World!" );
s;
Hello World!.
This is possible in Python for example.
According to the documentation on importing Java classes which(<java class>); should return the classpath location of the specified Java class. But which( java.lang.String ); does not work for me, I get a NullPointerException:
bsh % which(java.lang.String);
Start ClassPath Mapping
Mapping: Directory /Users/srm
// Error: // Uncaught Exception: Method Invocation cp.getClassSource : at Line: 42 : in file: /bsh/commands/which.bsh : cp .getClassSource ( className )
Called from method: which : at Line: 8 : in file: : which ( java .lang .String )
Target exception: java.lang.NullPointerException
java.lang.NullPointerException
Any pointers or help would be appreciated.
Run beanshell with jline.
Download jline jar from http://jline.sourceforge.net/index.html and then you can do:
java -cp jline-1.0.jar:bsh-2.0b4.jar jline.ConsoleRunner bsh.Interpreter
Line editing capability will be provided by jline. I found this hint here.
There are issues running with jline2. First, you'll get:
$ java -cp jline-2.12.jar:bsh-2.0b4.jar jline.ConsoleRunner bsh.Interpreter
Exception in thread "main" java.lang.NoClassDefFoundError: jline/ConsoleRunner
Due to this issue which is fixed. But then, use the new class and you still get:
$ java -cp jline-2.12.jar:bsh-2.0b4.jar jline.console.internal.ConsoleRunner bsh.Interpreter
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
due to this issue which is not fixed yet.
Use show() command which will trigger showing of value.
bsh % show();
bsh % String s = new String("Hello World");
bsh % s;
<Hello World>
bsh %
It is mentioned in the Useful BeanShell Commands section of the documentation.
Doesn't work for me either
It doesn't fail in my case, but it didn't find it either.
bsh % which(java.lang.String);
Start ClassPath Mapping
Mapping: Archive: file:/Users/me/beanshell/jline-1.0.jar
Mapping: Archive: file:/Users/me/beanshell/bsh-2.0b4.jar
Mapping: Archive: file:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Classes/classes.jar
End ClassPath Mapping
null
bsh %
As a JAVA teaching assistant, I get stuck with grading a lot of student's labs. A lot of these labs use a Scanner to get input from a user. Instead of repeated bashing numbers into the keyboard, is there a way I can utilize a heredoc to run all of the labs with the same input parameters without changing the student's code? What I have so far (which works for except the heredoc-esque code):
#!/bin/bash
for i in unzip/*; do
echo $i
javac $i/lab0/AddThree.java
cd $i/lab0
java AddThree <<EOF
2
3
4
EOF
cd ../../..
done
The code I'm trying to grade adds three integers that are provided by the user. unzip is the directory where each student has a folder (i.e. file structure is ./unzip/student/lab0/sourcecode.java)
Java gives:
unzip/student
Hello out there
I will add three numbers for you
Enter three whole numbers on a line :
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at AddThree.main(AddThree.java:10)
./lab0test: line 9: 2: command not found
./lab0test: line 10: 3: command not found
./lab0test: line 11: 4: command not found
./lab0test: line 12: EOF: command not found
Your heredoc looks good except it will send the spaces at the start of each line. To get rid of those, you can either use -EOF and start each line of the heredoc with Tab characters, which will get stripped:
cd $i/lab0
java AddThree <<-EOF
TabTab2
TabTab3
TabTab4
TabTabEOF
cd ../../..
Or unindent the heredoc contents. It's ugly, but it'll work.
cd $i/lab0
java AddThree <<EOF
2
3
4
EOF
cd ../../..
Alternatively, if the input is short enough you could do it inline:
java AddThree <<< $'2\n3\n4'
(Using $'...' tells the shell to interpret \n escape sequences.)
The javap command has several options, one of them is -l, which can print line number and local variable tables. Suppose a java program has been compiled successfully and there is the file "Main.class", so running javap -l Main can produce something like:
public static void main(java.lang.String[]);
LineNumberTable:
line 100: 0
line 101: 27
line 275: 54
LocalVariableTable:
Start Length Slot Name Signature
0 55 0 args [Ljava/lang/String;
However, I'm using this javap -l xxx command on the class files of one java program, but the area of line number and local variable table is empty (which shouldn't be). The javap command and other options such as -s, -verbose works fine, but only the line info area corresponding to the -l option is empty.
Has anyone ever encountered such weird case?
Use -g to compile your code, otherwise the line numbers are not kept (akin to the stack trace displaying "compiled code" instead of the line number)