- 浏览: 168709 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
Vcb:
http://osgi.jxtech.net 是目前发现最好的 ...
OSGi控制台在Eclipse插件开发中的妙用 -
zxjlwt:
学习了。http://surenpi.com
OSGi控制台在Eclipse插件开发中的妙用 -
enen1982:
这个写得相当不错,找了好久,省了我一堆事,能不能复制整个目录
Eclipse插件中如何读取插件项目下的文件 -
yhyysxqygs:
用到起了
为RCP程序添加帮助支持 -
ququsxc:
这个一定要顶
Eclipse插件中如何读取插件项目下的文件
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
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.
Term Definition final-source The final form of source. This source will be compiled into a class file . Typically, final-source is Java programming language source. translated-source Source that will be translated by a language-processor into another language or form. language-processor Converts translated-source to final-source or to different translated-source . class file A collection of bytes in Java virtual machine class file format. compiler Compiler which converts final-source to class files. For example, javac
is a compiler.post-processor Takes a class file and a Source Map File as input; generates a class file as output. Inserts a SourceDebugExtension attribute . Source Map
SMAPSpecifies the mapping of source between one or more sets of input source and the output source. See: Source Map Format . Source Map File
SMAP-fileSpecifies 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 . stratum A view of a class from a particular, named, programming language level. JPDA The Java Platform Debugger Architecture . JDI The Java Debug Interface, which is the high-level Java programming language interface of the Java Platform Debugger Architecture . See: JDI Specification . SourceDebugExtension
attributeA 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
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 ).
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.
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 | |||||||||||||||||
| | | | |||||||||||||||||||
|
|
|||||||||||||||||||
| | | | | | | | |||||||||||||||||
| | TS1a | | | SMAP1a | | | TS1b | | | SMAP1b | |||||||||||||
| | | | | | | | |||||||||||||||||
|
||||||||||||||||||||
| | | | |||||||||||||||||||
| | FS | | | SMAP2 | |||||||||||||||||
| | | | |||||||||||||||||||
|
| | |||||||||||||||||||
| | | | |||||||||||||||||||
| | class file | | | ||||||||||||||||||
| | | | |||||||||||||||||||
|
||||||||||||||||||||
| | ||||||||||||||||||||
| | class file | |||||||||||||||||||
| | ||||||||||||||||||||
|
||||||||||||||||||||
| | | | |||||||||||||||||||
| | FS location | | | SMAP via SourceDebugExtension | |||||||||||||||||
| | | | |||||||||||||||||||
|
||||||||||||||||||||
| | ||||||||||||||||||||
| | TS location | |||||||||||||||||||
| | ||||||||||||||||||||
|
Where TS
is translated-source
and FS
is final-source
.
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.
The ability to choose the source level to view is addressed in this JSR. These are referred to as strata .
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.
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.
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.
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
.
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.
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.
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.
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.
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:
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):
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. |
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
BSMAP
...*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{
ifRepeatCountE > 0
then{
for eachLineInfoO
in the stratum of the embedded SMAP:
which includes
InputStartLineO #LineFileIDO , RepeatCountO : OutputStartLineO , OutputLineIncrementOOutputStartLineE
that is,InputStartLineO + N == OutputStartLineE
for some offset into the outer input rangeN
where0 <= N < RepeatCountO
and for whichLineFileIDO
has a sourceName matching the embedded SMAP'sOutputFileName {
compute the number of outer mapping repeations which can be appliedcompute the number of embedded mapping repeations which can be applied
available := RepeatCountO - N ;floor
completeCount :=(available / OutputLineIncrementE )
minRepeatCountE ;
ifcompleteCount > 0
then{
output resolved LineInfouniquify
InputStartLineE #(LineFileIDE ), completeCount :
else
(OutputStartLineO + (N * OutputLineIncrementO )),
(OutputLineIncrementE * OutputLineIncrementO ) ;
ResolveLineInfo
(InputStartLineE + completeCount ) #LineFileIDE , (RepeatCountE - completeCount ) :
(OutputStartLineE + completeCount * OutputLineIncrementE ), OutputLineIncrementE ;
}{
output resolved LineInfouniquify
InputStartLineE #(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
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 | |||||||||||||||||
| | | | |||||||||||||||||||
|
|
|||||||||||||||||||
| | | | | | | | |||||||||||||||||
| | Hi.bar | | | Hi.bar.smap | | | Incl.bar | | | Incl.bar.smap | |||||||||||||
| | | | | | | | |||||||||||||||||
|
||||||||||||||||||||
| | | | |||||||||||||||||||
| | Hi.java | | | Hi.java.smap | |||||||||||||||||
| | | | |||||||||||||||||||
|
| | |||||||||||||||||||
| | | | |||||||||||||||||||
| | Hi.class | | | ||||||||||||||||||
| | | | |||||||||||||||||||
|
||||||||||||||||||||
| | ||||||||||||||||||||
| | Hi.class |
If the unresolved SMAP (in Hi.java.smap
) is as follows
SMAP
Hi.java
JavaOuter Header *O Bar
OpenEmbeddedSection SMAP
Hi.bar
Java
*S Foo
*F
1 Hi.foo
*L
1#1,5:1,2
*EEmbedded SMAP (Hi.bar) SMAP
Incl.bar
Java
*S Foo
*F
1 Incl.foo
*L
1#1,2:1,2
*EEmbedded 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:6Outer StratumSection *E
Final EndSection
The merged levelR
FileSection is (in stratum Foo
):
*F
1 Hi.foo
2 Incl.foo
The computation proceeds as follows --
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
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:
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.
This string is made opaquely accessible at the three layers of the Java Platform Debugger Architecture (JPDA):
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 The items of the SourceDebugExtension_attribute
structure are as follows:
attribute_name_index
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
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[]
debug_extension
array holds a string, which must be
in UTF-8 format. There is no terminating zero byte.
The string in the |
The example below shows how the process described above would apply to a tiny JSP program.
The input consists of two JSP
files, the first is Hello.jsp
:
<HTML>
|
<HEAD>
|
<TITLE>Hello Example</TITLE>
|
</HEAD>
|
<BODY>
|
<%@ include file="greeting.jsp" %>
|
</BODY>
|
</HTML>
|
The second JSP file is the included file greeting.jsp
:
Hello There!<P>
|
Goodbye on <%= new Date() %>
|
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
:
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
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.
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接口标准,全称为Java Specification Request 303,是Java平台上的一个规范,旨在提供一种统一的、与框架无关的bean验证框架。该标准由Java Community Process(JCP)提出,目的是简化Java应用中的数据验证...
本文是JSR-133规范,即JavaTM内存模型与线程规范,由JSR-133专家组开发。本规范是JSR-176(定义了JavaTM平台 Tiger(5.0)发布版的主要特性)的一部分。本规范的标准内容将合并到JavaTM语言规范、JavaTM虚拟机规范...
JSR-107,即JCache API,是一个旨在为Java程序提供与缓存系统交互的API规范。在Java社区中,分布式缓存对于提升系统的性能和可伸缩性起着至关重要的作用。然而,直到JSR-107标准的出现之前,Java平台并没有一个完整...
《JSR-133:JavaTM内存模型与线程规范》是Java多线程编程领域的重要指导文档,由JSR-133专家组制定,旨在解决Java平台中并发编程时可能出现的问题,确保多线程环境下的正确性和可预测性。这份规范与JavaTM平台Tiger...
遵循JSR-168规范开发的portlet,可以在多种支持该规范的门户服务器之间轻松迁移,因为大多数基于Java的门户服务器都实现了JSR-168接口。 **一、JSR-168的优势** 1. **可移植性**:JSR-168定义了一套标准接口和生命...
**JSR-000257 Contactless Communication API 1.0 Final Release** 是一个针对移动设备,尤其是Java ME(J2ME)平台的规范,它定义了如何在这些设备上实现非接触式通信(NFC)技术。NFC,全称Near Field ...
- **JSR-250**:这是Java标准组织提出的一套注解规范,其中包含了`@ManagedBean`注解,用于指示一个类作为JavaBean管理,虽然Spring并不直接支持`@ManagedBean`,但在某些场景下可能会用到。 - **JSR-330**:又称为...
JSR-94(Java Specification Request 94)是Java平台企业版(Java EE)中的一个规范,它定义了一个标准接口,使得开发者能够将规则引擎集成到Java应用程序中。这个API允许应用程序与规则引擎进行交互,执行业务规则...
JSR-88 就是关于“Java Deployment ToolKit”的规范,它提供了一套API,使得开发者可以编写程序来自动部署Java EE应用程序到应用服务器,如Tomcat、WebLogic、GlassFish等。 **描述解析:** 描述中提到的“NULL”...
Portlet JSR-168标准是Java社区进程(Java Community Process)发布的一个重要规范,主要定义了如何在门户环境中创建可重用的Web组件,即portlet。这项标准的出现,使得开发者能够构建独立的、可插拔的应用模块,...
1. **Portlet容器**:Portlet容器是运行portlet的环境,它实现了JSR-170规范,并提供portlet生命周期管理、渲染、事件处理等服务。 2. **Portlet生命周期**:portlet有三个主要的生命周期阶段:初始化、渲染和销毁...
本文是JSR-133规范,即JavaTM内存模型与线程规范,由JSR-133专家组开发。本规范是JSR-176(定义了JavaTM平台 Tiger(5.0)发布版的主要特性)的一部分。本规范的标准内容将合并到JavaTM语言规范、JavaTM虚拟机规范...
"Reference Implementation"(参考实现)是指根据JSR-217规范创建的可执行代码,它为其他开发者提供了实现该规范的起点和参考。这个实现是开源的,允许开发者和制造商测试、修改和扩展,以确保其符合标准,并且能在...
JSR-107是Java社区中的一个规范,名为Java缓存API,它为Java程序与缓存系统进行交互提供了标准的API。该规范的主要目的是简化Java应用中的缓存操作,提供一种统一的方式来管理缓存数据。Java缓存API,即JSR-107,...
Java EE Security(JSR-375)是Java企业版(Java EE)平台的一个关键组件,专注于增强应用程序的安全性。这个规范定义了如何在Java EE环境中集成和管理安全功能,以便为开发人员提供一个标准、统一的方式来处理安全...
该草案获得JSR-317专家组全部通过 新增了大量的特性包括类型安全的动态查询(Criteria API );加入了大量必须的 ORM 映射增强特性;标准的二级缓存,标准的 JDBC properties ,指定超时时间等等; 目前hibernate 3.5 ...
"jsr179_Final_Release10.pdf" 这份文档很可能是JSR-179的官方规范或开发者指南,它详细阐述了API的使用方法、示例代码以及实现细节。通过阅读这份文档,开发者可以深入理解如何在J2ME应用中有效利用JSR-179进行位置...
SpringMVC框架结合JSR-303(也称为JSR-349,Java Bean Validation)规范提供了一种优雅的方式来处理数据验证。本篇文章将详细介绍如何在SpringMVC中使用JSR-303进行Bean验证。 首先,我们需要引入JSR-303的实现库。...
JSR-286,即Java Specification Request 286,是Portlet规范的第二版,它对前一版本JSR-168进行了大幅度的改进和扩展。JSR-286旨在为门户和Portlet开发者提供更强大、更灵活的功能集。 #### JSR-168概述 - **...
标题:WebBeans -- JSR-299 描述:WebBeans是Gavin King的力作,专注于为Java EE平台提供上下文与依赖注入(Contexts and Dependency Injection)。 ### WebBeans (JSR-299) 知识点详解 #### 一、架构与合同 Web...