`
Dollyn
  • 浏览: 168755 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JSR-045规范

 
阅读更多

JSR-045是针对非Java语言,需要编译成class文件在JavaVM上运行并调试的一个规范。

以下内容来自:http://jcp.org/aboutJava/communityprocess/review/jsr045/index.html


<!-- body="start" -->

JSR-045: Debugging Support for Other Languages


Goal
Terminology
Approach
Single Translation
Multiple Translations
Diagram
Scope
Variables
Multi-Level Source View
Finding Source
Multiple Source Files per Class File
Source Map
General Format
Header
StratumSection
FileSection
LineSection
VendorSection
EndSection
EmbeddedSourceMaps
SMAP Syntax
SMAP Resolution
LineInfo Composition Algorithm
Resolution Example
JPDA Support
SourceDebugExtension Support
SourceDebugExtension Access
SourceDebugExtension Class File Attribute
Example
Input Source
Language Processor
Post Processor
Debugging
License


Goal

A mechanism is needed by which programs executed under the JavaTM virtual machine but written in languages other than the Java programming language, can be debugged with references to the original source (for example, source file and line number references).

Constraints:

  • No change to the Java programming language.
  • Optional change to Java programming language compiler.
  • No change to JPDA clients (debuggers, ...) for basic functionality. With the exception being, tools that arbitrarily prohibit non-Java programming language source.
  • Minimal change to Java virtual machine.
  • No change to the Java platform class libraries.


Terminology

Term Definition final-sourcetranslated-sourcelanguage-processorclass filecompilerpost-processorSource Map
SMAP Source Map File
SMAP-file stratumJPDAJDISourceDebugExtension
attribute
The final form of source. This source will be compiled into a class file . Typically, final-source is Java programming language source.
Source that will be translated by a language-processor into another language or form.
Converts translated-source to final-source or to different translated-source .
A collection of bytes in Java virtual machine class file format.
Compiler which converts final-source to class files. For example, javac is a compiler.
Takes a class file and a Source Map File as input; generates a class file as output. Inserts a SourceDebugExtension attribute .
Specifies the mapping of source between one or more sets of input source and the output source. See: Source Map Format .
Specifies the mapping created by a language-processor between translated-source input and the resultant output source. It is a Source Map stored in a file in Source Map Format .
A view of a class from a particular, named, programming language level.
The Java Platform Debugger Architecture .
The Java Debug Interface, which is the high-level Java programming language interface of the Java Platform Debugger Architecture . See: JDI Specification .
A Java virtual machine class file attribute that holds information about the source. In this case, the information is a Source Map in Source Map Format . The source is mapped to final-source (output source). The Source Map has potentially multiple sets of input source (strata ). See: SourceDebugExtension Class File Attribute


Approach

Single Translation

A language-processor translates translated-source to final-source (the case of translation from one translated-source to another translated-source, is addressed below ). It also creates a second output, an SMAP-file , whose format is described in Source Map Format . This file describes the mapping between input source and output source (e.g. line number and source file).

The final-source generated by the language-processor is compiled by the compiler .

The post-processor takes the class file generated by the compiler and the SMAP-file as input. A SourceDebugExtension attribute containing the SMAP in the SMAP-file is added to the class file and the new class file is written.

Optionally, the compiler may take both final-source and the SMAP-file as input, and perform both compilation and installation of the SourceDebugExtension.

When the resultant program is debugged using a debugging tool based on the Java Debug Interface (JDI ) of JPDA , the final-source line number information is converted to the specified language view (strata ).

Multiple Translations

A language-processor might translate source into source which will become input to another language-processor, and so on. Eventually, after possibly many translated-source forms, final-source is produced. Each translation produces SMAP information. This information must be preserved and placed in context, so that each stratum can be mapped to the final-source.

A language-processor checks for an SMAP-file in a location parallel to that of the input source. For example, if the source repository is a file system and the input source is located at path name . extension then path name . extension .smap will be checked for an SMAP. The input SMAPs will be copied into the generated SMAP. See OpenEmbeddedSection for specifics on the embedding of input SMAPs.

In the case of multiple translations, the post-processor must resolve the embedded SMAPs. See SMAP Resolution .

Note that final-source need not be Java programming language source, as compilers for other languages may directly generate class files, including the SourceFile and LineNumberTable class file attributes. SMAPs and the mechanism presented here are still useful for handling multiple translations.

A programming language implementor, directly generating class files might also choose to generate SMAPs (thus functioning as both language-processor and compiler) since the SMAP is useful for describing source configurations (such as multiple source files per class file) which cannot be represented with the SourceFile and LineNumberTable attributes. In this case, the input is translated-source and the final-source is represented in the attributes but is never generated.

Diagram

This diagram demonstrates data flow. The particular case shown has two levels of translation, with file inclusion on the second level (as is the case in the example in SMAP Resolution ).

| TS0a | TS0b
| |
language-processor0
language-processor0
| | | |
| TS1a | SMAP1a | TS1b | SMAP1b
| | | |
language-processor1
| |
| FS | SMAP2
| |
compiler
|
| |
| class file |
| |
post-processor
|
| class file
|
Java virtual machine
| |
| FS location | SMAP via SourceDebugExtension
| |
JPDA
|
| TS location
|
debugger application

Where TS is translated-source and FS is final-source .


Scope

Variables

The complexity of mapping semantics (like variable and data views) across languages has been discussed. And it has been agreed that this issue will wait for a possible subsequent JSR.

Multi-Level Source View

The ability to choose the source level to view is addressed in this JSR. These are referred to as strata .

Finding Source Files

Currently, final-source is found by combining the follow elements:

  • A source path
  • The package name converted to a directory path
  • The source file name from a JDI call (derived from the SourceFile class file attribute

Since existing debuggers use this mechanism (the only way for an existing debugger to find translated-source ) each aspect must be addressed:

  • The source path must be set-up to include translated-source directories
  • Source must be placed in a directory corresponding to the package
  • The JDI call must return the translated-source name.

For debuggers written against the new APIs, a new method has been added which returns the source path - this makes the translated-source directory structure flexible.

Multiple Source Files per Class File

When an inclusion mechanism is used, a class file will contain source from multiple translated-source files. The SourceFile attribute of class files only associates one source file with a class file which is one reason the approach of simply rewriting the SourceFile and LineNumberTable attributes had to be abandoned. The SMAP allows a virtually unlimited number of source files per stratum.


Source Map Format

A Source Map (SMAP) describes a mapping between source positions in an input language (translated-source ) and source positions in a generated output language. A view of the source through such a mapping is called a stratum . The SMAP-file contains an unresolved SMAP. The SourceDebugExtension class file attribute, when used as described in this document, contains an SMAP. The SMAP stored in a SourceDebugExtension attribute must be resolved , and thus will have no embedded SMAPs and will have the final-source language as the output language.

An SMAP consists of a header and one or more sections of mapping information.

There are currently seven types of section: stratum sections, file sections, line sections, vendor sections, end sections, and open and close embedded sections. New section types may be added in the future - to facilitate this, any unknown sections must be ignored without error.

The semantics of each section is discussed below. For clarity, an informal description of the syntax of each section is included in the discussion. See the formal SMAP syntax for syntax questions.

General Format

The SMAP consists of lines of Unicode text, with a concrete representation of UTF-8 . Line termination is with line-feed, carriage-return or carriage-return followed by line-feed. Because SMAPs are included in class files, size of the SMAP was an important constraint on the format chosen for them.

Header

The first line of an SMAP is the four letters "SMAP " which identifies it as an SMAP. The next line is the name of the generated file. This name is without path information (and thus if the generated file is final-source, the name should match the SourceFile class file attribute). The last line of the header is the default stratum for this class. The default stratum is the stratum used when a debugger does not explicitly specify interest in another stratum. In an unresolved SMAP the default stratum can be unspecified (blank line). In a resolved SMAP the default stratum must be specified. A specified stratum must either be one represented with a stratum section or "Java " which indicates the standard final-source information should be used by default.

StratumSection

An SMAP may map more than one translated-source to the output source (the output source is final-source if the SMAP is in a SourceDebugExtension ). A view of the source is a stratum (whether viewed as translated-source or final-source). Each translated-source language should have its own stratum section with a unique stratum name. The final-source stratum (named "Java ") is created automatically and should not have a stratum section. The stratum section should be followed by a file section and a line section which will be associated with that stratum.

The format of the section is simply the stratum section marker "*S " followed by the name of the stratum. The section ends with a line termination. One FileSection and one LineSection (in either order) must follow the StratumSection (before the next StratumSection or the EndSection ). One or more VendorSection s may follow a StratumSection. There must be at least one StratumSection .

FileSection

The file section describes the translated-source file names. Each line maps a file ID to a source name and, optionally, to a source path. File IDs are used only in the LineSection . The source name is the name of the translated-source. The source path is the path to the translated-source, the "/" symbol is translated to the local file separator. In the case where the source repository is a file system, source name is the file name (without directory information) and source path is a path name (often relative to one of the compilation source paths). For example: Bar.foo would be a source name, and here/there/Bar.foo would be a source path. The first file line denotes the primary file.

The format of the file section is the file section marker "*F " on a line by itself, followed by file information. File information has two forms, source name only and source name / source path. The source name only form is one line: the integer file ID followed by the source name. The source name / source path form is two lines: a plus sign "+ ", file ID, and source name on the first line and the source path on the second. The file ID must be unique within the file section. A FileSection may only occur after a StratumSection . The FileName must have at least one character. The AbsoluteFileName , if specified, must have at least one character.

For example:

*F
+ 1 Foo.xyz
here/there/Foo.xyz
2 Incl.xyz

declares two source files. File ID #1 has source name "Foo.xyz " and source path "here/there/Foo.xyz ". File ID #2 has source name "Incl.xyz " and a source path to be computed by the debugger.

LineSection

The line section (LineSection ) associates line numbers in the output source with line numbers and source names in the input source.

The format of the line section is the line section marker "*L " on a line by itself, followed by the lines of LineInfo . Each LineInfo has the form:

InputStartLine # LineFileID , RepeatCount : OutputStartLine , OutputLineIncrement

where all but

InputStartLine : OutputStartLine

are optional.

A range of output source lines is mapped to a single input source line. Each LineInfo describes RepeatCount of these mappings. OutputLineIncrement specifies the number of lines in the output source range; this line increment is applied to each mapping in the LineInfo . The source file containing the input source line is specified by LineFileID via the FileSection .

More precisely, for each n between zero and

RepeatCount


 - 1

the input source line number

InputStartLine


 + n


maps to the output source line numbers from

OutputStartLine


+ (n
* OutputLineIncrement


)

through

OutputStartLine


+ ((n
+ 1) * OutputLineIncrement


) - 1

If absent RepeatCount and OutputLineIncrement default to one. If absent LineFileID defaults to the most recent value (initially zero).

The first line of a file is line one. RepeatCount is greater than or equal to one. Each LineFileID must be a file ID present in the FileSection . InputStartLine is greater than or equal to one. OutputStartLine is greater than or equal to one. OutputLineIncrement is greater than or equal to zero. A LineSection may only occur after a StratumSection .

For example:

      *L
      123:207
      130,3:210
      140:250,7
      160,3:300,2

Creates this mapping

Input Source Output Source Line Begin Line End Line
123 207 207
130 210 210
131 211 211
132 212 212
140 250 256
160 300 301
161 302 303
162 304 305

Note that multiple LineInfo may map multiple input source lines to a single output source line, when such a LineSection is being used to map output source lines to input source lines, a first matching LineInfo rule applies.

Note also that multiple LineInfo may map a single input source line to a multiple, possibly disjoint, output source lines, when such a LineSection is being used to map input source lines to output source lines, a first matching LineInfo rule again applies.

VendorSection

The vendor section is for vendor specific information.

The format is "*V " on the first line to mark the section. The second line is the vendor ID which is formed by the same rules by which unique package names are formed in the Java language specification, second edition (?7.7) Unique Package Names . It includes the following lines until another section marker.

EndSection

The end section marks the end of an SMAP, it consists simply of a "*E " marker. The end section must be the last line of an SMAP.

EmbeddedSourceMaps

The OpenEmbeddedSection marks the beginning and CloseEmbeddedSection the end of a set of EmbeddedSourceMaps . These SMAPs correspond to the input source for a language-processor. The stratum of the language-processor is indicated on both sections. These sections must not occur in a resolved SMAP.

The format is the "*O " marker and the name of the output stratum on the first line. This is followed by the set of embedded SMAPs. The embedded SMAPs are included "whole" - from the SMAP to the EndSection "*E " marker - inclusive. Finally, the "*C " marker and the name of the output stratum on the last line terminates the embedded SMAPs.

SMAP Syntax


SMAP:
Header { Section } EndSection

Header :
ID OutputFileName DefaultStratumId

ID:
SMAP CR

OutputFileName:
NONASTERISKSTRING CR

DefaultStratumId:
NONASTERISKSTRING CR

Section:
StratumSection
FileSection
LineSection
EmbeddedSourceMaps
VendorSection
FutureSection

EmbeddedSourceMaps :
OpenEmbeddedSection { SMAP } CloseEmbeddedSection

OpenEmbeddedSection :
*O StratumID CR

CloseEmbeddedSection :
*C StratumID CR

StratumSection :
*S StratumID CR

StratumID :
NONASTERISKSTRING

LineSection :
*L CR { LineInfo }

LineInfo :
InputLineInfo
: OutputLineInfo CR

InputLineInfo :
InputStartLine
, RepeatCount
InputStartLine

OutputLineInfo :
OutputStartLine
, OutputLineIncrement
OutputStartLine

InputStartLine :
NUMBER
NUMBER
# LineFileID

LineFileID :
FileID

RepeatCount :
NUMBER

OutputStartLine :
NUMBER

OutputLineIncrement :
NUMBER

FileSection :
*F CR { FileInfo }

FileInfo :
FileID FileName CR
+ FileID FileName CR AbsoluteFileName CR

FileID :
NUMBER

FileName:
NONASTERISKSTRING

AbsoluteFileName:
NONASTERISKSTRING

VendorSection:
*V CR VENDORID CR { VendorInfo }

VendorInfo:
NONASTERISKSTRING CR

FutureSection:
* OTHERCHAR CR { FutureInfo }

FutureInfo:
NONASTERISKSTRING CR

EndSection:
*E CR

Where {x} denotes zero or more occurrences of x . And where the terminals are defined as follows (whitespace is a sequence of zero or more spaces or tabs):

Terminals
NONASTERISKSTRING Any sequence of characters (excluding the terminal carriage-return or new-line) which does not start with "*". Leading whitespace is ignored.
NUMBER Non negative decimal integer. The number is terminated by the first non-digit character. Leading and trailing whitespace is ignored.
CR a line terminator: carriage-return, carriage-return followed by new-line or new-line.
OTHERCHAR Any character (other than carriage-return, new-line, space or tab) not already used as a section header (not S,F,L,V,O,C or E).
VENDORID A sequence of characters that identifies a vendor. The name is formed by the same rules that unique package names are formed in the Java language specification. Leading and trailing whitespace is ignored. The terminal carriage-return or new-line is excluded.


SMAP Resolution

Before the SMAP in a SMAP-file can be installed into the SourceDebugExtension attribute it must be resolved into an SMAP with no embedded SMAPs and with final-source as the output source. A set of embedded SMAPs is specific to a stratum and is resolved in the context of the matching StratumSection in the outer SMAP. The resolved SMAP includes StratumSections computed from each set of embedded SMAPs as well as the unchanged StratumSections of the outer SMAP. If embedded SMAPs are nested, the inner-most is resolved first.

The structure of an SMAP with embedded SMAPs is as follows:

SMAP
...
*O B
SMAP
...
*S A
...
*E
*C B
...
*S B
...
*E

The structure is a set of embedded SMAPs (for a stratum, here named B ), an outer StratumSection (for B ), and an embedded SMAP with a StratumSection (for a stratum, here named A ). Note that: there may be many sets of embedded SMAPs, many embedded SMAPs within the set of embedded SMAPs, and many StratumSections within an SMAP. A StratumSection maps source information from its stratum to an output stratum. Thus, the embedded StratumSection maps stratum A to stratum B . We know it is mapped to stratum B because the set of embedded SMAPs for stratum B corresponds to the input for the language-processor for B . The outer StratumSection maps stratum B to its output stratum (let's call this stratum C ), if the shown SMAP is the outer-most SMAP then stratum C is the final-source stratum. The purpose of resolution is to create a non-embedded StratumSection for A which maps to C (all StratumSections within an SMAP must map to the same output stratum, in a resolved outer-most SMAP all StratumSections will map to the final-source stratum). This is done by composing the mapping in the embedded StratumSection (from A to B ) with the mapping in the outer StratumSection (from B to C ). Since there may be many embedded StratumSections for A , these sections must be merged.

A StratumSection is computed for each stratum present in the embedded SMAPs. The computed StratumSection is the merge of each embedded StratumSection, for that stratum. Line number information is composed with the line number information of the outer StratumSection (note that the embedded StratumSections cannot be for the same stratum as the outer StratumSection). Specifically, a computed StratumSection consists of a merged FileSection , a composed LineSection , and direct copies of any VendorSection s or unknown sections. The merged FileSection includes each unique FileInfo , with FileIDs reassigned to be unique. The composition the LineSections is described in the algorithm below.

LineInfo Composition Algorithm

The following pseudo-code sketches the algorithm for resolving LineInfo in embedded SMAPs. LineInfo resolution is by composition - discussed above. An embedded LineInfo which maps stratum A to stratum B is composed with an outer LineInfo which maps stratum B to stratum C to create a new resolved LineInfo which maps stratum A to stratum C .

The SMAPs and their components are marked by subscript:

  • Embedded SMAP - levelE
  • Outer StratumSection - levelO
  • Resolved computed StratumSection - levelR

The inputs and outputs of the algorithm are LineInfo tuples. Line information is represented in this algorithm in its LineInfo format which is discussed in the LineSection This algorithm is invoked for each LineInfoE in each embedded SMAP.

ResolveLineInfo:
InputStartLineE #LineFileIDE , RepeatCountE : OutputStartLineE , OutputLineIncrementE
as follows {
if RepeatCountE > 0 then {
for each LineInfoO in the stratum of the embedded SMAP :
InputStartLineO #LineFileIDO , RepeatCountO : OutputStartLineO , OutputLineIncrementO
which includes OutputStartLineE
that is, InputStartLineO + N == OutputStartLineE
for some offset into the outer input range N where 0 <= N < RepeatCountO
and for which LineFileIDO has a sourceName matching the embedded SMAP's OutputFileName {
compute the number of outer mapping repeations which can be applied
available := RepeatCountO - N ;
compute the number of embedded mapping repeations which can be applied
completeCount :=
floor (available / OutputLineIncrementE ) min RepeatCountE ;
if completeCount > 0 then {
output resolved LineInfo
InputStartLineE #
uniquify (LineFileIDE ), completeCount :
(OutputStartLineO + (N * OutputLineIncrementO )),
(OutputLineIncrementE * OutputLineIncrementO ) ;
ResolveLineInfo
(InputStartLineE + completeCount ) #LineFileIDE , (RepeatCountE - completeCount ) :
(OutputStartLineE + completeCount * OutputLineIncrementE ), OutputLineIncrementE ;
}
else {
output resolved LineInfo
InputStartLineE #
uniquify (LineFileIDE ), 1 :
(OutputStartLineO + (N * OutputLineIncrementO )), available ;
ResolveLineInfo
InputStartLineE #LineFileIDE , 1 :
(OutputStartLineE + available ), (OutputLineIncrementE - available ) ;
ResolveLineInfo
(InputStartLineE + 1) #LineFileIDE , (RepeatCountE - 1):
(OutputStartLineE + OutputLineIncrementE ), OutputLineIncrementE ;
}
}
}
}

where uniquify converts a LineFileIDE to a corresponding LineFileIDR

Resolution Example

The following example demonstrates resolution with this algorithm. The general example will provide context before walking through this example. In this example, Incl.bar is included by Hi.bar , but each is the result of a prior translation.

| Hi.foo | Incl.foo
| |
language-processorFoo
language-processorFoo
| | | |
| Hi.bar | Hi.bar.smap | Incl.bar | Incl.bar.smap
| | | |
language-processorBar
| |
| Hi.java | Hi.java.smap
| |
javac compiler
|
| |
| Hi.class |
| |
post-processor
|
| Hi.class

If the unresolved SMAP (in Hi.java.smap ) is as follows

SMAP
Hi.java
Java
Outer Header
*O Bar OpenEmbeddedSection
SMAP
Hi.bar
Java
*S Foo
*F
1 Hi.foo
*L
1#1,5:1,2
*E
Embedded SMAP (Hi.bar)
SMAP
Incl.bar
Java
*S Foo
*F
1 Incl.foo
*L
1#1,2:1,2
*E
Embedded SMAP (Incl.bar)
*C Bar CloseEmbeddedSection
*S Bar
*F
1 Hi.bar
2 Incl.bar
*L
1#1:1
1#2,4:2
3#1,8:6
Outer StratumSection
*E Final EndSection

The merged levelR FileSection is (in stratum Foo ):

*F
1 Hi.foo
2 Incl.foo

The computation proceeds as follows --

LineInfoE LineInfoE
recursion 1 LineInfoE
recursion 2 matching
outer
LineInfoO resolved
LineInfoR discussion
1#1,5:1,2 1#1:1 1#1,1:1,1 ResolveLineInfo is called for 1#1,5:1,2 (from the first embedded SMAP - OutputFileName is Hi.bar ). 1#1:1 is found as the outer StratumSection LineInfoO with InputStartLineO of 1 and LineFileIDO has a sourceName matching Hi.bar . N is 0, and completeCount is 0, thus the else branch is taken. available is 1 and thus output is 1#1,1:1,1 .
1#1,1:2,1 no match The remaining half of the initial LineInfoE mapping then must be resolved recursively, but there is no match and it is ignored.
2#1,4:3,2 3#1,8:6 2#1,4:6,2 The remaining mappings are also handled recursively. There is a matching LineInfoO . N is 0, and completeCount is 4, thus the if branch is taken.
6#1,0:11,2 n/a The recursive resolve descends deeper but does nothing since all of RepeatCountE has been mapped. The first LineInfoE is now resolved. Since it had only one LineInfoE the first SMAP is also resolved.
1#1,2:1,2 1#2,4:2 1#2,2:2,2 Now for the second SMAP (OutputFileName is Incl.bar ). FileIDE 1 in this SMAP is Incl.foo which corresponds to the remapped FileIDR 2. So the matching LineInfoO is 1#2,4:2 . N is 0, and completeCount is 2, so the if branch is taken.
3#1,0:5,2 n/a The recursive resolve does nothing since all the maps have been handled. Resolution is complete.

The resultant resolved SMAP is:

SMAP
Hi.java
Java
*S Foo
*F
1 Hi.foo
2 Incl.foo
*L
1#1,1:1,1
2#1,4:6,2
1#2,2:2,2
*S Bar
*F
1 Hi.bar
2 Incl.bar
*L
1#1:1
1#2,4:2
3#1,8:6
*E


JPDA Support

The Java Platform Debugger Architecture in the Merlin release has been extended in support of debugging other languages. The new APIs and APIs with comments changed to include reference to strata are listed below:

New APIs APIs with Changed Comments JVMDIJDWP - ReferenceType (2) Command Set JDWP - VirtualMachine (1) Command Set JDI - VirtualMachine interface JDI - ReferenceType interface JDI - Method interface JDI - Location interface
GetSourceDebugExtension
SourceDebugExtension Command (12)
SetDefaultStratum Command (19)
void setDefaultStratum(String stratum)
String getDefaultStratum()
String sourceNames(String stratum) String sourceName()
String sourcePaths(String stratum)
List allLineLocations(String stratum, String sourceName) List allLineLocations()
List locationsOfLine(String stratum, String sourceName, int lineNumber) List locationsOfLine(int lineNumber)
List availableStrata()
String defaultStratum()
String sourceDebugExtension()
List allLineLocations(String stratum, String sourceName) List allLineLocations()
List locationsOfLine(String stratum, String sourceName, int lineNumber) List locationsOfLine(int lineNumber)
class comment (strata defined)
int lineNumber(String stratum) int lineNumber()
String sourceName(String stratum) String sourceName()
String sourcePath(String stratum)
String sourcePath()


SourceDebugExtension Support

Debugger applications frequently need debugging information about the source that exceeds what is delivered by the existing JavaTM Virtual Machine class file attributes (SourceFile, LineNumber, and LocalVariable). This is particularly true for debugging the source of other languages. In a distributed environment side files may not be accessible, the information must be directly associated with the class.

The solution is the addition of a class file attribute which holds a string; The string contains debugging information in a standardized format which allows for evolution and vendor extension.

SourceDebugExtension Access

This string is made opaquely accessible at the three layers of the Java Platform Debugger Architecture (JPDA):

JVMDI JDWP JDI
GetSourceDebugExtension(jclass clazz, char **sourceDebugExtensionPtr)
SourceDebugExtension Command (12) in the ReferenceType (2) Command Set
String sourceDebugExtension() in the ReferenceType interface

SourceDebugExtension Class File Attribute

Java virtual machine class file attributes are described in section 4.7 of the The Java Virtual Machine Specification . The definition of the added attribute is in the context of The Java Virtual Machine Specification:

The SourceDebugExtension attribute is an optional attribute in the attributes table of the ClassFile structure. There can be no more than one SourceDebugExtension attribute in the attributes table of a given ClassFile structure.

The SourceDebugExtension attribute has the following format:


SourceDebugExtension_attribute {
u2 attribute_name_index;
u4 attribute_length;
u1 debug_extension[attribute_length];
}

The items of the SourceDebugExtension_attribute structure are as follows:

attribute_name_index
The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "SourceDebugExtension" .

attribute_length
The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus the number of bytes in the debug_extension[] item.

debug_extension[]
The debug_extension array holds a string, which must be in UTF-8 format. There is no terminating zero byte.

The string in the debug_extension item will be interpreted as extended debugging information. The content of this string has no semantic effect on the Java Virtual Machine.


Example

The example below shows how the process described above would apply to a tiny JSP program.

Input Source

The input consists of two JSP files, the first is Hello.jsp :

1 2 3 4 5 6 7 8
<HTML>
<HEAD>
<TITLE>Hello Example</TITLE>
</HEAD>
<BODY>
<%@ include file="greeting.jsp" %>
</BODY>
</HTML>

The second JSP file is the included file greeting.jsp :

1 2
Hello There!<P>
Goodbye on <%= new Date() %>

Language Processor

When a JSP compiler (the language-processor ) compiles these files it will produce two outputs - a Java programming language source file and a SMAP-file . The generated Java programming language source file is HelloServlet.java :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Hello.jsp:1
out.println("<HTML>");
// Hello.jsp:2
out.println("<HEAD>");
// Hello.jsp:3
out.println("<TITLE>Hello Example</TITLE>");
// Hello.jsp:4
out.println("</HEAD>");
// Hello.jsp:5
out.println("<BODY>");
// greeting.jsp:1
out.println("Hello There!<P>");
// greeting.jsp:2
out.println("Goodbye on " + new Date() );
// Hello.jsp:7
out.println("</BODY>");
// Hello.jsp:8
out.println("</HTML>");
}
}

The generated SMAP-file is HelloServlet.java.smap :

SMAP
HelloServlet.java
JSP
*S JSP
*F
1 Hello.jsp
2 greeting.jsp
*L
1#1,5:10,2
1#2,2:20,2
7#1,2:24,2
*E

A couple things are interesting to note about this SMAP -- the user has chosen to make JSP the default stratum (perhaps by a command line option) and even though there are ten lines of input source and 29 lines of generated source, only three LineInfo lines describe the transformation: the first and last are for the lines before and after the include (respectively) and the middle is for the included file greeting.jsp .

The three LineInfo lines describe these mappings:

   1#1,5:10,2 
Hello.jsp: line 1 -> HelloServlet.java: lines 10, 11
line 2 -> lines 12, 13
line 3 -> lines 14, 15
line 4 -> lines 16, 17
line 5 -> lines 18, 19

1#2,2:20,2
greeting.jsp: line 1 -> HelloServlet.java: lines 20, 21
line 2 -> lines 22, 23

7#1,2:24,2
Hello.jsp: line 7 -> HelloServlet.java: lines 24, 25
line 8 -> lines 26, 27

Post Processor

Next HelloServlet.java is compiled by a Java programming language compiler (for example javac ) producing the class file HelloServlet.class . Then the post-processor is run. It takes HelloServlet.class and HelloServlet.java.smap as input. It creates a SourceDebugExtension attribute whose content is the SMAP in HelloServlet.java.smap and rewrites HelloServlet.class with this attribute.

Debugging

Now the program is run under the control of a debugger (which is a client of JDI ). Let's say we are stepping through this code and the debugger has just received a JDI StepEvent for the line that is just about to output <BODY> . The debugger's code might look like this (the StepEvent is in the variable stepEvent ):

Location location = stepEvent.location();
String sourceName = location.sourceName("Java");
int lineNumber = location.lineNumber("Java");
displaySource(sourceName, lineNumber);

where displaySource is a debugger routine that displays a source location. Because the Java stratum has been specified sourceName would be HelloServlet.java , the lineNumber would be 19 and the displayed line would be:

out.println("<BODY>");

However, if sourceName and lineNumber were derived as follows:

String sourceName = location.sourceName("JSP");
int lineNumber = location.lineNumber("JSP");

Since the JSP stratum has been specified, sourceName would be Hello.jsp , the lineNumber would be 5 and the displayed line would be:

<BODY>

This occurs because the SourceDebugExtension attribute was stored when the VM read HelloServlet.class and it was retrieved with the SourceDebugExtension JDWP command which in turn caused the JVMDI function call GetSourceDebugExtension. The SMAP in the SourceDebugExtension was parsed which provided the above transformation of source location. Specifically, the line:

1#1,5:10,2

is the basis of this transformation - which refers to FileId #1

1 Hello.jsp

and whence the sourceName information. Since the default stratum specified in the SMAP is JSP , the code:

String sourceName = location.sourceName();
int lineNumber = location.lineNumber();

would have the same effect. Since this is the form code would have taken before these extensions were introduced, existing debuggers can be utilized if they are run under the new implementation of JDI .


Debugging Support for Other Languages Specification ("Specification")
Version: 1.0
Status: FCS
Release: November 24, 2003

Copyright 2003 Sun Microsystems, Inc.

4150 Network Circle, Santa Clara, California 95054, U.S.A
All rights reserved.

NOTICE; LIMITED LICENSE GRANTS

Sun Microsystems, Inc. ("Sun") hereby grants you a fully-paid, non-exclusive, non-transferable, worldwide, limited license (without the right to sublicense), under the Sun's applicable intellectual property rights to view, download, use and reproduce the Specification only for the purpose of internal evaluation, which shall be understood to include developing applications intended to run on an implementation of the Specification provided that such applications do not themselves implement any portion(s) of the Specification.

Sun also grants you a perpetual, non-exclusive, worldwide, fully paid-up, royalty free, limited license (without the right to sublicense) under any applicable copyrights or patent rights it may have in the Specification to create and/or distribute an Independent Implementation of the Specification that: (i) fully implements the Spec(s) including all its required interfaces and functionality; (ii) does not modify, subset, superset or otherwise extend the Licensor Name Space, or include any public or protected packages, classes, Java interfaces, fields or methods within the Licensor Name Space other than those required/authorized by the Specification or Specifications being implemented; and (iii) passes the TCK (including satisfying the requirements of the applicable TCK Users Guide) for such Specification. The foregoing license is expressly conditioned on your not acting outside its scope. No license is granted hereunder for any other purpose.

You need not include limitations (i)-(iii) from the previous paragraph or any other particular "pass through" requirements in any license You grant concerning the use of your Independent Implementation or products derived from it. However, except with respect to implementations of the Specification (and products derived from them) that satisfy limitations (i)-(iii) from the previous paragraph, You may neither: (a) grant or otherwise pass through to your licensees any licenses under Sun's applicable intellectual property rights; nor (b) authorize your licensees to make any claims concerning their implementation's compliance with the Spec in question.

For the purposes of this Agreement: "Independent Implementation " shall mean an implementation of the Specification that neither derives from any of Sun's source code or binary code materials nor, except with an appropriate and separate license from Sun, includes any of Sun's source code or binary code materials; and "Licensor Name Space " shall mean the public class or interface declarations whose names begin with "java", "javax", "com.sun" or their equivalents in any subsequent naming convention adopted by Sun through the Java Community Process, or any recognized successors or replacements thereof.

This Agreement will terminate immediately without notice from Sun if you fail to comply with any material provision of or act outside the scope of the licenses granted above.

TRADEMARKS

No right, title, or interest in or to any trademarks, service marks, or trade names of Sun or Sun's licensors is granted hereunder. Sun, Sun Microsystems, the Sun logo, Java, and the Java Coffee Cup logo are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries.

DISCLAIMER OF WARRANTIES

THE SPECIFICATION IS PROVIDED "AS IS". SUN MAKES NO REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE OR THAT ANY PRACTICE OR IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADE SECRETS OR OTHER RIGHTS. This document does not represent any commitment to release or implement any portion of the Specification in any product.

THE SPECIFICATION COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION THEREIN; THESE CHANGES WILL BE INCORPORATED INTO NEW VERSIONS OF THE SPECIFICATION, IF ANY. SUN MAY MAKE IMPROVEMENTS AND/OR CHANGES TO THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THE SPECIFICATION AT ANY TIME. Any use of such changes in the Specification will be governed by the then-current license for the applicable version of the Specification.

LIMITATION OF LIABILITY

TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION, LOST REVENUE, PROFITS OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO ANY FURNISHING, PRACTICING, MODIFYING OR ANY USE OF THE SPECIFICATION, EVEN IF SUN AND/OR ITS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

You will indemnify, hold harmless, and defend Sun and its licensors from any claims arising or resulting from: (i) your use of the Specification; (ii) the use or distribution of your Java application, applet and/or clean room implementation; and/or (iii) any claims that later versions or releases of any Specification furnished to you are incompatible with the Specification provided to you under this license.

RESTRICTED RIGHTS LEGEND

U.S. Government: If this Specification is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in the Specification and accompanying documentation shall be only as set forth in this license; this is in accordance with 48 C.F.R. 227.7201 through 227.7202-4 (for Department of Defense (DoD) acquisitions) and with 48 C.F.R. 2.101 and 12.212 (for non-DoD acquisitions).

REPORT

You may wish to report any ambiguities, inconsistencies or inaccuracies you may find in connection with your use of the Specification ("Feedback"). To the extent that you provide Sun with any Feedback, you hereby: (i) agree that such Feedback is provided on a non-proprietary and non-confidential basis, and (ii) grant Sun a perpetual, non-exclusive, worldwide, fully paid-up, irrevocable license, with the right to sublicense through multiple levels of sublicensees, to incorporate, disclose, and use without limitation the Feedback for any purpose related to the Specification and future versions, implementations, and test suites thereof.

(LFI#136249/Form ID#011801)


<!-- hhmts start -->

Last modified: Fri Oct 3 14:48:10 PDT 2003

<!-- hhmts end -->

<!-- body="end" -->


分享到:
评论

相关推荐

    JSR-303接口标准和参考实现

    JSR-303接口标准,全称为Java Specification Request 303,是Java平台上的一个规范,旨在提供一种统一的、与框架无关的bean验证框架。该标准由Java Community Process(JCP)提出,目的是简化Java应用中的数据验证...

    JSR-133-JMM.zip

    本文是JSR-133规范,即JavaTM内存模型与线程规范,由JSR-133专家组开发。本规范是JSR-176(定义了JavaTM平台 Tiger(5.0)发布版的主要特性)的一部分。本规范的标准内容将合并到JavaTM语言规范、JavaTM虚拟机规范...

    JSR-107 标准手册 Specification

    JSR-107,即JCache API,是一个旨在为Java程序提供与缓存系统交互的API规范。在Java社区中,分布式缓存对于提升系统的性能和可伸缩性起着至关重要的作用。然而,直到JSR-107标准的出现之前,Java平台并没有一个完整...

    JSR-133-ZH.pdf

    《JSR-133:JavaTM内存模型与线程规范》是Java多线程编程领域的重要指导文档,由JSR-133专家组制定,旨在解决Java平台中并发编程时可能出现的问题,确保多线程环境下的正确性和可预测性。这份规范与JavaTM平台Tiger...

    JSR-168 Portlet指南.doc

    遵循JSR-168规范开发的portlet,可以在多种支持该规范的门户服务器之间轻松迁移,因为大多数基于Java的门户服务器都实现了JSR-168接口。 **一、JSR-168的优势** 1. **可移植性**:JSR-168定义了一套标准接口和生命...

    JSR-000257 Contactless Communication API 1.0 Final Release

    **JSR-000257 Contactless Communication API 1.0 Final Release** 是一个针对移动设备,尤其是Java ME(J2ME)平台的规范,它定义了如何在这些设备上实现非接触式通信(NFC)技术。NFC,全称Near Field ...

    spring3零配置注解实现Bean定义(包括JSR-250、JSR-330)

    - **JSR-250**:这是Java标准组织提出的一套注解规范,其中包含了`@ManagedBean`注解,用于指示一个类作为JavaBean管理,虽然Spring并不直接支持`@ManagedBean`,但在某些场景下可能会用到。 - **JSR-330**:又称为...

    JSR-94的API,最终版的

    JSR-94(Java Specification Request 94)是Java平台企业版(Java EE)中的一个规范,它定义了一个标准接口,使得开发者能够将规则引擎集成到Java应用程序中。这个API允许应用程序与规则引擎进行交互,执行业务规则...

    用JSR-88往Java EE应用服务器上部署应用

    JSR-88 就是关于“Java Deployment ToolKit”的规范,它提供了一套API,使得开发者可以编写程序来自动部署Java EE应用程序到应用服务器,如Tomcat、WebLogic、GlassFish等。 **描述解析:** 描述中提到的“NULL”...

    Portlet JSR-168标准手册跟帮助文档

    Portlet JSR-168标准是Java社区进程(Java Community Process)发布的一个重要规范,主要定义了如何在门户环境中创建可重用的Web组件,即portlet。这项标准的出现,使得开发者能够构建独立的、可插拔的应用模块,...

    Portlet JSR-170标准手册跟帮助文档

    1. **Portlet容器**:Portlet容器是运行portlet的环境,它实现了JSR-170规范,并提供portlet生命周期管理、渲染、事件处理等服务。 2. **Portlet生命周期**:portlet有三个主要的生命周期阶段:初始化、渲染和销毁...

    JSR133中文版.pdf

    本文是JSR-133规范,即JavaTM内存模型与线程规范,由JSR-133专家组开发。本规范是JSR-176(定义了JavaTM平台 Tiger(5.0)发布版的主要特性)的一部分。本规范的标准内容将合并到JavaTM语言规范、JavaTM虚拟机规范...

    Personal Basis Profile Reference Implmentation 1.1 Final Release(JSR-217)

    "Reference Implementation"(参考实现)是指根据JSR-217规范创建的可执行代码,它为其他开发者提供了实现该规范的起点和参考。这个实现是开源的,允许开发者和制造商测试、修改和扩展,以确保其符合标准,并且能在...

    JSR-107 文档

    JSR-107是Java社区中的一个规范,名为Java缓存API,它为Java程序与缓存系统进行交互提供了标准的API。该规范的主要目的是简化Java应用中的缓存操作,提供一种统一的方式来管理缓存数据。Java缓存API,即JSR-107,...

    Java EE Security (JSR-375) Specification.zip

    Java EE Security(JSR-375)是Java企业版(Java EE)平台的一个关键组件,专注于增强应用程序的安全性。这个规范定义了如何在Java EE环境中集成和管理安全功能,以便为开发人员提供一个标准、统一的方式来处理安全...

    jpa2.0(JSR-317) 规范 包含javadoc

    该草案获得JSR-317专家组全部通过 新增了大量的特性包括类型安全的动态查询(Criteria API );加入了大量必须的 ORM 映射增强特性;标准的二级缓存,标准的 JDBC properties ,指定超时时间等等; 目前hibernate 3.5 ...

    JSR-179_Location_API_for_J2ME.zip_j2me 1_j2me gps_j2me gps jsr17

    "jsr179_Final_Release10.pdf" 这份文档很可能是JSR-179的官方规范或开发者指南,它详细阐述了API的使用方法、示例代码以及实现细节。通过阅读这份文档,开发者可以深入理解如何在J2ME应用中有效利用JSR-179进行位置...

    SpringMVC使用JSR-303进行验证Bean.docx

    SpringMVC框架结合JSR-303(也称为JSR-349,Java Bean Validation)规范提供了一种优雅的方式来处理数据验证。本篇文章将详细介绍如何在SpringMVC中使用JSR-303进行Bean验证。 首先,我们需要引入JSR-303的实现库。...

    JSR-268

    JSR-286,即Java Specification Request 286,是Portlet规范的第二版,它对前一版本JSR-168进行了大幅度的改进和扩展。JSR-286旨在为门户和Portlet开发者提供更强大、更灵活的功能集。 #### JSR-168概述 - **...

    webbeans--jsr-299

    标题:WebBeans -- JSR-299 描述:WebBeans是Gavin King的力作,专注于为Java EE平台提供上下文与依赖注入(Contexts and Dependency Injection)。 ### WebBeans (JSR-299) 知识点详解 #### 一、架构与合同 Web...

Global site tag (gtag.js) - Google Analytics