Welcome to the OpenJDK Developers’ Guide!
The OpenJDK Community is the place to collaborate on open-sourceimplementations of the Java Platform, Standard Edition, and relatedprojects. It was created in November 2006, when initial portions ofthe JDK source code were published under the GPLv2 license.
In order to work together efficiently, clear directions aresometimes needed to avoid misconceptions and to aligndevelopers’ views of terminology and process. The OpenJDKCommunity is a fairly pragmatic place. “Do the rightthing” is most often the right course of action. Still, ifpeople do things in the same right way then everyone’s workbecomes more transparent and easier for others to follow. For thisreason most parts of the development process have standard flowsthat are the recommended ways to do things.
The goal of this guide is to answer questions that developers ofthe JDK might have around development process, tooling, standards,and so forth. The formal rules and processes are described in otherdocuments, such asJEP1 for the JDK Enhancement-Proposal & Roadmap Process, andJEP 3 for the JDKRelease Process. This guide is meant to be a complement to suchdocuments, with tutorials and examples for how to follow theserules and how to work together with the rest of the OpenJDKCommunity.
There are many common use cases that aren’t detailed inthe formal process. This guide suggests how to work in suchcases.
Quick Links
OpenJDK consists of a number ofGroups. Members of a groupcollaborate on an area of mutual interest. The right hand side baron theOpenJDK website hasa list of all groups in OpenJDK. If you’re interested in aspecific area, this is where you would start your OpenJDKexperience. Look at the group’s information and wiki pages,and see what projects they sponsor on theCensus page. TheCensus shows the structure ofthe OpenJDK Community.
Projects arewhere the coding and much of the other work is done in OpenJDK.There are many different projects, some produce shippableartifacts, like theJDK Project, someproduce tools to be used by developers of these artifacts, like theCode ToolsProject orProject Skara, andsome produce documentation, like theDevelopers’ GuideProject. Many projects designs and develops new features forthe Java language or the JVM, but there are also less code centricprojects like theDuke Project whichcollects images of the Java mascot, Duke.
OpenJDK has a few different roles that determine who has theright to do what in the different projects. These roles are definedin theOpenJDK Bylaws.The roles are earned based on experience and knowledge within eachproject.
A Contributor can have different roles in different projects.When you’re new to a project you don’t yet have aformal role in that specific project, even though you might haveearned roles in other OpenJDK projects or have been recognized as aContributor or aMemberof OpenJDK. By contributing high-quality content you’ll soonbe eligible forOpenJDK rolesin the project. FirstAuthor, thenCommitter, andfinallyReviewer if you stayactive and earn the trust of the community. Trust is an importantpart of earning these roles. There’s arough guideline sayingthat to become aCommitter youshould have contributed 8 significant changes, and to become aReviewer youshould have contributed 32 significant changes. In realityit’s not as easy as “just” contributing code. Youneed to build a track record of good decisions and sound judgmentand show that you know what differentiates a good change from a notso good one. It’s not only correctness of the code thatmatters, it’s also the appropriateness. In the end the trustyou’ve earned is put to the test through a vote.
Becoming anAuthor is the firststep. To achieve this you need to contribute two changes to theproject in which you wish to become an Author. Once your changesare pushed into the code base and has been vetted enough todetermine that the changes were indeed good changes you can goahead and send an email to the project lead of that particularproject and ask to be added as an Author. TheOpenJDK Projectdescription has a template for such an email. In response toyour email you will get a time-limited invite which you should fillout.
To see who the project lead is for your project, see theOpenJDK Census. TheCensus unfortunately doesn’t provide email addresses forpeople, but assuming you have been active on the project mailinglist (since you are applying for Author after all), you should beable to find the lead’s email address in your local emailarchive, or ask your sponsor.
As an Author you will get your OpenJDK user name. This should beassociated with your GitHub account in order for the bots to beable to identify you on GitHub. See theSkara documentation for more details on that. Once that’sdone you can create PRs and get them reviewed, but you will stillneed a sponsor to approve your change before it can be integrated.You’ll also get write access toJBS and theOpenJDK wiki related to theproject in question, and tocr.openjdk.java.net via an SSHkey provided at the time you accept your invitation.
To become aCommitter youshould show that you can produce non-trivial changes that areaccepted for inclusion into the project code base. The number eighthas been seen as a formal lower limit on the number of changes, butsince the changes must be non-trivial, or “significant”as theOpenJDK Projectdescription says, and the definition of significant issubjective, the general recommendation is to wait with a Committernomination until there’s at least 10-12 changes pushed tohave some margin for different interpretations of“significant”. It’s always a good idea to seekthe advice of a sponsor who can guide you through the process tobecoming a Committer - you will need one later to run the Committervote anyway. They probably will have a better idea of whatconstitutes a “significant” change.
Once you have the required changes, a Committer in the projectcan start a vote by sending an email proposing that you shouldbecome a Committer. The email should follow the template found intheOpenJDKProject description.
A Committer is allowed to push changes without the aid of asponsor. A Committer is also allowed to nominate othernon-Committers to become Committers in the project.
To become aReviewer you mustshow a track record of sound and correct judgment calls asmentioned above. Being a good Committer doesn’t necessarilymake you a good Reviewer. As a Reviewer you have the power toapprove changes for inclusion into the project source code. Thismeans that a Reviewer needs to be able to judge the quality andappropriateness of any proposed change, not just the mechanics ofthe code.
The assumption is that after having produced 32 significantchanges one should have become familiar with the process aroundreviews and the requirements around getting a change approved. Thisshould really be seen as a minimum requirement though. A morepractical consideration would be to look at whether the non-trivialcommits of a potential Reviewer are accepted largely intact orwhether they are always being refined by the review process. Theremay be cases where it will take significantly more than 32 changesfor a Committer to be ready to become a Reviewer.
Once you are deemed ready, a Reviewer in the project can start avote by sending an email proposing that you should become aReviewer. The email should follow the template found in theOpenJDKProject description.
One key definition when advancing through the OpenJDK roles isthe significant change. What exactly does it take for a change tobe significant?
Instead of describing the significant change (becausethat’s quite difficult to define) provided here is a fewexamples of changes that wouldn’t be considered significantor for other reasons wouldn’t count as significantcontributions.
Contributing to OpenJDK can take many forms. Writing code andproviding patches is just one of them. A big part of developing afeature or a bugfix is testing and code review. Anything you can doto help out in these areas will be recognized as a contribution.Join themailing lists to engage indesign discussions and reviews, and download the latest EA buildsor project repositories to try out new features and give feedback.If you see some misbehavior, or if you see somebody mention somemisbehavior on some internet forum, try to track it down. Good bugreports with reproducible test cases are extremely valuable andmake excellent contributions.
Anything you can do to spread the word about Java, new features,and your experiences using the JDK will be helpful for thecommunity and to the OpenJDK developers. Trying out a new featureand reporting your experiences is also a contribution. Whether youfind that the new feature improves your application, or if you findsome area that needs to be improved, your feedback is valuable tothe developers of that feature.
If you have a success story where Java solved your problem, orif you successfully upgraded to a more recent version of the JDKand noticed some improvements, spreading this story through a blog,news article, or some other channel is also a contribution.
If you’re in a position to choose what programminglanguage to use in a project, in a tutorial, or in a class, youhave the power to enlarge the Java community in a very direct way,and your colleagues or students will get an opportunity to learnone of the most used programming languages in the world.
In many GitHub projects the standard way to propose a change isto create a pull request (PR) and discuss the patch in the PR. ForOpenJDK projects the situation is somewhat different. The JDK isused for mission critical applications and by millions ofdevelopers, the bar to contributing changes is high. Please followthe steps outlined below to make sure your change passes above thebar before creating a PR.
Oracle is the steward of OpenJDK. In order to make your patchavailable for review you must first sign theOracle ContributorAgreement (OCA). This agreement gives Oracle and you as acontributor joint copyright interests in the code. You will retainyour copyright while also granting those rights to Oracle.
When you sign the OCA, please make sure that you specify yourGitHub user name in theUsername
field of the OCA. Ifyou try to create a PR before you have signed the OCA, or if youdidn’t specify your GitHub user name, you’ll getinstructions telling you to do so, and the PR won’t bepublished until this is done. OCA registration is a manual process.Please allow for up to several days to have your OCA applicationprocessed, even though it’s normally processed swiftly. Analphabetical list of all of the assigned OpenJDK usernames may befound on theOpenJDKpeople list.
Once the OCA is signed, please restrain your urge to create a PRjust a little while longer. In order to prepare the community foryour patch, please socialize your idea on the relevantmailing lists. Almost all changes, and inparticular any API changes, must go this route and have a broadagreement in place before there is any point in presenting code. Tounderstand the criteria by which your patch is going to be judged,please readWhy is MyChange Rejected? below. In short, hidden constraints andassumptions, stability and quality, maintainability, compatibility,and conformance to specifications must be considered before your PRis ready to be submitted. If you don’t understand theconstraints for acceptance, you might be surprised when your PR isrejected.
Socializing your change on the mailing lists also prevents thesurprise that would otherwise make the community choke on theirmorning coffee when they see a huge patch in a new, unknown PR. Asa new developer in the community you’ll need to make a fewfriends that agree with your change. There are many good reasons tomake friends, but the one relevant here is that for your firstchanges you’ll need a sponsor to facilitate the integrationof your work. The sponsor will perform any number of administrativetasks like JBS updates, additional testing, etc. It’s usualfor a sponsor to also be a reviewer of a change and thus familiarwith it, but it’s not a requirement.
Many OpenJDK projects require a tracking issue to be filed intheJDK Bug System(JBS) before a change can be pushed. This is the case forinstance for the JDK and the JDK-Updates projects. In order to getwrite access to JBS you need to be anAuthor in an OpenJDKproject (seeBecoming an Author).For your first changes, ask your sponsor to help you create theissue or file the bug through theBug Report Tool.
Even though we strive to unify how things are done withinOpenJDK, different areas and projects in OpenJDK may have slightvariations in how they work. Some of these differences arehighlighted throughout this guide, some aren’t. Ifyou’re new to an area, make sure you understand localdifferences before you proceed. Ask your sponsor who should be yourmain point of contact through your first developer experience inOpenJDK.
Java and the JDK are very popular products, and just about everyJava developer out there has an idea or two for how to enhancesomething. And (obviously not referring to you) believe it or not,not every idea is a good idea. Even though many ideas are indeedgood, we must be quite restrictive on what we actually include intothe JDK. There are many reasons for this.
Hidden constraints and assumptions. Manysections of code have constraints and assumptions that aren’tnecessarily visible at first glance. This might preclude certainchanges, even those that might seem obvious.
Stability and quality. The JDK is used bymillions of developers and as a widely deployed commercial product,it’s held to a high standard of quality. Changes shouldinclude tests where practical, and core tests should pass at alltimes. The value of the change should outweigh the risk ofintroducing a bug or performance regression.
Maintainability. Any new feature or code changewill need to be maintained in the JDK essentially forever, thusimposing a maintenance burden on future maintainers. The code mightstill be in use long after you and the people who reviewed it havemoved on. New maintainers must be able to understand how to fixbugs in this code.
Complexity. Each new feature interacts with allthe existing features, which can result in geometric growth of theinteractions among features if features are added unchecked.Sometimes we avoid adding a new feature, even if it seems like anobvious thing to add, if that feature would make it difficult toadd a more important feature in the future.
Adherence to specifications. Much of the JDK isgoverned by a series of specifications, in particular theJava LanguageSpecification, theJava Virtual MachineSpecification, and theJavaAPI Specification (“javadocs”). All changes must bechecked and tested carefully to ensure that they don’tviolate these specifications.
Javadoc comments are specifications. The JavaAPI Specification is authored in the form of javadoc comments, soeven apparently innocuous changes to comments can be quitesignificant. It’s not always easy to tell what comments arepart of the specification and what parts are merely code comments.Briefly, documentation comments on public packages, classes, andclass members of exported modules are specifications.
Specification changes. It’s possible tochange the API specifications, and this is done regularly. However,these changes require even more scrutiny than code changes. Thisextra review is handled by theCSR Process.Specifications are written in stylized, somewhat formal language,and they don’t simply describe what the code does. Writingspecifications is a separate skill from coding.
Compatibility. Changes should also adhere tohigh standards of binary, source, and behavioral compatibility. Thecompatibility impact of apparently innocuous changes is sometimesstartling.
For reasons like these it’s quite possible that yourchange, even though it adds value to you, isn’t deemed to addenough value to the larger community.
Quick Links
The mailing lists are the key communications mechanism for allOpenJDK work. All participation in an OpenJDK project starts withjoining the relevant mailing list. A subscriber to an OpenJDKmailing list is referred to as aParticipant intheBylaws. As ageneral recommendation we suggest to subscribe toannounce,discuss,and the-dev
lists covering your explicit area ofinterest. All OpenJDK mailing lists are found here:
The OpenJDK Community is a friendly place. To keep it that wayit’s important to keep a professional tone in emails and beaware that the community is global. Many different people withdifferent backgrounds collaborate in these lists. Even thoughEnglish is the required language for all lists, many Participantsspeak other languages as their native language. A high tolerancefor non-perfect English is expected from anyone joining theselists. You’re also strongly encouraged to use your real nameon the mailing lists. This adds to the professional tone of youremail. Postings from anonymized mailboxes risk being seen as spam.If you do work in OpenJDK on behalf of your employer, please alsolist this affiliation. If your GitHub username differs from yourreal name it’s also a good idea to include that to identifyyourself and your actions on GitHub.
You must be a member of a list to be able to post to that list.Some lists are moderated to keep the content on topic. Each listhas its own archive where you can browse older conversations on thelist.
There are a few different types of lists. The list name has twoparts to explain what the list is intended for,<name>-<suffix>
. The name often refers tothe project that owns the list or a specific area of interest thatthe list focuses on. The suffix is explained below. Not allprojects or areas have all types of lists described here.
-dev
- Technical discussions around the implementation of the projectartifacts. This is also where code reviews happen.
-use
- Technical discussions around the usage of the projectartifacts.
-discuss
- General discussions around the project. The special case
discuss(at)openjdk.java.net
is used for generaldiscussions around OpenJDK. Discussions around new projectproposals usually happens here.
-changes
- Changeset notifications from the source code repositoriesmaintained by the project.
-announce
- General project announcements. These lists are tightlymoderated and are expected to be low traffic. The special case
announce(at)openjdk.java.net
is used for announcementsfor OpenJDK.
-experts
- Expert group discussions. The list is restricted; only membersof the expert group can subscribe.
-observers
- Open for anyone to subscribe to see what the experts arediscussing and potentially to have some dialog with othernon-experts. There is no guarantee that an expert is subscribed tothe
-observers
list or will see any responses on thatlist.
-comments
- Used by observers to directly provide feedback/comments to theexperts (typically a lead will process the comments list andforward things on to the experts list).
If you need to change your registered email address, or if youhave any other problems with the mailing lists, please contactmailman@openjdk.java.net.
Quick Links
JBS is a publicissue tracker used by many OpenJDK projects. It’s open foranyone to read and search. In order to get write access you need tobe registered in theOpenJDK Census, for instanceby becoming anAuthor in an OpenJDKProject.
When a new failure is found in the JDK a bug should be filed todescribe and track the issue. Depending on your role in OpenJDK youcan either use theBug ReportTool or, if you are registered in theOpenJDK Census, report thebug directly inJBS.Try to make the bug report as complete as possible to make iteasier to triage and investigate the bug.
A few things to keep in mind when filing a new bug:
To find out which component to use for different bugs, consultthedirectory to areamapping.
To resolve an issue asIncomplete
is JBS lingo for“Need More Information”. An issue that isResolved - Incomplete
isnot closed but moreinformation is needed to be able to work on it. If no moreinformation is obtained within reasonable time the issue should beclosed (Closed - Incomplete
). Closing a resolved issueis done using theVerify
option.
JBS labels are used to tag and group related issues. JBS labelsare an open namespace, which means that anyone can create newlabels at any time. In order to avoid confusion, however,it’s best to reuse existing labels where possible. Most areashave their commonly used labels to identify issues in theirrespective area. Make an effort to find and use these labels. Thiscan be done by editing theLabelsfield of a bug and entering the first few characters of the labelyou want to add. JIRA will pop up an autocomplete window withexisting labels that match that prefix. Then choose one of theexisting labels. Using the autocomplete window is preferable totyping the whole label name (even if you’re a good typist)because it’s easy for minor spelling errors to creep in,which can inadvertently introduce multiple labels with spuriousspelling variations.
JBS labels should not be used to write documentation -don’t try to write sentences using labels. Adding a number ofrandom labels is unlikely to be helpful to anyone.
Labels are case sensitive
When using labels in Jira gadgets (like pie charts, heat maps,and statistics tables) Jira will be case sensitive and treate.g. OpenJDK and openjdk as two different labels. Searchinghowever is case insensitive. This means that if you group a set ofissues in a gadget based on a label, and then click one of thegroups to see the list of issues, that list will contain moreresults than the gadget if there are usages of the label withdifferent casing. This can be very confusing and for this reasonthe recommendation is to stick with the commonly used case for alllabels, regardless of your personal taste for upper or lower caseletters. Most labels are lower case only, but there are exampleswhere upper case letters are used in the most common version of alabel. Use of the autocomplete popup window (described above) whenadding labels will avoid inadvertent introduction of labels withdiffering case.
This table contains some frequently used JBS labels and theirmeaning. Please help keeping this dictionary up to date by addingyour favorite labels. This table doesn’t dictate how to uselabels, but rather document how they are used. That said, obviouslyit will help everyone if we try to follow a common standard and usesimilar labels in the same way across all entities that useJBS.
Label | Description |
---|---|
(Area)-interest | Used to indicate that an area (usually ateam or project) is interested in the issue. This labeldoesn’t indicate ownership of the issue. E.g.,redhat-interest,azul-interest,coin-interest |
(Area)-related | Used to indicate that an issue is related toa specific area (usually a feature or project). This labeldoesn’t indicate ownership of the issue. E.g.,graal-related,testcolo-related,doc-related |
(Rel)-bp | Used to indicate that a bug would besuitable for backport to a release(Rel). This isn’ta decision to backport, just a suggestion / recommendation. E.g.,11-bp |
(Rel)-critical-request (Rel)-critical-approved (Rel)-critical-watch | Used in the rampdown phases of specific releases to requestapproval of changes that requires project lead approval (orsimilar) to be included.(Rel) is the release in question.E.g.,jdk11-critical-request (Rel)-critical-approvedis used to signal that the change has been approved for inclusion.E.g.,jdk11-critical-approved |
(Rel)-defer-request (Rel)-defer-yes (Rel)-defer-no | Used to request deferral of changes that requires project leadapproval (or similar) to defer.(Rel) is the release inquestion. E.g.,jdk12-defer-request (Rel)-defer-yes and(Rel)-defer-no are used toindicate wether the deferral has been approved or not. E.g.,jdk12-defer-yes These labels are always placed on the main JBS issue (the bug),never on backports or subtasks. Further details are found in theJDKRelease Process. |
(Rel)-enhancement-request (Rel)-enhancement-yes (Rel)-enhancement-no | Used in the rampdown phases to request the late inclusion of anenhancement.(Rel) is the release in question. E.g.,jdk10-enhancement-request (Rel)-enhancement-yesand(Rel)-enhancement-noare used to indicate the response on the request. E.g.,jdk10-enhancement-yes,jdk10-enhancement-no These labels are always placed on the main JBS issue (the bug),never on backports or subtasks. Further details are found in theJDKRelease Process. |
(Rel)-fix-request (Rel)-fix-SQE-ok (Rel)-fix-yes (Rel)-fix-no | Used in rampdown phase 2 to indicate that an issue would be ofinterest to get integrated into release(Rel). E.g.,jdk12u-fix-request (Rel)-fix-SQE-ok is usedto indicate that the issue will be covered by the test plan for(Rel). E.g.,jdk12u-fix-SQE-ok |
(Rel)-na | Used to indicate that the issuedoesn’t affect release(Rel) or later. Could forinstance be a bug in code that was removed in(Rel). |
(Team)-triage-(Rel) | Used to indicate that(Team) has triaged this issue forrelease(Rel). It’s encouraged that all open bugsare triaged on a regular basis so that old bugs aren’tforgotten. It’s therefore common to see several triage labelson the same issue which helps keeping track of which bugs has beentriaged for each release. E.g.,oracle-triage-13 There are many label variants that include the word triage in someform. The form described above is the only one recommended. Pleaserefrain from using other forms. |
aot | Used to identify issues in Ahead of TimeCompilation. |
Deprecated. Was used toidentify issues in Application Class-Data Sharing. Thecds label is now used instead. | |
c1 | Used to identify issues in the C1 JITcompiler. |
c2 c2- .* | Used to identify issues in the C2 JIT compiler. c2-.* labels are usedto identify different c2 features. E.g.,c2-intrinsic,c2-loopopts |
cds | Used to identify issues in Class DataSharing. |
cleanup | Thecleanuplabel is used to indicate enhancements which has no semanticchanges, whose only purpose is to make the code more maintainableor better looking. |
docker | Used to identify issues in dockersupport. |
gc-.* | Used to identify issues in specific garbage collectors in theJVM. E.g.,gc-g1,gc-shenandoah,gc-serial,gc-epsilon There are also labels in use to identify different GC features orareas rather than GC algorithms. E.g.,gc-g1-fullgc,gc-largeheap,gc-performance |
graal | Used to indicate that this is a Graal issue.(Something that needs to be fixed in Graal rather than inOpenJDK.) |
graal-integration | Reserved for Graal integration umbrellabugs. The automated integration script will break if this label isused for other bugs. |
hgupdate-sync | Used to identify backport issuesautomatically created by HG Updater (a script that monitors the hgrepositories for changes). |
Deprecated. Was used to tagbugs found in the HotSpot nightly testing. Since we are now runningtiered testing there is no more nightly HotSpot testing. Seetier[1-8] . | |
hs-sbr | Used to identify issues that are found inthe “same binary runs”, a stress testing method used tofind intermittent failures. |
[1-8] | Deprecated. Was used toidentify which HotSpot tier a test failure was seen in. Wedon’t separate HotSpot tiers from the JDK tiers anymore. Seetier[1-8] . |
i18n | Used to identify issue ininternationalization. i18n is short for internationalizationmeaning “i 18 letters and an n”. |
integration-blocker | Used to indicate that a bug is present in adownstream repository but not present in the upstream repositoryand is therefore blocking integration of downstream changes intoupstream. |
intermittent intermittent-environment intermittent-hardware | An intermittent issue is one that fails sometimes but notalways. The exact reason for the intermittent failure is perdefinition unknown. Once the reason has been identified the issueis no more considered intermittent. An issue isn’tintermittent if some characteristics has been found that triggersthe failure consistently, even if the actual cause for the failurehasn’t been found. For instance if a test fails every timeit’s executed on a specific host but not on other hosts itwouldn’t be considered intermittent as it fails consistentlyon that specific host. In other cases it may be that we know that atest sometimes is unlucky in some respect and fails due to this.This test could still be considered intermittent even though weknow what the reason is if the reason itself appearsintermittently. Some issues may seem intermittent when looking at test results,even though the reason for failing is actually known. One exampleis where a test fails consistently on a specific host, or due tospecific conditions in the environment. These failuresshouldn’t be considered intermittent but it may still bevaluable to tag these in JBS with one of the labelsintermittent-hardware orintermittent-environment. This will help tofaster identify that the cause of the failure is known withouthaving to read through the entire bug. A test that should be platform agnostic but is consistently failingon a specific OS would for instance be labeled withintermittent-environment, while a test thatfails every time it’s run on some specific hardware would belabeled withintermittent-hardware. |
maintainer-pain | Used to tag bugs that for some reason is wasting time or inother ways are causing pain for the OpenJDK maintainers. Examplesof issues that could be considered a pain:
There are other cases as well and there is some flexibility inthe definition. If you see a problem that is causing pain for alarge number of maintainers, add an explanation in the JBS issue towhy you think the issue is a pain and add the label. If you have amaintainer-pain bugassigned to you please consider fixing it asap. If you chose not towork on the issue, you should at least be aware that you arechoosing to waste others’ time and people will be affected bythis choice. As with any issue the best way to deal with amaintainer-pain issue is to fix it. Another wayto reduce the noise is toexclude thefailing test. This is a viable option if there is a limited setof tests that are failing and the bug is actively investigated.When excluding amaintainer-painissue, remember to move themaintainer-pain label to the JBS issue used toexclude. Leaving the label on the closed exclude-issue is helpfulfor tracking purposes. |
noreg-.* nounit- .* | Thenoreg-
|
performance | Used to identify an issue with noticeableperformance impact. Either positive or negative. |
Deprecated. Was used toindicate that a failure happened in product integration testing(PIT). Since we are now running tiered testing there is no morePIT. Seetier[1-8] . | |
problemlist | One or more tests has been problemlisted dueto this bug. |
regression | Used to identify regressions. A regressionis a bug that didn’t exist in the previous release. Ideallyall regressions must be fixed in order to release the next majorversion. |
release-note | Used to indicate that the issue is a releasenote. SeeRelease Notes. |
release-note=yes release-note=no | Used to indicate whether a change requires a release note ornot. The labels are always placed on the main JBS issue, never onthe actual release note issue. SeeReleaseNotes. release-note=done is deprecated andshould no longer be used. |
RN-.* | Used to indicate what kind of change therelease note is for. SeeReleaseNotes. |
starter | A starter bug is a well contained, smallissue that is suitable for someone new to the codebase. |
startup | Used to identify an issue as affecting JavaSE startup performance. |
tck-red-(Rel) | Used to identify TCK conformance stoppers (e.g. failure ofa valid TCK test that exists in a shipped TCK). The release numberindicates which release of the TCK that failed. E.g.,tck-red-11 There aretck-red labels without therelease number out there as well. This usage is deprecated. |
The labelstest,test-only,andtestbug are deprecated andshould no longer be used. Usenoreg-self to indicate that an issue is abug in test code. | |
tier[1-8] | Used to indicate which tier in the jdk/jdk CI pipeline. Use(Rel)[-tier1] forother CI pipelines, where(Rel) is the name of thepipeline. E.g.8u-tier1 |
vthreads | Used to identify an issue in the virtualthread implementation. |
webbug | Used to identify a bug as submitted onbugs.java.com. |
zgc | Used to identify an issue in ZGC. |
This is the list of steps which should be performed when fixinga small bug. Small bugs include typos in code or specification,algorithm improvements for correctness or performance, and codechanges required to correctly implement the specification.
Some steps refer to operations which can’t be performeddirectly without the assistance of aProject Committer.For example, any changes to thebug database fall into thiscategory. Since these steps are required,Contributors areurged to work with theirSponsors to complete thesetasks.
For the purposes of brevity this document will use the term“bug” to refer to both bugs and enhancements unlessotherwise noted. Hence “fix for a bug” could also imply“implementation for an enhancement”.
Discuss the intended change
Send an e-mail to the appropriate development mailing list forthe Project that maintains the code. The e-mail should have asubject line of the form:
6543210: My favorite bug
where6543210
is replaced with the actual bug idnumber or “[NEW BUG]” if the bug id isn’t knownandMy favorite bug
is replaced with the bug’ssummary. The message should describe the intended change, whichcomponents may be affected, and any other risks or concerns.
Does a bug id exist for the work?
Set the bug status to “Open”
This communicates intent to fix the bug to other members of theProject. It also sets the expectation for downstream teams such asSQE and JCK that the bug will be fixed in an upcomingintegration.
Does the fix for the bug require a specification change,directly affect an external interface, or otherwise have acompatibility impact?
Fix the bug
Assuming that the development team approves of the intendedapproach, begin working on the code using the latest sourceavailable from the appropriate OpenJDK Projectrepository.
[Is it possible to write a test to detect thebug?]
An entirely new test (or tests) may not be required. Forexample, if the bug is an existing regression test failure, thenwhen fixing the bug you should just add the new bug ID to the listof space-delimited bugs in the@bugtag of the failing regression test, even if the testdidn’t need to be updated.
Is modification of shared Java code needed?
Is modification of shared C code needed?
Is modification of C or Java platform-specific codeneeded?
src/solaris
builds on Solaris, Linux, and MacOS Xdespite its name.Run relevant regression and unit tests on all relevantplatforms
These include tests for external interfaces as well as otherkinds of tests, e.g., HotSpot tests that use internal verificationmechanisms.
Run relevant JCK tests on all relevantplatforms
Running JCK tests is particularly important if the change mayhave unexpected side-effects.
Request a review of the changes by sending an e-mail tothe development alias
A patch can be submitted as described inContributing.Alternatively, a“webrev”may be generated and uploaded to thecommunity code review server.The complete webrev generation and upload procedure is described athttps://cr.openjdk.java.net.
Changeset pushes before theFeature Complete require at least oneReviewer; pushesafter the Feature Complete require at least two Reviewers. Ineither case, the more the merrier. Some teams may require moreReviewers. Check with members of the Project.
Reviewers should examine not only the code being added orchanged but also the relevant unit or regression tests.
A change may require multiple Reviewers because it affectsmultiple areas. Reviewers should be aware that they take fullresponsibility for the appropriateness and correctness of anychanges in their area of expertise. If something goes wrong (e.g.,the build breaks) and the change's author is unavailable, they maybe asked to deal with the problem. Potential Reviewers areencouraged to refuse to review code for which they aren’tqualified.
Create a changeset
Follow the instructions inProducing a Changeset.
Update the bug content
Bug descriptions and comments should be written in aprofessional manner.
Push the changeset into the Project’sforest
Follow the instructions inProducing a Changeset. If working witha Sponsor, send the changeset to the development mailing list sothat they can handle the final push.
The push will trigger a update to the bug which will make thefollowing changes:
Congratulations! Your changeset will now make its waytowards a promoted build. When the changeset becomes part of apromoted build, the bug’s “Resolved in Build”will have a value of "b[1-9][0-9]*" to indicate the buildnumber.
The complete source code for the JDK is hosted atGitHub. You can browse the code directlyin theopenjdk/jdkrepository, or download the code for offline browsing, editing,and building usinggit clone
.
$ git clone https://github.com/openjdk/jdk.git
openjdk/jdk
is the mainline JDK developmentrepository where the next major release of the JDK is beingdeveloped. Other projects have their own repositories onGitHub.
Note that source may be available from other locations, forexample
src.zip
from a full JDK distribution. However,OpenJDK contributions must use source from the appropriate OpenJDKGitHub repository since other source distributions may containolder code or code which differs due to licensing. Consult theProject’s documentation ormailinglist to determine the appropriate repository, developmentconventions, and helpful tools.
If you intend to contribute patches, you should firstfork the repository on GitHub and clone your ownpersonal fork as shown below. To fork a project on GitHub,go to the GitHub project page and click the ‘Fork’button in the upper right corner, then follow the on screeninstructions.
This is the typical development model:
Diagram of upstream repos and user's clone
Pushes to your personal fork can be made either using HTTPS orSSH. These examples assume you have an SSH key installed on GitHub.If this is the first time you clone your personal fork of anOpenJDK repository you may want to create an SSH key to use withit. SeeGenerating an SSH keybelow. Once you have your personal fork and an SSH key to go withit, go ahead and clone.
$ git clone git@github.com:OpenDuke/jdk.git$ cd jdk$ git remote add upstream https://github.com/openjdk/jdk.git
In the example above Duke cloned his personal fork of the JDKmainline repository using SSH. You should of course use your ownGitHub username instead. Then, by adding a newremotenamed ‘upstream’, the clone is associated withopenjdk/jdk. Doing this willallow the tooling to automatically create a PR onopenjdk/jdk whenever a changeis pushed to the personal fork. The way that works is that once thechange has been pushed to the personal fork, and you navigate totheopenjdk/jdkrepository on GitHub, there will be a message saying that you justpushed a change and asking if you want to create a PR.
The recommendation is to always create a new branch for anychange you intend to implement. By doing that you can easily workon many different changes in parallel in the same code repository.Unless you know what you are doing, the recommendation is also toalways base your new branch on themaster
branch.
$ git switch -c JDK-8272373 master
Here we create a new branch calledJDK-8272373
based on themaster
branch and set the repository upto work in that new branch.
git switch
was introduced in Git version 2.23. Forearlier versions of Gitgit checkout
can be usedinstead. However it is always recommended to use the latestversions of all your tools when possible.
More information about how to work with git and the dedicatedtooling that is available for OpenJDK can be found in theProject SkaraDocumentation. If you’re new to git you can also readmore about how to work with it in one of the many fine gittutorials available on the Internet. For instance thePro Git book. This guidedoesn’t aspire to become another git guide.
For security reasons you should always create new keys and usedifferent keys with each repository you clone. Thessh-keygen
command generates an SSH key. The-t
option determines which type of key to create.ed25519
is recommended.-C
is used to adda comment in the key file, to help you remember which key it is.While it’s possible to use SSH without a passphrase, this isstrongly discouraged. Empty or insecurepassphrases may be reset usingssh-keygen -p
; thisdoesn’t change the keys.
$ ssh-keygen -t ed25519 -C openjdk-jdk -f ~/.ssh/openjdk-jdkGenerating public/private ed25519 key pair.Enter passphrase (empty for no passphrase):Enter same passphrase again:Your identification has been saved in /Users/duke/.ssh/openjdk-jdk.Your public key has been saved in /Users/duke/.ssh/openjdk-jdk.pub.The key fingerprint is:SHA256:WS4jCQMtat75ZEue+so+Lgj7V/sdMtj1FTNkfNsCfHA openjdk-jdkThe key's randomart image is:+--[ED25519 256]--+| .. ..oE || ... o+o .|| . .o . o+.o||.. o . + .=.||o . . o S o .. ||.. o +.+ + . . ||o. *.+.+ . . ||o....=. + . || .=B=. .. . |+----[SHA256]-----+
~/.ssh/openjdk-jdk
is a text file containing yourprivate ssh key. There’s a corresponding public key in~/.ssh/openjdk-jdk.pub
(as detailed in the exampleabove). You shouldnever share your private key.Thepublic key on the other hand should be uploaded toGitHub. Follow the steps below to do that.
~/.ssh/openjdk-jdk.pub
intothe text fieldcat ~/.ssh/openjdk-jdk.pub
ssh-ed25519AAAAC3NzaC1lZDI1NTE5AAAAIO8+egiIgWV+tE7LVVJmlR7WS2Lr3Fj7dXVo9HiasD6Topenjdk-jdk
Now you are ready to clone youropenjdk/jdk fork usingSSH.
The JDK build system is a fairly complex machine that has theability to build anything from a single module to a completeshippable JDK bundle with various levels of debug capabilities, runtests, install your newly built JDK on your system, orcross-compile for some other system. The build usesmake
and a few other tools that you will have toinstall on your system before starting.
The JDK supports incremental builds. This means that if you havea complete build and make changes in just a single part of the JDK(e.g. a module or part of the JVM), only that particular partneeds to be rebuilt. So subsequent builds will be faster and youcan always use a make target that results in a complete JDK imagewithout having to worry about actually building the entire JDKevery time. Please note that the incremental build do have limitsin its understanding of what you change. For instance, if youchange behaviors or conventions in one module there may be otherparts of the JDK that implicitly depends on these withoutmake’s knowledge. For this reason you may have to rebuildseveral modules, or do a clean build if you change things that mayhave a wider impact.
The examples below show the steps taken to build the JDK sourcecode. Please seeCloning the JDK forinformation on how to download it. These examples were written inthe JDK 17 development time frame which is why the boot JDK usedhere is JDK 16. Note that the download links used here point to JDK16 bundles. To build JDK N, use JDK N-1 as the boot JDK.
The configure script will tell you what additional packages youneed. In this first example several packages were needed since thisbuild was performed on a clean Ubuntu installation. The configurescript was run several times to get all the dependencies, but onlythe commands actually needed to get the JDK built are included inthe log. This is just an example log, don’t copy theapt-get install
line. Instead runsh./configure
to see what packages you actually need on yoursystem.
$ wget https://download.java.net/java/GA/jdk16/7863447f0ab643c585b9bdebf67c69db/36/GPL/openjdk-16_linux-x64_bin.tar.gz$ tar xzf openjdk-16_linux-x64_bin.tar.gz$ sudo apt-get install autoconf zip make gcc g++ libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev libcups2-dev libfontconfig1-dev libasound2-dev$ cd jdk$ sh ./configure --with-boot-jdk=$HOME/jdk-16/$ make images
The built JDK can be found inbuild/linux-x86_64-server-release/jdk
. The exact pathdepends on your build platform and selected configuration.
The second example is from a clean (newly installed) Mac runningMacOS Big Sur. Please note that in this case there are some stepstaken outside of the terminal. First XCode and the XCode commandline tools must be installed. It could be that the most recentversion of XCode that you get from App Store is too new to havebeen properly tested with the JDK build. Seethe JDK build instructions for supported versions and moredetails in case you need to install an older version of XCode. Inthis exampleMac Ports isused to installautoconf
.autoconf
canalso be installed usingHomebrew andsurely through other sources as well.
$ curl https://download.java.net/java/GA/jdk16.0.1/7147401fd7354114ac51ef3e1328291f/9/GPL/openjdk-16.0.1_osx-x64_bin.tar.gz --output openjdk-16.0.1_osx-x64_bin.tar.gz$ tar xzf openjdk-16.0.1_osx-x64_bin.tar.gz$ sudo port install autoconf$ sh ./configure --with-boot-jdk=$HOME/jdk-16.0.1.jdk/Contents/Home$ make images
In this case the built JDK can be found inbuild/macosx-x86_64-server-release/jdk
.
The JDK build is extremely configurable. This list only containsthe most basic configure options needed to get you started. Useconfigure --help
to see a complete list ofoptions.
Option | What it does |
---|---|
--with-boot-jdk | Tell configure what boot JDK to use to build theJava libraries. |
--with-debug-level | Set the debug level. Available levels arerelease ,fastdebug ,slowdebug ,optimized . |
Through the configure flags you will select what configurationof the JDK to build. The name of the output directory for the builddepends on this configuration. In the example above the JDK endedup inlinux-x86_64-server-release
. This means that wemade a release build of a 64 bit linux x86 version of the serverJDK. If we change some of these options the output directory willbe affected accordingly.
--with-debug-level
is one example of a configureoption that will change the output directory name. Sometimes itmakes sense to have several different configurations in parallel.For example while debugging some code you might want to have both adebug build and a release build to be able to test it properly. Thedirectory naming scheme makes this very easy. Simply configure andbuild the JDKs you need and they will end up next to each other inthe build directory.
In the example above we built arelease
image. Tobuild a debug image as well we can configure with--with-debug-level=slowdebug
. This will give us a JDKwhere for instance asserts in the JDK source code are enabled. Toselect which JDK to work with in later calls tomake
addCONF=<configuration>
.
$ sh ./configure --with-boot-jdk=$HOME/jdk-16/ --with-debug-level=slowdebug$ make CONF=slowdebug images$ ls build/linux-x86_64-server-releaselinux-x86_64-server-slowdebug
make images
, as used in the example above, willbuild a JDK image which is very close to what you’d get fromany JDK provider. There are several other make targets you can usedepending on what you’re looking for. The table belowcontains some commonly used make targets.
Target | What it does |
---|---|
exploded-image | This is the default make target that you’llget if you simply invokemake . |
image | Builds a complete JDK image. A good target to useif you want to build a JDK for general usage or if you want to testsomething closer to the shipping product. This can also be a goodtarget to use if doing something which might have a build aspect toit. |
<name>-image | Build just the image for any of jdk, test, docs,symbols, etc. |
reconfigure | Re-runs the configure script with the samearguments as given the last time. |
demos | Builds the demos which for instance make it easyto test something UI related. |
docs | Builds the javadoc. Note that a number of classesin the javadoc API are generated during the build, somakedocs might do more than simply invokejavadoc ,depending on the state of your build. |
java.base | Builds the base module. You can (re)build anymodule withmake <module> . |
hotspot | Builds the JVM. Note that the JVM depends onseveral other parts of the JDK, somake hotspot mightbuild more than just the JVM, depending on the state of yourbuild. |
clean | Removes all files generated by make, but not thosegenerated by configure. Useful when doing significant renaming orrefactoring which may confuse the incremental build. To clean out aspecific module only usemakeclean-<module> . |
dist-clean | Removes all files, including configuration. |
There are many other targets available as well. Usemakehelp
to find out more.
In addition to your own Java applications, OpenJDK have supportfor two test frameworks, jtreg and GTest. jtreg is a Javaregression test framework that is used for most of the tests thatare included in the OpenJDK source repository. The Google Test(GTest) framework is intended for unit testing of the C++ nativecode. Currently only JVM testing is supported by the GTestframework. Other areas use jtreg for unit testing of C++ code.
This section provides a brief summary of how to get started withtesting in OpenJDK. For more information on configuration and howto use the OpenJDK test framework, a.k.a. “run-testframework”, seedoc/testing.md
.
In general all changes should come with a regression test so ifyou’re writing product code you should also be writing testcode. There are a few examples where it doesn’t make sense towrite an explicit regression test. These should be tagged in JBSwith one of thenoreg-labels.
A few key items to think about when writing a regressiontest:
The jtreg documentation has a section onhow to write goodjtreg tests.
In-depth documentation about the jtreg framework is found here:jtreg harness. jtregitself is available in theCode ToolsProject.
Below is a small example of a jtreg test. It’s a cleanJava class with a main method that is called from the test harness.If the test fails we throw a RuntimeException. This is picked up bythe harness and is reported as a test failure. Try to always writea meaningful message in the exception. One that actually helps withunderstanding what went wrong once the test fails.
/* * @test * @summary Make sure feature X handles Y correctly * @run main TestXY */public class TestXY { public static void main(String[] args) throws Exception { var result = X.y(); if (result != expected_result) { throw new RuntimeException("X.y() gave " + result + ", expected " + expected_result); } }}
This example only utilizes three jtreg specific tags,@test
,@summary
, and@run
.@test
simply tells jtreg that this class is a test,and@summary
provides a description of the test.@run
tells jtreg how to execute the test. In this casewe simply tell jtreg to execute the main method of the classTestXY
.@run
isn’t strictlynecessary for jtreg to execute the test, an implicit@run
tag will be added if none exists. However, forclarity and in order to avoid bugs it’s recommended to alwaysexplicitly use the@run
tag.
There are several other tags that can be used in jtreg tests.You can for instance associate the test with a specific bug thatthis test is a regression test for.
@bug 7000001
Or you can specify a number of requirements that must befulfilled for jtreg to execute the test.
@requires docker.support@requires os.family != ”windows”@requires os.maxMemory > 3G@requires os.arch=="x86_64" | os.arch=="amd64"
You can also specify if the test requires specific modules, andyou can specify command line flags and run the test in severaldifferent ways.
@modules java.base/jdk.internal.misc@run main/othervm -Xmx128m TestXY
Note that you can have several@run
tags in thesame test with different command line options.
jtreg also have support for labeling tests with keys using the@key
tag. These keywords can then be used to filterthe test selection. For instance if you have a UI test which needsto display a window you’ll want to make sure the test harnessdoesn’t try to run this test on a system which doesn’tsupport headful tests. You do this by specifying
@key headful
Another example is@key randomness
that should beused to indicate that a test is using randomness - i.e. isintentionally non-deterministic.
There are many other keywords in use and their usage may differbetween areas in the JDK. Make sure you understand the conventionsfor the particular area you are testing since these are justexamples.
Thejtregdocumentation provides information on many more tags likethese.
Thecompilergroup has a section in their wiki withGuidelinesfor “langtools” tests.
When configuring the OpenJDK build you can tell it where yourjtreg installation is located. When providing this information youcan later runmake run-test
to execute jtregtests.
sh ./configure --with-jtreg=/path/to/jtregmake run-test TEST=tier1
In the OpenJDK source tree you can find a directory calledtest
. There are a large number of tests in thisdirectory that are written to be used with jtreg.
make run-test TEST=test/jdk/java/lang/String/
You can also run jtreg without invoking make. In this caseyou’ll need to tell jtreg which JDK to test.
jtreg -jdk:/path/to/jdk /path/to/test
As mentioned the Google test framework is mainly used for C++unit tests. There are several of these in thetest/hotspot
directory. Currently, only the C++ codein the JVM area is supported by the OpenJDK GTest framework. Thetests can be run without starting the JVM, which enables testing ofJVM data structures that would be fragile to play with in a runningJVM.
static int demo_comparator(int a, int b) { if (a == b) { return 0; } if (a < b) { return -1; } return 1;}TEST(Demo, quicksort) { int test_array[] = {7,1,5,3,6,9,8,2,4,0}; int expected_array[] = {0,1,2,3,4,5,6,7,8,9}; QuickSort::sort(test_array, 10, demo_comparator, false); for (int i = 0; i < 10; i++) { ASSERT_EQ(expected_array[i], test_array[i]); }}
ASSERT_EQ
is one example of an assertion that canbe used in the test. Below are a few other examples. A full list isfound in theGoogle Test Documentation.
ASSERT_TRUE(condition);ASSERT_FALSE(condition);EXPECT_EQ(expected, actual);EXPECT_LT(val1, val2);EXPECT_STREQ(expected_str, actual_str);
ASSERT
is a fatal assertion and will interruptexecution of the current sub-routine.EXPECT
is anonfatal assertion and will report the error but continues to runthe test. All assertions have both anASSERT
and anEXPECT
variant.
For more information on how to write good GTests in HotSpot, seedoc/hotspot-unit-tests.md
.
When configuring the OpenJDK build you can tell it where yourGTest installation is located. Once configured, use make to runGTests.
sh ./configure --with-gtest=/path/to/gtestmake test TEST=gtest
You can also use a regular expression to filter which tests torun:
make test TEST=gtest:code.*:os.*make test TEST=gtest:$X/$variant
The second example above runs tests which match the regexp$X.*
on a specific variant of the JVM. The variant isone of client, server, etc.
Sometimes tests break. It could be e.g. due to bugs in thetest itself, due to changed functionality in the code that the testis testing, or changes in the environment where the test isexecuted. While working on a fix, it can be useful to stop the testfrom being executed in everyone else’s testing to reducenoise, especially if the test is expected to fail for more than aday. There are two ways to stop a test from being run in standardtest runs: ProblemListing and using the@ignore
keyword. Removing tests isn’t the standard way to remove afailure. A failing test is often a regression and should ideally behandled with high urgency.
I’ll say it right away so that it’s not forgotten atthe end: Remember to remove the JBS id from the ProblemList or thetest when the bug is closed. This is especially easy to forget if abug is closed as a duplicate or ‘Will Not Fix’. jcheckwill report an error and prohibit a push if a PR is created for anissue that is found in a ProblemList if the fix doesn’tremove the bug ID from the ProblemList.
ProblemListing should be used for a short term exclusion while atest is being fixed, and for the exclusion of intermittentlyfailing tests that cause too much noise, but can still be useful torun on an ad-hoc basis. ProblemListing is done in the fileProblemList.txt
. There are actually severalProblemList files to choose from. Their location and name hintabout what area or feature each file belongs to. Each file hassections for different components. All ProblemList files complementeach other to build the total set of tests to exclude in jtregruns.
test/hotspot/jtreg/ProblemList.txttest/hotspot/jtreg/ProblemList-aot.txttest/hotspot/jtreg/ProblemList-graal.txttest/hotspot/jtreg/ProblemList-non-cds-mode.txttest/hotspot/jtreg/ProblemList-Xcomp.txttest/hotspot/jtreg/ProblemList-zgc.txttest/jaxp/ProblemList.txttest/jdk/ProblemList.txttest/jdk/ProblemList-aot.txttest/jdk/ProblemList-graal.txttest/jdk/ProblemList-Xcomp.txttest/langtools/ProblemList.txttest/langtools/ProblemList-graal.txttest/lib-test/ProblemList.txt
Use the suitable ProblemList and add a line like this in theproper section:
foo/bar/MyTest.java 4711 windows-all
In this example,MyTest.java
is ProblemListed onwindows, tracked by bugJDK-4711
.
Currently there’sno supportfor multiple lines for the same test. For this reasonit’s important to always make sure there’s no existingentry for the test before adding a new one, as multiple entriesmight lead to unexpected results, e.g.
foo/bar/MyTest.java 4710 generic-all...foo/bar/MyTest.java 4711 windows-all
This would lead tosun.tools.jcmd.MyTest.java
beingProblemListed only onwindows-all
. The proper way towrite this is:
foo/bar/MyTest.java 4710,4711 generic-all,windows-all
Althoughwindows-all
isn’t strictly requiredin this example, it’s preferable to specify platforms foreach bugid (unless they are allgeneric-all
), thismakes it easier to remove one of the bugs from the list.
Remember to always add aproblemlist label in the JBS issue referenced inthe ProblemList entry.
Some tests contain several test cases and there may be a need toProblemList only a few of them. To do this use the full test name,i.e. <filename> + # + <test case id>
,where test case id can be specified in the test header. If no id isspecified each test case can be referenced withid
+ordinary number of the test case in the test file.
Let’s assume we have four test cases infoo/bar/MyTest.java
:
/* @test *//* @test id=fancy_name *//* @test *//* @test */
A ProblemList entry that excludes the first, second, and thirdtest case would look like this:
foo/bar/MyTest.java#id0 4720 generic-allfoo/bar/MyTest.java#fancy_name 4721 generic-allfoo/bar/MyTest.java#id2 4722 generic-all
Due to an issue described inCODETOOLS-7902712tests that contains more than one@test
must actuallyuse this way to specify all test cases if all of them should beProblemListed. Specifying just the test name will not work.
To run ad-hoc runs of ProblemListed tests useRUN_PROBLEM_LISTS=true
.
make test TEST=... JTREG=RUN_PROBLEM_LISTS=true
@ignore
The@ignore
keyword is used in the test sourcecode. This is mainly used for tests that are so broken that theymay be harmful or useless, and is less common than ProblemListing.Examples can be tests that don’t compile because somethingchanged in the platform; or a test which might remove your/etc/shadow
. Use@ignore
with a bugreference in the test case to prevent the test from being run.
/***@test*@ignore4711*/
In this example,MyTest.java
is excluded, trackedby bugJDK-4711
.@ignore
should always beplaced directly before the first@run
line in thetest.
ProblemListing and@ignore
-ing are done in the JDKsource tree, that means a check-in into the repository is needed.This in turn means that a unique JBS issue and a code review areneeded. This is a good thing since it makes test problemsvisible.
The fix for the main issue should remove the test from theProblemList or remove the@ignore
keyword from thetest.
After a failure is handled by excluding a test, the main JBSissue should be re-triaged and possibly given a new priority. Thisshould be handled by the standard triage process. A test exclusionresults in an outage in our testing. This outage should be takeninto consideration when triaging, in addition to the impact of thebug itself.
GitHub has a feature calledGitHub Actions(GHA) that can be used to automate testing. The GHA is executedwhenever a push is made to a branch in your repository. The botswill show the results of the GHA in your PR when you create orupdate it. The GHA in the JDK project is configured to run a set oftests that is commonly known astier 1. This is arelatively fast, small set of tests that tries to verify that yourchange didn’t break the JDK completely. In tier 1 the JDK isbuilt on a small set of platforms including (but not necessarilylimited to) Linux, Windows, and MacOS, and a few tests are executedusing these builds.
In addition to the testing you run manually before publishingyour changes, it’s recommended that you take advantage ofthis automated testing that the GHA offers. This will for instanceallow you to run tests on platforms that you may not otherwise haveaccess to. To enable this on your personal fork of the JDK onGitHub go to the “Actions” tab and click the big greenbutton saying “I understand my workflows, go ahead and enablethem”. If you don’t understand these workflowsthere’s a link to the actual file that describes them rightbelow the green button.
In case of failures in the GHA it’s always a good start totry to reproduce the failure locally on a machine where you havebetter control and easier access to a debug environment. There havebeen cases where the GHA has failed due to issues unrelated to thechange being tested, e.g. because the GHA environment wasupdated and changes were needed to the JDK GHA configuration. Theconfiguration is in general updated fairly quickly, so in caseswere you can’t reproduce the failure locally, considerre-running the GHA later.
Please keep in mind that the tier 1 tests run by the GHA shouldonly be seen as a smoke test that finds the most criticalbreakages, like build errors or if the JDK is DOA. These tests cannever replace the targeted testing that you always must do on yourchanges. There are several areas of the JDK that aren’t partof tier 1 at all. To see exactly what tier 1 includes, please seethe various TEST.groups files that you will find in thesubdirectories ofjdk/test/
.
If a change causes a regression that can’t be fixed withinreasonable time, the best way to handle the regression can be toback out the change. Backing out means that the inverse(anti-delta) of the change is pushed to effectively undo the changein the repository. There are two parts to this task, how to do thebookkeeping in JBS, and how to do the actual backout in git orMercurial.
The backout is a regular change and will have to go through thestandard code review process, but is considered atrivial change. The rationale is that a backout isusually urgent in nature and the change itself is automaticallygenerated. In areas where two reviewers are normally required, onlyone additional Reviewer is required for a backout since the personwho is performing the backout also will review the change.
[REDO]
on the summary - the clone becomes theredo-issue(R).[BACKOUT]
.[BACKOUT]
.[BACKOUT]
.ProblemList entries and@ignore
keywords willcontinue to point to the original bug (unless updated at back out).This is accepted since there is a clone link to follow.
To backout a change with git, usegit revert
. Thiswill apply (commit) the anti-delta of the change.
$ git show aa371b4f02c2f809eb9cd3e52aa12b639bed1ef5 commit aa371b4f02c2f809eb9cd3e52aa12b639bed1ef5 (HEAD -> master) Author: Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com> Date: Wed Jun 23 20:31:32 2021 +0200 8272373: Make the JDK mine Reviewed-by: dukediff --git a/README.md b/README.md index 399e7cc311f..4961acb2126 100644--- a/README.md+++ b/README.md@@ -1,4 +1,4 @@-# Welcome to the JDK!+# Welcome to my modified JDK! For build instructions please see the [online documentation](https://openjdk.java.net/groups/build/doc/building.html), $ git revert aa371b4f02c2f809eb9cd3e52aa12b639bed1ef5 [master d454489052d] 8280996: [BACKOUT] Make the JDK mine Reviewed-by: duke 1 file changed, 1 insertion(+), 1 deletion(-) $ git show d454489052dc6ff69a21ad9c8f56b67fdeb435ee commit d454489052dc6ff69a21ad9c8f56b67fdeb435ee (HEAD -> master) Author: Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com> Date: Wed Jun 23 20:32:08 2021 +0200 8280996: [BACKOUT] Make the JDK mine Reviewed-by: dukediff --git a/README.md b/README.md index 4961acb2126..399e7cc311f 100644--- a/README.md+++ b/README.md@@ -1,4 +1,4 @@-# Welcome to my modified JDK!+# Welcome to the JDK! For build instructions please see the [online documentation](https://openjdk.java.net/groups/build/doc/building.html),
In order to backout a change, thehg backout
command is recommended, which essentially applies the anti-delta ofthe change. Make sure you perform the backout in the most upstreamrepository the change has escaped to.
hg backout [OPTION]... [-r] REVreverse effect of earlier changeset Prepare a new changeset with the effect of REV undone in the current working directory. If REV is the parent of the working directory, then this new changeset is committed automatically. Otherwise, hg needs to merge the changes and the merged result is left uncommitted.
In rare cases it may be necessary to back out a backport from anupdate release without backing out the original fix in mainline.This will require a somewhat different procedure and will result ina small mess in JBS. It’s extremely important to add commentsin all relevant issues explaining exactly what’shappened.
The steps to take in order to do this are described below.(M) used below refers to the main bug entry - thefirst fix that was later backported.
[REDOBACKPORT]
on the summary - the clone becomes the redo-issue(R).<N>-pool
if it’s not critical whichrelease the fixed backport goes into.[BACKOUT BACKPORT]
.[BACKOUTBACKPORT]
.[BACKOUTBACKPORT]
.The end result in JBS should look like this:
JBS structure after backout and redo of abackport
For this example in JBS see the 15.0.2 backport ofJDK-8272373.
The approach described here has both advantages anddisadvantages. The key invariants that lead to this model are:
Disadvantages of this model are that the list of backports inJBS will still list the old (failed) backport as the 15.0.2backport, and the new backport will not be linked to using abackported by link. It is assumed that the advantagesabove outweighs the disadvantages and that the capital letterprefixes for the backout and the redo will be visible enough in JBSto alert that something fishy is going on.
Quick Links
Once you have made a change that you want to integrate into anOpenJDK code base you need to create aPull Request (PR)on GitHub. This guide assumes that you have previous experiencefrom using git and GitHub and won’t go into details of howthose work. Still, the aim is of course to provide a useful guide,sosend an email if more detailsare needed.
It’s likely that other people have pushed changes to thecode base since you created your branch. Make sure to pull thelatest changes and rebase your fix on top of that before creatingyour PR. This is a courtesy issue. Your reviewers shouldn’thave to read your patch on top of old code that has since changed.This is hopefully obvious in cases where the upstream code has gonethrough cleanups or refactorings, and your patch may need similarcleanups in order to even compile. But even in cases where onlysmaller changes have been done, the reviewers shouldn’t haveto react to issues like “that line of code was moved lastweek, why is it back there?”.
git rebase master
After the PR has been published, rebasing, force-pushing, andsimilar actions are strongly discouraged. Such actions will disruptthe workflow for reviewers who fetch the PR branch. Pushing newchanges is fine (and even merging if necessary) for a PR underreview. Incremental diffs and other tools will help your reviewerssee what you have changed. In the end, all commits will be squashedinto a single commit automatically, so there’re actually nodrawbacks whatsoever to making commits to a PR branch duringreview.
Creating the PR is essentially the same as asking a large groupof people to start reviewing your change. Before doing that, youwant to make sure your change is done in every detail you have thepower to control. These are a few of the things you should thinkabout in order to avoid wasting people’s time on anunfinished change. (You may think that some of these are tooobvious to even mention, but all of them are things that in thepast have caused actual failures that broke the JDK forall developers out there.)
Is the copyright statement at the top of each modified sourcefile correct?
Did you run all relevant tests on the final version of thechange? (Yes, I mean final! If you only knew how many times peopleonly changed a comment and caused a build failure.)
Did yougit add
all new files?
Did you add regression tests for your change?
Did you run those new regression tests?
If you are unsure of any of these things but still want to goahead and create the PR,don’t!
If you have an actual reason to create a PR before the change isall done, make sure to create it inDRAFT
mode. Thebot won’t add therfr
label or send emails aslong as the PR is inDRAFT
mode.
Make sure the PR is reviewable
There are changes that span across several areas, for examplewide spread cleanups or the introduction of a new langauge feature.Accordingly, the number of lines of code touched can be quitelarge, which makes it harder to review the entire PR. In suchcases, it may make sense to split the change into several PRs, mostcommonly by grouping them by module or area.
Set a correctly formatted title
The title of the PR should be of the form “nnnnnnn:Title of JBS issue
” wherennnnnnn
is theJBS issue id of the main JBS issue that is being fixed, and theTitle of JBS issue
is the exact title of the issue aswritten in JBS. In fact, the title can be set toonly theJBS issue id (nnnnnnn
) in which case the bot willfetch the title from JBS automatically. If you are creating abackport PR, seeUsing the Skaratooling to help with backports for more details on the titlerequirements.
Write a useful description
The description of the PR should state what problem is beingsolved and shortly describe how it’s solved. Reviewers andother interested readers are referred to the text in the JBS issuefor details, but the description should be enough to give anoverview. This assumes there’s useful information in the JBSissue, like an evaluation etc. If not, add it.
Remember that the description is included in many emails sent tolists with many receivers, so a too long description can cause alot of noise, while of course a too short description won’tgive the reader enough information to perform the review. If youhave a lot of information you wish to add to your PR, likeperformance evaluations, you can put that in a separate comment inthe PR.
Finish the change before publishing it
Each update to a published PR will result in emails being sentto all relevant lists. This is per design and it’s how wewant it to be, but it also mean that if you publish a PR before youhave gone through the final check mentioned above, and later findthat a few more updates are necessary, a lot of people will get alot of emails.
Make sure all relevant groups are included
The bot will make an attempt to include the groups that need toreview your change based on the location of the source code youhave changed. There may be aspects of your change that are relevantto other groups as well, and the mapping from source to groupsisn’t always perfect, so make sure all relevant groups havebeen included, and add new labels using/label
if needed.
Allow enough time for review
In general all PRs should be open for at least 24 hours to allowfor reviewers in all time zones to get a chance to see it. It mayactually happen that even 24 hours isn’t enough. Take intoaccount weekends, holidays, and vacation times throughout the worldand you’ll realize that a change that requires more than justa trivial review may have to be open for a while. In some areastrivial changes are allowed to be pushedwithout the 24 hour delay. Ask your reviewers if you think thisapplies to your change.
At least one reviewer should be knowledgeable in the area beingchanged. Some areas (e.g. client and hotspot) require tworeviewers in most cases, so be sure to read the relevant OpenJDKgroup pages for advice or ask your sponsor.
Updating the PR
You may need to change the code in response to review comments.To do this, simply commit new changes and push them onto the PRbranch. The PR will be updated automatically. Multiple commits tothe branch will be squashed into a single commit when the PR iseventually integrated.
If the set of files in the PR has changed, this may affect thegroups that need to review the PR. Make sure to adjust the PRlabels accordingly.
Merge the latest changes
If your PR is out for review for a longer time it’s a goodhabit to pull from the target repository regularly to keep thechange up to date. This will make it easier to review the changeand it will help you find issues caused by other changes sooner.Typically this involves fetching changes from the master branch ofthe main JDK repo, merging them into your local branch, resolvingconflicts if necessary, and then pushing these changes to the PRbranch. Pushing additional commits and merges into the PR branch isfine; they will be squashed into a single commit when the PR isintegrated. Avoid rebasing changes, and prefer merging instead.
If there are upstream changes that might affect your change,it’s likely a good idea to rerun relevant testing as well.TheGHA testing that’s doneautomatically by GitHub should only be seen as a smoke test thatfinds the most severe problems with your change. It’s highlyunlikely that it will test your actual change in any greater detail- or even at all execute the code that you have changed in mostcases.
Integrate your change
When you have the required reviews and have made sure allrelevant areas have had a chance to look at your change, integrateby entering the command/integrate
in a comment on the PR. If you are notyet a Committer in the project, ask your sponsor to enter thecommand/sponsor
in the PR as well in order for yourchange to be allowed to be integrated.
Quick Links
As all OpenJDK projects are hosted on GitHub, most code reviewstakes place there. When you publish a PR to an OpenJDK repositorythe corresponding JBS issue will get a link to the code review inthe PR, making this the natural place to go for review. OpenJDK dohowever provide other tools and infrastructure for code reviews aswell: Thewebrevs.
Webrev refers to both the tool used to create them and itsoutput. The script,webrev.ksh
,is maintained in theCodeTools project. Please note that this version of webrev is foruse with mercurial and won’t work with the git basedrepositories. You don’t actually need tools like this anymoreunless you want to host code reviews in other locations thanGitHub.
On the GitHub reviews you will find links to webrevs. These areautomatically generated by the bot and are provided as a complementfor those who prefer this style of code review. Many OpenJDKdevelopers are used to the webrevs as this was the default way toprovide code for review before OpenJDK moved to GitHub. Thoughwebrevs are mainly deprecated today, they used to be a central partof OpenJDK development and you may still see people use the word asa synonym for code review, so they do deserve to be mentioned hereas well.
cr.openjdk.java.net
Thecr.openjdk.java.net
server provides storage anddisplay of code review materials such as webrevs and otherartifacts related to the OpenJDK Community. This area can also beused to store design documents and other documentation relatedOpenJDK but not related to any specific project that have anOpenJDK wiki space for such purposes.
Any OpenJDK Author can publish materials on thecr.openjdk.java.net
server. Users can upload files totemporary storage using secure methods (rsync
,scp
, andsftp
).
This site is for open source materials related to the OpenJDKCommunity only. Users uploading inappropriate materials will loseaccess and the material will be deleted. Please review theTerms of Use beforeusing this server.
Development of the latest version of the JDK often results inbug fixes that might be interesting to include in some of the JDKupdate releases still being maintained. Moving a fix from a morerecent release train (e.g. JDK 17) to an older release train(e.g. JDK 11) is calledbackporting.
The guideline for what to backport into a specific updaterelease will vary over the lifetime of that release. Initially morefixes are expected to be backported as new features and largechanges introduced in a mainline release stabilize. Over time thefocus will shift from stabilization to keeping it stable - therelease will go into maintenance mode. This means that bug fixesthat require larger disruptive changes are more likely to be madein mainline and backported to more recent release trains only, andnot to older release trains.
Over time it’s likely that the code base will divergebetween mainline and any given update release, and the cost ofbackporting will increase. The cost in this case is not only theeffort needed to perform the actual backport, but also the costinferred by bugs introduced by the backport. This should be takeninto consideration when deciding if a change should be backportedor not. For more details on how to reason around what to backport,this email from JDK 8 Updates Project lead Andrew Haley hassome guidelines for JDK 8u. The reasoning in this mail is specificto JDK 8u, but will in general apply to any JDK release inmaintenance mode.
Any change that originally required a CSR will require a new CSRto be backported unless the backport was covered by the initialCSR. Changes to Java SE specifications cannot be made in an updaterelease without a Java SE Maintenance Release. CSR-related issuesaffect interfaces and behavior and must be very carefullyscrutinized.
Terminology
Main issue - The top issue in a backport hierarchy. Eg.JDK-8272373is a main issue, whileJDK-8277498andJDK-8277499are backport issues of this main issue.
Example of backport hierarchy
In general there’s no need to create backport issues inJBS manually. All work that’s done in JBS in preparation fora backport (requesting approvals etc) is done in the main issue.The backport issue will be created automatically by the bots whenyou integrate the change to the source code repository.
There can be cases where it’s desirable to create abackport issue before the fix is done, e.g. if a CSR needs tobe filed. In these cases set theFixVersion/s of the backport toN-pool
, whereN
is the release train the backport is targeting. E.g.17-pool
. Please note that even if a backport issue iscreated ahead of time, all work done in JBS is still done in themain issue.
Obviously it’s possible to set theFix Version/s to the exact release the backportis targeting, but this isn’t recommended. When a change ispushed, the bots will look at the main issue as indicated in the PRtitle, and look for backports with the currentN.0.x
release version asFix Version/s, ifno such backport is found they will look forN-pool
,and if that isn’t found either, a new backport issue will becreated. This means that if the backport has an exactFix Version/s set, but is delayed and misses therelease indicated by thisFixVersion/s, a new backport issue is created with a small messas the result.
Setting theFix Version/s of abackport toN
is always wrong. JDKN
hasalready been released (or you wouldn’t be trying to backportto it) and can’t get any more fixes.
In order to be allowed to push a change to one of the OpenJDKupdate development repositories (e.g. jdk17u-dev
),an approval is required. Theofficialprocess for how to request push approval for a backportdescribes in detail how to work with JBS when requesting approvals.In short, there’s a labeljdk<release>u-fix-request that should beadded to the main JBS issue. Also put a motivation as to why theissue needs to be backported as a comment in the main issue. Oncethe label and motivation has been added, wait for the maintainersof the release to approve your request. The approval will beindicated with a label,jdk<release>u-fix-yes, added to the mainissue.
If the update release is in rampdown, changes are pushed to therelease repository (e.g. jdk17u
).During rampdown the bar to get changes in are significantly higherand fixes need to be approved withjdk<release>u-critical-request /jdk<release>u-critical-yes.
The Skara tooling includes support for backports.Theofficial Skara documentation describes in detail how to workwith the tooling to create backport PRs on GitHub or using the CLItools. As described in the documentation, the/backport
command can be used on a commit (not aPR!) to create the backport PR. If a backport PR is manuallycreated, set the PR title toBackport <original commithash>
. This ensures that the bots will recognize it as abackport as opposed to a main fix specifically targeting an olderrelease. One can tell whether or not the bots recognized a PR as abackport by thebackport label beingadded if it’s recognized.
If a main bug is targeted to a release and a fix referring tothat main bug is pushed to a different release, then a backport bugis automatically created in JBS. Usually this is a “goodthing”, e.g., when you are backporting a fix to an earlierrelease, but not always… If the main bug is targeted to alater release (due to schedule planning), but someone finds thetime to fix that bug in the current release, then the bug should beretargeted to the current release before pushing the fix. However,sometimes we forget to do that.
Here’s how to fix that:
In this example a fix was pushed to JDK N (a.k.a. the currentrelease) while the JBS bug was targeted to JDK N+1 (a.k.a. a futurerelease). The same procedure can be used in the opposite situation,when a fix has been pushed to JDK N+1 when the JBS bug was targetedto JDK N, by switching N and N+1 below. Remember, to keep therecord clean for the future, what matters the most is that the bugid used in the commit comment is the main bug, and that the“backports” (regardless of if they are to earlier orlater releases) are Backport type issues of that main issue. Alsomake sure there are never more than one Backport issue targeted toany given release.
Fix was pushed while main bug was targeted to 'N+1'. Reset the main bug to fixed in 'N', reset this bug to fix in 'na' and closed as 'Not An Issue' since JDK N+1 will automatically get this fix from JDK N later.
Changeset: 12345678Author: Duke <duke@openjdk.org>Date: 2020-10-23 15:37:46 +0000URL: https://git.openjdk.java.net/jdk/commit/12345678
Fix was pushed while main bug was targeted to 'N+1'. Reset the main bug to fixed in 'N' and copied the Robo Duke entry here.
Release notes for a product such as the JDK are part of therelease deliverables providing a way to highlight information abouta fix, such as when it may have changed behavior, or whenit’s decided not to fix something. While what should go intoa release note isn’t something that can be precisely defined,it should describe changes that are important for a user to takeinto account when they are upgrading to the specific version. Whilerelease notes should not duplicate information in other documents,they can serve to highlight that a change has been made.
Release notes are associated with a JBS issue that has beenfixed (or in some cases not been fixed) in a release and aregenerated with each build of a release. Any note should beconsidered as an integral part of the fix process, rather thanwaiting until the end of the release to determine what to write. InOpenJDK, release notes are currently being generated for the JDKand JDK Updates projects.
Writing the release note is the responsibility of the engineerwho owns the issue. The note should be generated before the fix isreviewed, or in the case of known issues, when it’sdetermined that a fix won’t be possible in the release theissue was found in.
When writing a release note, be prepared for rather picky reviewcomments about grammar, typos, and wording. This is for the sake ofthe Java community as a whole, as the language of the release notesets the tone for many blogs and news articles. For a widely usedproduct like the JDK, the release notes are often copied verbatim(including typos) and published to highlight news in the release.This means that we need to take extra care to make sure the text inthe release note is correct and follows a similar style.
The release note itself is written in aJBS sub-task of the issue that is usedto push the change. There are a few steps to follow for the releasenote to find its way from JBS to the actual release notedocument.
Create a sub-task (More → Create Sub-Task) for the issuethat requires a release note - the main issue, that is, the JBSissue that is used to push the original change,not for backports or the CSR (if there isone).
For the newly created sub-task, follow these steps:
Have the release note ready to be reviewed at the same time asthe code is reviewed. If it’s later determined that a releasenote is necessary, then go back to the same engineers who reviewedthe fix to review the release note. Special care should be takenwhen writing a release note that will cover changes related to avulnerability fix in order to avoid describing technical details ofhow it could have been exploited.
When you are done,Resolve the release note sub-task asDelivered
. Only release notes where the sub-task hasbeen resolved asDelivered
is considered to be part ofthe EA/GA release notes. To avoid mixing up the release notes withthe code fixes that have gone into a particular release or build,we don’t useResolved/Fixed
.
If you see an issue you feel should have a release note but youare not the assignee of the bug, then add the labelrelease-note=yes to the main bug (not on abackport nor a sub-task). This acts as a flag to make sure that therelease note is considered. This can be done even with fixes thathave been shipped already if it’s noticed that there isconfusion around the change. If, after discussion, it’sdecided that a release note isn’t required either remove thelabel, or change it torelease-note=no if it makes sense to have aclear indication that a release note isn’t required for thefix. The labelrelease-note=yes canbe removed once the release note sub-task has been created.
For examples of well written release note issues in JBS, seeJDK-8276929orJDK-8278458.
The following are general practices that should be followed whencreating release notes.
Release notes should be no longer than 2-3 paragraphs.
Don’t repeat information that will be included in updatesto the docs, keep it to a high level summary or key changes.
Note that where the changes are more fully documented in the JDKdocumentation, then refer to that document for details. Whencovering a change in behavior provide some idea to what can be doneif a developer or user encounters problems from the change.
Don’t include graphics etc. Refer to the main docs ifthere are more details that need explaining.
Don’t include your name or affiliation, make sure however,you are the assignee of the release note sub-task.
If you have a < in theSummarythen use<
. For <’s in theDescription surround them byback-ticks.
Avoid using Latin and abbreviations in the release note.
TheSummary should be in titlecase instead of sentence case.
TheDescription should bestandardized to follow this pattern:
jdk.disableLastUsageTracking
, has been introduced todisable JRE last usage tracking for a running VM.Special case: JEP release note
Unless labeled otherwise it will be assumed that the releasenote documents a change in behavior (will have likely required aCSR) or other item which should be included in the release notes.If the note covers a more specific type of change, then one of thefollowing labels can be included (notes of a similar type will belisted together).
The Release Notes for a particular release can be found usingthe JBS query
affectedversion = <version> and type = sub-task and labels = release-note
where<version>
is the appropriate releasevalue, e.g. 17.
Quick Links
While developing your fix, your might want your code to outputsome diagnostic information. You might even want to leave somelogging in the code you check in, to facilitate futurediagnostics.
The appropriate way to print logging output from HotSpot isthrough theUnifiedLogging Framework (JEP 158). It gives you a lot of nicefeatures and enables common command-line options for all logging.Messages can also be “decorated” with e.g. uptime,level, tags. The JEP contains a thorough description of thefeature, but a quick example might look like:
(gc, marking)("Mark Stack Usage: " SIZE_FORMAT"M", _mark_stack_usage/ M); log_info
Where ‘gc’ and ‘marking’ are tags, and‘info’ is the log level. This would be visible if theJVM were run with any of the following flags:
-Xlog:gc+marking=info-Xlog:gc+marking-Xlog:gc*
The API should be similar to:
log_<level>(Tag1[,...])(fmtstr,...)
At the time of writing, the different log levels can be found insrc/hotspot/share/logging/log.hpp.
After the initial release of the JDK source code into OpenJDK in2007 the OpenJDK project moved from TeamWare to using Mercurial.Starting in 2019 the source revision control has been moved to Gitand GitHub. Even though most large projects have moved to Git bynow, some still use the Mercurial servers. To access these projectssome additional setup is required.
There used to be a sandbox repository that could be used fortesting purposes. With the move to Git this has been replaced byGitHub Actions.
This document assumes familiarity with the first two chapters ofthe free on-line bookMercurial: The DefinitiveGuide.
Source bundles and binary packages for Mercurial are availableathttps://www.selenic.com/mercurial/wiki/index.cgi.The OpenJDK repositories recommend installation of Mercurial 2.6.3(or later). A Mercurial installation is sufficient to clone arepository. Contributors who wish to submit changes will need someadditional configuration as described below.
Once Mercurial is installed, create and edit the~/.hgrc
file to minimally contain the followingentry:
[ui]username = <openjdk_username>
openjdk_username is in general the same as your GitHubuser name. (SeeContributing to an OpenJDKProject for more information.) If you don’t have a GitHubuser name, you choose your OpenJDK user name when you sign the OCA.The user name should be a plain lowercase, alphanumeric token (notan e-mail address) with twelve characters or less. The firstcharacter should be alphabetic. This username will be publiclyvisible in all Mercurial changeset logs. It will be used to verifythat the changeset author is at least anAuthor for the Projectand that the person pushing the changeset is at least aCommitter.It’s recommended that theopenjdk_username besomehow related to the Author’s full name, such as the firstcharacter of the Author’s first name followed by theAuthor’s last name.
Some Projects may recommend additional tools or scripts thathelp with repository manipulation and code development. Forinstance, in JDK 8u, the utility scriptcommon/bin/hgforest.sh
may be used to apply commandsto all the repositories in theforest. Someuseful Mercurial extensions for OpenJDK developers arejcheck,trees,andMercurial Queues (mq). Note thattrees
is enabledon the OpenJDK Mercurial server.
After installing and configuring Mercurial, validate theconfiguration using the following steps.
Verify that Mercurial is version 2.6.3 (or newer).
$ hg versionMercurial Distributed SCM (version 2.9)(see http://mercurial.selenic.com for more information)Copyright (C) 2005-2014 Matt Mackall and othersThis is free software; see the source for copying conditions. There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Verify that the list of enabled extensions includes fetch andmq.
$ hg help
Verify that the~/.hgrc
configuration lookscorrect. Minimally it should contain the following entries:
$ hg showconfigui.username=iris
At this point, it should be possible to start retrieving sourcefrom the repositories.
Some Projects organized their code into multiple Mercurialrepositories. For instance,JDK 8 uses a forest ofmultiple related repositories which contain components of theentire JDK. If a Project uses a forest, It’s stronglyrecommended for developers to clone an entire forest, rather than asingle repository. This is the only means to ensure consistency inbuilds. The following examples illustrate two alternatives forcloning the entirejdk8u/jdk8u-dev
forest into thedirectory8u-dev
.
To clone the forest using thetreesextension just usetclone
:
$ hg tclone http://hg.openjdk.java.net/jdk8u/jdk8u-dev/ 8u-dev
To clone the forest usingget_source.sh
, firstclone the main tree:
$ hg clone http://hg.openjdk.java.net/jdk8u/jdk8u-dev/ 8u-devrequesting all changesadding changesetsadding manifestsadding file changesadded 997 changesets with 1477 changes to 138 filesupdating to branch default82 files updated, 0 files merged, 0 files removed, 0 files unresolved
Then clone the repositories in the forest:
$ cd 8u-dev$ sh ./get_source.sh
Regardless of how the forest was cloned, this is the resultingpopulated forest.
$ lsASSEMBLY_EXCEPTION hotspot LICENSE README-builds.htmlcommon jaxp make testconfigure jaxws Makefile THIRD_PARTY_READMEcorba jdk nashornget_source.sh langtools README
If the source for the Project is contained within a singlerepository or reading a limited portion of the source is the onlygoal, it’s possible to clone a single repository (even ifit’s part of a forest). For instance, this example shows howto clone thelangtools
repository fromjdk8u/jdk8u-dev
into the default destinationdirectory.
$ hg clone http://hg.openjdk.java.net/jdk8u/jdk8u-dev/langtoolsdestination directory: langtoolsrequesting all changesadding changesetsadding manifestsadding file changesadded 2289 changesets with 21194 changes to 7004 filesupdating to branch default6212 files updated, 0 files merged, 0 files removed, 0 files unresolved
The timing for creating a changeset is important. Creating thechangeset long before it gets pushed into the parent repository mayrequire complex merges. If a changeset is created before sufficientreview or testing, a rollback may be required and a new changesetmay be required to correct previous mistakes. Themqextension is recommended for managing changes before theybecome committed to a changeset.
In the examples below, the scriptcommon/bin/hgforest.sh
can be used to apply theMercurial command to all the repositories in the forest. So whenyou seehg
, if you are dealing with one repository,just use “hg
”, if it’s a forest, use“sh common/bin/hgforest.sh
”.
Each repository in the forest is managed independently. Afterediting files in the individual cloned repositories of the forest,thehg status
command may be used to see the changesin a single repository.
$ hg root/u/iris/sandbox/box$ hg status? duke/images/DukeTubbingSmall.png$ hg add duke/images/DukeTubbingSmall.png$ hg statusA duke/images/DukeTubbingSmall.png
To see changes made to the repositories usehgstatus
:
$ hg status[.]A duke/images/DukeTubbingSmall.png
In this example, a new fileDukeTubbingSmall.png
was added to a new subdirectory.
A single change is described by a block of text of the followingform:
<bugid>: <synopsis-of-symptom>Summary: <summary-of-code-change>Reviewed-by: <reviewer>+Contributed-by: <contributor-email>
There may be more than onebugid line, but there mustbe at least one.
Thesummary line is optional, but authors are stronglyencouraged to include one if the nature of the change isn’tobvious from the synopsis. It’s just one line, meant to givethe reader a clue as to how the code changed. A more completedescription of the change belongs in the bug report.
Areviewed-by line is required. Reviewers must have theability to deal with any adverse consequences of the change, and somust themselves be authors. They are therefore identified by theirOpenJDK usernames rather than full e-mail addresses.
Thecontributed-by line is optional. If present,it’s a list of comma-separated email addresses. It should beincluded only when the author of the change doesn’t havecommit rights to the target repository and thus would not otherwisereceive acknowledgment, or when there are multiple authors.
There will be exceptions for merge changesets, tag changesets,etc.
Example:
1234567: NPE thrown on FileInputStream("")Summary: Rewrite precondition-checking code in io.cReviewed-by: mrContributed-by: Ben Bitdiddle <ben at bits.org>
If a changeset contains multiple unrelated changes (this isfrowned upon, but may happen from time to time) then its commentwill contain multiple blocks of the above form, separated by blanklines.
The required format of the comments will be enforced wheneverthe changeset is pushed into the JDK forests. Other Projects maycopy these conventions, adopt some other conventions, or have noconventions, depending upon their goals.
The following commands commit all of the changes in a repositoryto a changeset.
$ cat ../message1111111: Missing Duke gifSummary: Add missing fileReviewed-by: iag$ hg commit -l ../message$ hg toutgoing[.]comparing with http://hg.openjdk.java.net/sandbox/boxsearching for changeschangeset: 23:fb12953f3a35tag: tipuser: irisdate: Wed Dec 12 21:05:59 2007 -0800summary: 1111111: Missing Duke gif
It’s often necessary to merge local changes with thosemade in the parent repositories. The first step in a merge processis to retrieve (or pull) the collection of changesets which havebeen pushed since the last merge or initial clone. If there ifthere are merge conflicts, then they must be resolved.Chapter 3of the Mercurial book contains detailed information on the mergingprocess.
There are two basic ways to update the working set files in therepositories:
Option 1:hg pull
One way to merge the parent repository with the working set offiles is to use
hg pull
all by itself. This optionallows merging off-line or at a later time.$ hg pull[.]pulling from http://hg.openjdk.java.net/jdk8u/jdk8u-devsearching for changesno changes found
In Mercurial, pulling changesets will not update or merge intothe working set of files. To update the clone, run
hgupdate
. If the update reports conflicts, runhgmerge
to resolve them.
Option 2:hg fetch
Alternatively, use
hg fetch
to pull the changes,update the working set files, and create simple merge changesets asnecessary. The fetch extension is distributed with Mercurial butneeds to be enabled. Edit the.hgrc
to include thefollowing entries:[extensions]fetch=
Once the fetch extension has been enabled,
hg fetch
may be invoked as follows:$ hg fetch[.]pulling from http://hg.openjdk.java.net/jdk8u/jdk8u-devsearching for changesno changes found
Actual file merging will be done with the selected Mercurialmerging tool seeMergeProgramfor the details on how to define the selected merge tool in
~/.hgrc
.
In order to push changesets into the parent repository, someadditional configuration is required. The following sectionsdescribe the operations that will be performed by users with pushaccess.
First you should create a new SSH key. SeeGenerating an SSH key for guidance onhow to do that. Your public key (~/.ssh/id_rsa.pub
)should be mailed as an attachment along with your JDK username tokeys(at)openjdk.java.net. Anadministrator will install your key on the server and notify you oncompletion. This process may take a couple of days.
Users behind a SOCKS firewall can add a directive to the
~/.ssh/config
file to connect to the OpenJDK Mercurialserver:Host *.openjdk.java.netProxyCommand /usr/lib/ssh/ssh-socks5-proxy-connect -h [socks_proxy_address] %h %p
See the
ssh-socks5-proxy-connect
man page andssh-config
man page for more information. Othersystems may require proxy access via other programs. Some Linuxdistributions provide thecorkscrew
package whichprovides ssh access through HTTP proxies.It’s recommended that all users check with theirnetwork administrators before installing any kind of TCP forwardingtool on their network. Many corporations and institutions havestrict security policies in this area.
default-push
path to the serverrepositoriesThis is the typical development model:
Diagram of server repos and user's clone
Changesets need to bepushed via ssh to the read/writerepository which resides on the OpenJDK Mercurial server. Theeasiest way to do this is to have each repository define the“default-push” path in every repository’s.hg/hgrc
file. The.hg/hgrc
fileisn’t a managed file - it’s private to the repository.The following example defines the “default” and“default-push” paths for clones of thejdk8u/jdk8u-dev
repository.
[paths]default = http://hg.openjdk.java.net/jdk8u/jdk8u-devdefault-push = ssh://<JDK_username>@hg.openjdk.java.net/jdk8u/jdk8u-dev
Given aJDK_username
this simple script willattempt to do this for all the repositories:
#!/bin/shusername=$1hgdirs="`find . -type d -name .hg`"for i in ${hgdirs}; do d="`dirname ${i}`" defpush="`(cd ${d} && hg paths default-push 2> /dev/null)`" if [ "${defpush}" = "" ] ; then defpath="`(cd ${d} && hg paths default 2> /dev/null)`" if [ "${defpath}" != "" ] ; then defpush="`echo ${defpath} | sed -e 's@http://\([^/]*/[^/]*/[^/]*\)/\(.*\)@ssh://$username\@\1/\2@'`" cp ${i}/hgrc ${i}/hgrc.orig echo "default-push = ${defpush}" >> ${i}/hgrc echo "Added default-push: ${defpush}" fi fidonefor i in ${hgdirs}; do d="`dirname ${i}`" echo "(cd ${d} && hg paths)" (cd ${d} && hg paths)doneexit 0
Committers can usethehg push
command to propagate changesets into therepositories.
Most developers will only find a need to create changesets inone or two repositories. However, it’s important that beforeany changesets are pushed, the corresponding forest pull and mergewith the destination forest be performed; otherwise there is a riskof breaking the build.
$ hg push
After the push has been accepted, an automatic e-mailnotification will be sent to themailing list associated withthe repository. In most cases notifications are sent to theProject’s-dev mailing list. Some Projects with hightraffic-dev mailing lists use a dedicated-changes list for notifications.
Who has push access?
All of a Project’sCommitters can pushto all of the the Project’s repositories.
Some Projects may chose to restrict the set of Committers withpush to key repositories. For instance, JDK Release Projectsrestrict push access to MASTER repositories to Committers who areeither integrators or members of the Release Engineering Team.
SeeBecoming a Committer forinformation about becoming a Project Committer.
Quick Links
The JDK project has a well defined release process.JEP 3 describes this processin detail. This section intends to clarify some topics that oftencause questions.
The release cycle starts when development of a new releasebegins, and ends when that release is delivered to the public. Thecurrent release cadence is six months. This means that every sixmonths we start development of a new release, and every six monthsa new release is delivered. However, this doesn’t mean thateach release cycle is six months. As described below, the totaldevelopment time for a release (the release cycle) is actually ninemonths. Obviously this in turn doesn’t mean that all featuresare developed in nine months. Most features are developed for amuch longer time than that, and goes through long time developmentin other project repositories, and through a series of preview andexperimental stages. But any feature that is to be included in aspecific release has a specific window of nine months to integratethe code into mainline and fix all the remaining bugs.
It may be tempting to integrate a new feature near the end of arelease cycle, to get more time to fix all those last bugs beforeintegration. Please don’t. If you are getting close to theend of a release and you still just have one more bug to fix,please defer your feature to the next release. It’s only sixmonths out. Not only will this vouch for your new feature to bemore stable on release, you will also help keeping the JDK as awhole more stable by allowing others to find and fix bugs in theirnew code that might come as a result of your changes.
Integrating early in a release is preferable, but all newfeatures can’t be integrated at the same time. If many largechanges enters the repository at the same time it will be moredifficult to determine which change that caused all the new bugs.If you’re about to integrate a larger change you musttherefore communicate this on the relevantmailing lists to synchronize with otherprojects that may also be planning to integrate something soon.
Throughout the release there are a number of milestones andphases that define where in the release cycle we are.
Even though there’s nothing explicitly written in theprocess about deferring P1 and P2 bugs during the initialdevelopment phase, the assumption is that these aren’tdeferred unless time runs out at the end of the release cycle.
Please note that the priority of a bug doesn’t change justbecause you want to get your fix in late in the release, or if youwant to be able to defer it. The priority is based on the severityof the bug and if it was deemed to be a P2 before, you better havea really good explanation to why that conveniently has changed bythe end of the release. Being hard to fix isnot areason to lower the priority of a bug.
During the rampdown of a release there are two repositories inplay, the stabilization fork for the outgoing release, and themainline repository where the next release is being developed. Anybugfix going into the stabilization fork is likely to be desired inmainline as well. As a developer you should push your fix to thestabilization forkonly, even if you intend for itto go to both repositories. Your fix will be forward ported tomainline.
All fixes that are pushed to the stabilization fork areforward ported to mainline. If you have a fix that is only intendedfor the stabilization fork you will have tomanually back it out from mainline once it hasbeen forward ported. In order to remember to do this you shouldfile a backout isue in JBS before pushing your change to thestabilization fork. E.g., To push JDK-xxx to the stabilization forkbut not to mainline, you need to file an issue, JDK-yyy, in JBS toback out the fix after it has been merged into mainline. Make surethe two JBS issues (JDK-xxx and JDK-yyy) are related so thatit’s easy to find one from the other.
To clarify, as soon as you know that there is a fix that needsto go into the stabilization fork but not mainline, you should dothe following:
relates to
linkThen, you have to wait until the JDK-xxx fix is forward portedto mainline before actually fixing JDK-yyy. Making these settingsin JDK-yyy will help ensure that it won’t be missed.
There are also examples in JBS where JDK-yyy has been created asa sub-task of JDK-xxx. This works, but isn’t recommendedsince JDK-yyy stands a higher risk of being missed when it’snot of typeBug but rather asub-task of analready closed issue. Also seeBacking out a change for reference.
This list is intended to make it easier to identify which emaillist to include in code reviews when making changes in differentareas. The list may also help when assigning bugs based on whichcode they are found in. Please note that some directories may havebeen created or removed between releases. The intention here is toinclude directories that exists in mainline, LTS releases and otherreleases (post JDK 9) commonly being updated.
build-dev@openjdk.java.net
awt-dev@openjdk.java.net
beans-dev@openjdk.java.net
2d-dev@openjdk.java.net
openjfx-dev@openjdk.java.net
core-libs-dev@openjdk.java.net
sound-dev@openjdk.java.net
swing-dev@openjdk.java.net
core-libs-dev@openjdk.java.net
hotspot-dev@openjdk.java.net
i18n-dev@openjdk.java.net
amber-dev@openjdk.java.net
compiler-dev@openjdk.java.net
javadoc-dev@openjdk.java.net
kulla-dev@openjdk.java.net
panama-dev@openjdk.java.net
valhalla-dev@openjdk.java.net
security-dev@openjdk.java.net
make
– Build teamhotspot
– HotSpotcpu
– Compiler, Runtimejdk.*
– Compileros
– Runtimeos_cpu
– Compilershare
adlc
– Compileraot
– Compilerasm
– Runtimec1
– Compilerci
– Compilerclassfile
– Runtimecode
– Compilercompiler
– Compilergc
– GCinclude
– HotSpotinterpreter
– Runtimejfr
– JFRjvmci
– Compilerlibadt
– Compilerlogging
– Runtimememory
– Runtime, GCmetaprogramming
– Runtimeoops
– Runtimeopto
– Compilerprecompiled
– Runtimeprims
– Runtime, Serviceabilityruntime
– Runtimeservices
– Runtimeshark
– Compilertrace
– Runtimeutilities
– Runtimejava.base
classes
crypto
– Securityinternal
– HotSpot, Core Libsinvoke
– Core Libsio
– NIOlang
– Core Libslauncher
– LangToolsmath
– Core Libsnet
– Netnio
– NIOreflect
– Core Libssecurity
– Securitytext
– I18ntime
– Core Libsutil
– I18n, Core Libsconf
sdp
– Netsecurity
– Securitylegal
–lib/security
– Securityman
java.1
- LangToolsjfr.1
- Runtimekeytool.1
- Securitynative
common
–include
– Runtime, Core Libsjspawnhelper
– LangToolslauncher
– LangToolslibfdlibm
– Core Libslibjava
– Core Libslibjimage
– LangTools, Core Libslibjli
– LangToolslibjsig
– HotSpotlibnet
– Netlibnio
– NIOlibosxsecurity
– Securitylibverify
– LangToolslibzip
– Core Libsjava.compiler
– LangToolsjava.datatransfer
– AWTjava.desktop
– Clientcolor
,font
,freetype
,geom
,imageio
,java2d
,jpeg
,lcms
,mlib
,print
, graphics primitives – 2Dsplashscreen
,dnd
,eawt
,lwawt
– AWTim
, input methods – I18n, AWTlibjsound
,sound
– Soundaccessibility
,laf
– Swingjava.instrument
– Serviceabilityjava.logging
– Core Libsjava.management
– Serviceabilityjava.management.rmi
– Serviceabilityjava.naming
– Core Libsjava.net.http
– Netjava.prefs
– Core Libsjava.rmi
– Core Libsjava.scripting
– LangToolsjava.se
– Core Libsjava.security.jgss
– Securityjava.security.sasl
– Securityjava.smartcardio
– Securityjava.sql
– Core Libsjava.sql.rowset
– Core Libsjava.transaction.xa
– Core Libsjava.xml
– Core Libsjava.xml.crypto
– Securityjdk.accessibility
– Swingjdk.aot
– HotSpot Compilerjdk.attach
– Serviceabilityjdk.charsets
– I18n, Core Libsjdk.compiler
– LangToolsjdk.crypto.cryptoki
– Securityjdk.crypto.ec
– Securityjdk.crypto.mscapi
– Securityjdk.crypto.ucrypto
– Securityjdk.dynalink
– LangToolsjdk.editpad
– LangToolsjdk.hotspot.agent
– Serviceabilityjdk.httpserver
– Netjdk.incubator.foreign
– LangToolsjdk.incubator.httpclient
– Netjdk.incubator.jpackage
– Clientjdk.incubator.vector
– HotSpot Compilerjdk.internal.ed
– LangToolsjdk.internal.jvmstat
– Serviceabilityjdk.internal.le
– LangToolsjdk.internal.opt
– LangToolsjdk.internal.vm.ci
– HotSpot Compilerjdk.internal.vm.compiler
– HotSpotCompilerjdk.internal.vm.compiler.management
–HotSpot Compilerjdk.jartool
– LangToolsjdk.javadoc
– LangToolsjdk.jcmd
– Serviceabilityjdk.jconsole
– Serviceabilityjdk.jdeps
– Core Libsjdk.jdi
– Serviceabilityjdk.jdwp.agent
– Serviceabilityjdk.jfr
– JFRjdk.jlink
– LangToolsjdk.jpackage
– Clientjdk.jshell
– LangToolsjdk.jsobject
– LangToolsjdk.jstatd
– Serviceabilityjdk.localedata
– I18njdk.management
– Serviceabilityjdk.management.agent
– Serviceabilityjdk.management.jfr
– Runtimejdk.naming.dns
– Core Libsjdk.naming.rmi
– Core Libsjdk.net
– Netjdk.nio.mapmode
– NIOjdk.pack
– LangToolsjdk.rmic
– Core Libsjdk.scripting.nashorn
– LangToolsjdk.scripting.nashorn.shell
– LangToolsjdk.sctp
– Netjdk.security.auth
– Securityjdk.security.jgss
– Securityjdk.unsupported
– Core Libsjdk.unsupported.desktop
– Swingjdk.xml.dom
– Core Libsjdk.zipfs
– Core Libssample
–utils
–This guide is being maintained through theOpenJDK Developers’Guide Project. Thesource repository isavailable at GitHub. The revision hash at the bottom of each pagerefers to the latest change that modified that particular page.
Comments and questions may be sent toguide-dev (at)openjdk.java.net. Please let us know if there’s anythingin the guide that isn’t clear.
common/bin/hgforest.sh
can be used to apply aMercurialhg
command to all the repositories in aforest.git revert
. It’s upto the author of a change to claim that the change is trivial inthe RFR, and it’s up to the Reviewer whether to approve sucha claim. A change is trivial only if the Reviewer agrees that itis. A trivial change doesn’t need to wait 24 hours beforebeing pushed, and it only needs one Reviewer, even in areas wherestricter rules for pushing normally apply.webrev.ksh
, examines a forest or repository togenerate a set of web-based views of differences.