Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
J
jdk17u
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
einsteinathome
openjdk
jdk17u
Commits
45628a35
Commit
45628a35
authored
Dec 4, 2018
by
Erik Helin
Browse files
Options
Downloads
Patches
Plain Diff
8214230: Classes generated by SystemModulesPlugin.java are not reproducable
Reviewed-by: alanb, redestad, mchung
parent
3e2804d0
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
+29
-13
29 additions, 13 deletions
...jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
test/jdk/tools/jlink/JLinkReproducibleTest.java
+114
-0
114 additions, 0 deletions
test/jdk/tools/jlink/JLinkReproducibleTest.java
with
143 additions
and
13 deletions
src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
+
29
−
13
View file @
45628a35
...
@@ -52,6 +52,7 @@ import java.util.Map;
...
@@ -52,6 +52,7 @@ import java.util.Map;
import
java.util.Objects
;
import
java.util.Objects
;
import
java.util.Optional
;
import
java.util.Optional
;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.TreeMap
;
import
java.util.TreeSet
;
import
java.util.TreeSet
;
import
java.util.function.IntSupplier
;
import
java.util.function.IntSupplier
;
import
java.util.function.Supplier
;
import
java.util.function.Supplier
;
...
@@ -925,7 +926,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -925,7 +926,7 @@ public final class SystemModulesPlugin implements Plugin {
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/util/Map$Entry"
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/util/Map$Entry"
);
int
index
=
0
;
int
index
=
0
;
for
(
Map
.
Entry
<
String
,
Set
<
String
>>
e
:
map
.
entrySet
())
{
for
(
var
e
:
new
TreeMap
<>(
map
)
.
entrySet
())
{
String
name
=
e
.
getKey
();
String
name
=
e
.
getKey
();
Set
<
String
>
s
=
e
.
getValue
();
Set
<
String
>
s
=
e
.
getValue
();
...
@@ -971,7 +972,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -971,7 +972,7 @@ public final class SystemModulesPlugin implements Plugin {
pushInt
(
mv
,
size
);
pushInt
(
mv
,
size
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/String"
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/String"
);
int
i
=
0
;
int
i
=
0
;
for
(
String
element
:
set
)
{
for
(
String
element
:
sorted
(
set
)
)
{
mv
.
visitInsn
(
DUP
);
mv
.
visitInsn
(
DUP
);
pushInt
(
mv
,
i
);
pushInt
(
mv
,
i
);
mv
.
visitLdcInsn
(
element
);
mv
.
visitLdcInsn
(
element
);
...
@@ -985,7 +986,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -985,7 +986,7 @@ public final class SystemModulesPlugin implements Plugin {
true
);
true
);
}
else
{
}
else
{
StringBuilder
sb
=
new
StringBuilder
(
"("
);
StringBuilder
sb
=
new
StringBuilder
(
"("
);
for
(
String
element
:
set
)
{
for
(
String
element
:
sorted
(
set
)
)
{
mv
.
visitLdcInsn
(
element
);
mv
.
visitLdcInsn
(
element
);
sb
.
append
(
"Ljava/lang/Object;"
);
sb
.
append
(
"Ljava/lang/Object;"
);
}
}
...
@@ -1146,7 +1147,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1146,7 +1147,7 @@ public final class SystemModulesPlugin implements Plugin {
pushInt
(
mv
,
requires
.
size
());
pushInt
(
mv
,
requires
.
size
());
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/module/ModuleDescriptor$Requires"
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/module/ModuleDescriptor$Requires"
);
int
arrayIndex
=
0
;
int
arrayIndex
=
0
;
for
(
Requires
require
:
requires
)
{
for
(
Requires
require
:
sorted
(
requires
)
)
{
String
compiledVersion
=
null
;
String
compiledVersion
=
null
;
if
(
require
.
compiledVersion
().
isPresent
())
{
if
(
require
.
compiledVersion
().
isPresent
())
{
compiledVersion
=
require
.
compiledVersion
().
get
().
toString
();
compiledVersion
=
require
.
compiledVersion
().
get
().
toString
();
...
@@ -1192,7 +1193,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1192,7 +1193,7 @@ public final class SystemModulesPlugin implements Plugin {
pushInt
(
mv
,
exports
.
size
());
pushInt
(
mv
,
exports
.
size
());
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/module/ModuleDescriptor$Exports"
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/module/ModuleDescriptor$Exports"
);
int
arrayIndex
=
0
;
int
arrayIndex
=
0
;
for
(
Exports
export
:
exports
)
{
for
(
Exports
export
:
sorted
(
exports
)
)
{
mv
.
visitInsn
(
DUP
);
// arrayref
mv
.
visitInsn
(
DUP
);
// arrayref
pushInt
(
mv
,
arrayIndex
++);
pushInt
(
mv
,
arrayIndex
++);
newExports
(
export
.
modifiers
(),
export
.
source
(),
export
.
targets
());
newExports
(
export
.
modifiers
(),
export
.
source
(),
export
.
targets
());
...
@@ -1245,7 +1246,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1245,7 +1246,7 @@ public final class SystemModulesPlugin implements Plugin {
pushInt
(
mv
,
opens
.
size
());
pushInt
(
mv
,
opens
.
size
());
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/module/ModuleDescriptor$Opens"
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/module/ModuleDescriptor$Opens"
);
int
arrayIndex
=
0
;
int
arrayIndex
=
0
;
for
(
Opens
open
:
opens
)
{
for
(
Opens
open
:
sorted
(
opens
)
)
{
mv
.
visitInsn
(
DUP
);
// arrayref
mv
.
visitInsn
(
DUP
);
// arrayref
pushInt
(
mv
,
arrayIndex
++);
pushInt
(
mv
,
arrayIndex
++);
newOpens
(
open
.
modifiers
(),
open
.
source
(),
open
.
targets
());
newOpens
(
open
.
modifiers
(),
open
.
source
(),
open
.
targets
());
...
@@ -1310,7 +1311,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1310,7 +1311,7 @@ public final class SystemModulesPlugin implements Plugin {
pushInt
(
mv
,
provides
.
size
());
pushInt
(
mv
,
provides
.
size
());
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/module/ModuleDescriptor$Provides"
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/module/ModuleDescriptor$Provides"
);
int
arrayIndex
=
0
;
int
arrayIndex
=
0
;
for
(
Provides
provide
:
provides
)
{
for
(
Provides
provide
:
sorted
(
provides
)
)
{
mv
.
visitInsn
(
DUP
);
// arrayref
mv
.
visitInsn
(
DUP
);
// arrayref
pushInt
(
mv
,
arrayIndex
++);
pushInt
(
mv
,
arrayIndex
++);
newProvides
(
provide
.
service
(),
provide
.
providers
());
newProvides
(
provide
.
service
(),
provide
.
providers
());
...
@@ -1420,6 +1421,8 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1420,6 +1421,8 @@ public final class SystemModulesPlugin implements Plugin {
// Invoke ModuleHashes.Builder::hashForModule
// Invoke ModuleHashes.Builder::hashForModule
recordedHashes
recordedHashes
.
names
()
.
names
()
.
stream
()
.
sorted
()
.
forEach
(
mn
->
hashForModule
(
mn
,
recordedHashes
.
hashFor
(
mn
)));
.
forEach
(
mn
->
hashForModule
(
mn
,
recordedHashes
.
hashFor
(
mn
)));
// Put ModuleHashes into the hashes array
// Put ModuleHashes into the hashes array
...
@@ -1600,7 +1603,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1600,7 +1603,7 @@ public final class SystemModulesPlugin implements Plugin {
* it will reuse defaultVarIndex. For a Set with multiple references,
* it will reuse defaultVarIndex. For a Set with multiple references,
* it will use a new local variable retrieved from the nextLocalVar
* it will use a new local variable retrieved from the nextLocalVar
*/
*/
class
SetBuilder
<
T
>
{
class
SetBuilder
<
T
extends
Comparable
<
T
>
>
{
private
final
Set
<
T
>
elements
;
private
final
Set
<
T
>
elements
;
private
final
int
defaultVarIndex
;
private
final
int
defaultVarIndex
;
private
final
IntSupplier
nextLocalVar
;
private
final
IntSupplier
nextLocalVar
;
...
@@ -1660,7 +1663,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1660,7 +1663,7 @@ public final class SystemModulesPlugin implements Plugin {
if
(
elements
.
size
()
<=
10
)
{
if
(
elements
.
size
()
<=
10
)
{
// call Set.of(e1, e2, ...)
// call Set.of(e1, e2, ...)
StringBuilder
sb
=
new
StringBuilder
(
"("
);
StringBuilder
sb
=
new
StringBuilder
(
"("
);
for
(
T
t
:
elements
)
{
for
(
T
t
:
sorted
(
elements
)
)
{
sb
.
append
(
"Ljava/lang/Object;"
);
sb
.
append
(
"Ljava/lang/Object;"
);
visitElement
(
t
,
mv
);
visitElement
(
t
,
mv
);
}
}
...
@@ -1672,7 +1675,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1672,7 +1675,7 @@ public final class SystemModulesPlugin implements Plugin {
pushInt
(
mv
,
elements
.
size
());
pushInt
(
mv
,
elements
.
size
());
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/String"
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/String"
);
int
arrayIndex
=
0
;
int
arrayIndex
=
0
;
for
(
T
t
:
elements
)
{
for
(
T
t
:
sorted
(
elements
)
)
{
mv
.
visitInsn
(
DUP
);
// arrayref
mv
.
visitInsn
(
DUP
);
// arrayref
pushInt
(
mv
,
arrayIndex
);
pushInt
(
mv
,
arrayIndex
);
visitElement
(
t
,
mv
);
// value
visitElement
(
t
,
mv
);
// value
...
@@ -1690,7 +1693,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1690,7 +1693,7 @@ public final class SystemModulesPlugin implements Plugin {
* Generates bytecode to create one single instance of EnumSet
* Generates bytecode to create one single instance of EnumSet
* for a given set of modifiers and assign to a local variable slot.
* for a given set of modifiers and assign to a local variable slot.
*/
*/
class
EnumSetBuilder
<
T
>
extends
SetBuilder
<
T
>
{
class
EnumSetBuilder
<
T
extends
Comparable
<
T
>
>
extends
SetBuilder
<
T
>
{
private
final
String
className
;
private
final
String
className
;
...
@@ -1788,7 +1791,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1788,7 +1791,7 @@ public final class SystemModulesPlugin implements Plugin {
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/String"
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/String"
);
int
index
=
0
;
int
index
=
0
;
for
(
String
moduleName
:
map
.
keySet
())
{
for
(
String
moduleName
:
sorted
(
map
.
keySet
())
)
{
mv
.
visitInsn
(
DUP
);
// arrayref
mv
.
visitInsn
(
DUP
);
// arrayref
pushInt
(
mv
,
index
);
pushInt
(
mv
,
index
);
mv
.
visitLdcInsn
(
moduleName
);
mv
.
visitLdcInsn
(
moduleName
);
...
@@ -1811,7 +1814,7 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1811,7 +1814,7 @@ public final class SystemModulesPlugin implements Plugin {
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/String"
);
mv
.
visitTypeInsn
(
ANEWARRAY
,
"java/lang/String"
);
index
=
0
;
index
=
0
;
for
(
String
className
:
map
.
values
())
{
for
(
String
className
:
sorted
(
map
.
values
())
)
{
mv
.
visitInsn
(
DUP
);
// arrayref
mv
.
visitInsn
(
DUP
);
// arrayref
pushInt
(
mv
,
index
);
pushInt
(
mv
,
index
);
mv
.
visitLdcInsn
(
className
.
replace
(
'/'
,
'.'
));
mv
.
visitLdcInsn
(
className
.
replace
(
'/'
,
'.'
));
...
@@ -1831,6 +1834,19 @@ public final class SystemModulesPlugin implements Plugin {
...
@@ -1831,6 +1834,19 @@ public final class SystemModulesPlugin implements Plugin {
return
rn
;
return
rn
;
}
}
/**
* Returns a sorted copy of a collection.
*
* This is useful to ensure a deterministic iteration order.
*
* @return a sorted copy of the given collection.
*/
private
static
<
T
extends
Comparable
<
T
>>
List
<
T
>
sorted
(
Collection
<
T
>
c
)
{
var
l
=
new
ArrayList
<
T
>(
c
);
Collections
.
sort
(
l
);
return
l
;
}
/**
/**
* Pushes an int constant
* Pushes an int constant
*/
*/
...
...
This diff is collapsed.
Click to expand it.
test/jdk/tools/jlink/JLinkReproducibleTest.java
0 → 100644
+
114
−
0
View file @
45628a35
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.io.File
;
import
java.nio.file.*
;
import
java.util.*
;
import
static
jdk
.
test
.
lib
.
Asserts
.*;
import
jdk.test.lib.JDKToolFinder
;
import
jdk.test.lib.process.ProcessTools
;
/*
* @test
* @bug 8214230
* @summary Test that jlinks generates reproducible modules files
* @library /test/lib
* @run driver JLinkReproducibleTest
*/
public
class
JLinkReproducibleTest
{
private
static
void
run
(
List
<
String
>
cmd
)
throws
Exception
{
var
pb
=
new
ProcessBuilder
(
cmd
.
toArray
(
new
String
[
0
]));
var
res
=
ProcessTools
.
executeProcess
(
pb
);
res
.
shouldHaveExitValue
(
0
);
}
private
static
void
jlink
(
Path
image
)
throws
Exception
{
var
cmd
=
new
ArrayList
<
String
>();
cmd
.
add
(
JDKToolFinder
.
getJDKTool
(
"jlink"
));
cmd
.
addAll
(
List
.
of
(
"--module-path"
,
JMODS_DIR
.
toString
()
+
File
.
pathSeparator
+
CLASS_DIR
.
toString
(),
"--add-modules"
,
"main"
,
"--compress=2"
,
"--output"
,
image
.
toString
()
));
run
(
cmd
);
}
private
static
void
javac
(
String
...
args
)
throws
Exception
{
var
cmd
=
new
ArrayList
<
String
>();
cmd
.
add
(
JDKToolFinder
.
getJDKTool
(
"javac"
));
cmd
.
addAll
(
Arrays
.
asList
(
args
));
run
(
cmd
);
}
private
static
final
List
<
String
>
MODULE_INFO
=
List
.
of
(
"module main {"
,
" exports org.test.main;"
,
"}"
);
private
static
final
List
<
String
>
MAIN_CLASS
=
List
.
of
(
"package org.test.main;"
,
"public class Main {"
,
" public static void main(String[] args) {"
,
" System.out.println(\"Hello, world\");"
,
" }"
,
"}"
);
private
static
final
Path
CLASS_DIR
=
Path
.
of
(
"classes"
);
private
static
final
Path
JMODS_DIR
=
Path
.
of
(
System
.
getProperty
(
"java.home"
),
"jmods"
);
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// Write the source code
var
srcDir
=
Path
.
of
(
"main"
,
"org"
,
"test"
,
"main"
);
Files
.
createDirectories
(
srcDir
.
toAbsolutePath
());
var
srcFile
=
srcDir
.
resolve
(
"Main.java"
);
Files
.
write
(
srcFile
,
MAIN_CLASS
);
var
moduleFile
=
Path
.
of
(
"main"
).
resolve
(
"module-info.java"
);
Files
.
write
(
moduleFile
,
MODULE_INFO
);
// Compile the source code to class files
javac
(
"--module-source-path"
,
"."
,
"--module"
,
"main"
,
"-d"
,
CLASS_DIR
.
toString
());
// Link the first image
var
firstImage
=
Path
.
of
(
"image-first"
);
jlink
(
firstImage
);
var
firstModulesFile
=
firstImage
.
resolve
(
"lib"
)
.
resolve
(
"modules"
);
// Link the second image
var
secondImage
=
Path
.
of
(
"image-second"
);
jlink
(
secondImage
);
var
secondModulesFile
=
secondImage
.
resolve
(
"lib"
)
.
resolve
(
"modules"
);
// Ensure module files are identical
assertEquals
(-
1L
,
Files
.
mismatch
(
firstModulesFile
,
secondModulesFile
));
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment