1 Working on OpenJDK using NetBeans
   2     This note describes how to work on the OpenJDK from NetBeans. We've
   3     provided several NetBeans projects as starting points. Below we'll
   4     describe how to use them, as well as how to create your own.
   5 
   6 Getting Started
   7     In addition to the source bundle for Open JDK, you'll need to download
   8     and install copies of the JDK and of NetBeans. And if you want to run
   9     tests on the JDK (you do want to run tests, right?), you'll need to
  10     install the jtreg test harness.
  11 
  12     In this note, when pathnames are not fully specified, they should be
  13     interpreted as being relative to the directory containing this README
  14     and the NetBeans projects themselves.
  15 
  16         The JDK build process is largely make-based, and is not
  17         exceptionally tolerant of pathnames with spaces in them (such as
  18         "Program Files". Please be sure to install everything in a
  19         directories whose paths don't have any spaces!
  20 
  21     Downloading the JDK
  22         You've probably done this a million times. Download and install it
  23         from http://www.oracle.com/technetwork/java/javase/overview/index.html
  24 
  25     Downloading the OpenJDK sources
  26         Since you're reading this, d you've already downloaded the OpenJDK
  27         source bundle.  Later in this document we'll refer to the location
  28         where you installed the Open JDK sources as *install-dir*.
  29 
  30     Downloading a pre-built, JDK 8
  31         This will be necessary to do builds of some of the projects.  In
  32         general, you want to download and install a pre-built JDK that
  33         corresponds to the OpenJDK sources you download.  Building the entire
  34         OpenJDK depends on a few parts of the pre-built JDK.  Get this from
  35         http://download.java.net/jdk8/binaries
  36 
  37         Note: For working on certain projects, like JMX and JConsole, you
  38               may find convenient to use a pre-built version of JDK 8 (or
  39               OpenJDK) rather than building your own. This will allow you
  40               to build only that part of the OpenJDK sources which correspond
  41               to that project.
  42 
  43     NetBeans 7.0 or later
  44         Older versions may also work but are unsupported.
  45 
  46     jtreg
  47         "jtreg" is the test harness for running OpenJDK's regression tests.
  48         Get it from http://openjdk.java.net/jtreg
  49 
  50     Ant
  51        NetBeans comes with ant, but if you use a separately-installed copy
  52        please make sure that it is at least version 1.8.1.
  53 
  54 Configuring
  55     Building OpenJDK is hard and complex. No, strike that. While it's not
  56     exactly "easy", we've got it down to *relatively* small set of
  57     properties you need to set.
  58 
  59     The NetBeans projects provided here share a fair amount of common
  60     structure. They share properties values where it makes sense. Each
  61     project loads properties from these properties files, in this order
  62 
  63         ${basedir}/nbproject/private/build.properties
  64         $HOME/.openjdk/${ant.project.name}-build.properties
  65         $HOME/.openjdk/build.properties
  66         ${basedir}/build.properties
  67 
  68     (${basedir} refers to the directory containing a particular NetBeans
  69     project.) The first time a property defined determines value: it is
  70     *not* overridden if it is read from properties files read later. The net
  71     result is that by carefully choosing where to define a property, you can
  72     have it for a specific project, all uses of a specific project (useful
  73     if you work on multiple copies of the OpenJDK sources), all projects, or
  74     only projects in a specific sandbox.
  75 
  76     With that in mind, please set the following properties. Presuming you
  77     want the same values for all your work, set them in
  78     $HOME/.openjdk/build.properties.
  79 
  80     * bootstrap.jdk
  81         Set to the location where you installed JDK 7.
  82 
  83     * jtreg.home
  84         Set to the location where you installed jtreg.
  85 
  86     * make.options
  87         Some of the projects invoke "make", since they compile native code.
  88         The make.options property is for passing information about what you
  89         installed where to make.  Change the paths to fit your particular
  90         situation:
  91 
  92         make.options=\
  93             ALT_BOOTDIR=/home/me/bin/jdk1.7.0 \
  94             ALT_JDK_IMPORT_PATH=/home/me/bin/jdk1.8.0 \
  95             OPENJDK=true
  96 
  97         The trailing '\' are important, so that make gets the above as a
  98         single set of options.
  99 
 100         You might want to add additional additional options: see the README
 101         for the project you're using for more information.  And see
 102                  *install-dir*/jdk/make/README-builds.html
 103         to read much more about building the JDK.
 104 
 105   Windows-specific configuration
 106     First, please note that the entire JDK cannot currently be built on
 107     Windows platforms.  This will likely limit your ability to build
 108     make-based projects.  See
 109          *install-dir*/jdk/make/README-builds.html
 110     for full information on issues with building on the Windows platform.
 111 
 112     That said, there are two ways to work with the Windows-required settings
 113     for the Microsoft tools. Either:
 114 
 115     * Set environment variables values in Windows
 116         Doing so means accessing the System control panel in Windows, and
 117         setting the environment variables there.
 118 
 119         By doing so, you can launch NetBeans by double-clicking its icon,
 120         and the environment variable values will be available.
 121 
 122     * Set environment variable values in a shell
 123         Doing so means adding the settings to an init file (e.g. .bashrc,
 124         .cshrc, etc.) or a file that you source before running NetBeans. In
 125         this case, you'll have to launch NetBeans from the command line in a
 126         shell in which you've set the environment variables.
 127 
 128     In either case, the end result should be that the settings are available
 129     to the make-based build process when it runs from within NetBeans.
 130 
 131     The make-based builds presumes that you're using cygwin, and expects to
 132     find "make" in c:\cygwin\bin\make. If you've installed cygwin elsewhere,
 133     set "make" in a properties file.
 134 
 135   Configuring Project Properties
 136     A note of caution is in order: These are NetBeans *freeform* projects.
 137     If you use the NetBeans GUI to examine them, things are likely to not
 138     look "right". Please don't edit them there, please instead use a text
 139     editor.
 140 
 141   Locale Requirements
 142     To build the OpenJDK sources, be certain that you are using the "C"
 143     locale on Unix (R) platforms, or "English (United States)" locale on
 144     Windows.
 145 
 146 Platforms and architectures, oh my!
 147     The Open JDK can be built for a variety of operating system platforms
 148     and hardware architectures. The resulting builds are always placed in a
 149     directory which contains the platform and architecture as part of the
 150     pathname, as in *platform*-*arch*. For example, if you build the jdk
 151     project on a Linux platform running on x86 hardware, the resulting build
 152     will be in:
 153 
 154     *install-dir*/jdk/build/linux-i586
 155 
 156     We've provided support for some platforms and architectures in
 157     common/architectures. Add another, if your needs require it.
 158 
 159 Provided NetBeans projects
 160     This section describes the NetBeans projects that help you work on
 161     particular parts of the JDK. While they're largely similar in structure
 162     and should work the way you expect NetBeans projects to work: edit,
 163     build, test, etc. But there are some differences. They don't all support
 164     the same targets (e.g., there's nothing to run in jarzip project).
 165 
 166     Some projects are built by invoking make, since they involve compilation
 167     of native code or other activities that cannot be done by javac. We call
 168     these "make-based", and call all others "ant-based".
 169 
 170     They all are configured by way of a build.properties file, which
 171     specifies what subdirectories of the JDK sources they manipulate, what
 172     directories contain their tests, whether they use make or ant, etc.
 173 
 174     The very first time you open any one of these projects on set of Open
 175     JDK sources, NetBeans will scan the entire set of sources, not just
 176     those for the project you opened. This will take a few minutes, but will
 177     ensure that Go To Type, Go To Source, and so on work as expected. Later,
 178     when you open other projects on the same Open JDK sources, there will be
 179     at most a slight delay.
 180 
 181     There's a README accompanying each project. Most are text files, which
 182     you can Open in NetBeans, some are HTML files, in which case unless you
 183     enjoy reading raw HTML, you're better off choosing the *View* menu item
 184     from the context menu, which will display the README in your web
 185     browser.
 186 
 187     Finally, note that these projects were all created by different people,
 188     and are while some attempt has been made to make them look and behave
 189     the same, they are maintained separately and will vary somewhat.
 190 
 191     The projects currently provided are:
 192 
 193     jdk (directory "jdk")
 194         A convenient starting point for the other projects, and from which
 195         you can build the entire OpenJDK. Please note that depending on your
 196         hardware, this could take a *very* long time. The results of the
 197         build are in *install-dir*/jdk/build/*platform*-*arch*.
 198 
 199     world (directory "world")
 200         This project builds both the Hotspot VM and all of JavaSE. Please
 201         note that pretty much regardless of your hardware, this *will* take
 202         a long time, and use *lots* of disk space (more than 3GB). The
 203         results of the build are in
 204         *install-dir*/build/*platform*-*arch* and
 205         *install-dir*/build/*platform*-*arch*-fastdebug.
 206 
 207         Consult the project's README file for details.
 208 
 209     AWT & Java2d (directory "awt2d")
 210         For working on AWT and Java2d. Supports running the Font2DTest demo.
 211 
 212         This is a make-based project: In order to build this project, you
 213         should build the jdk project first, since AWT and Java2d include
 214         native code.
 215 
 216     JConsole (directory "jconsole")
 217         For working on JConsole. Creates ../dist/lib/jconsole.jar. Supports
 218         running and debugging JConsole.
 219 
 220         This ant-based project does *not* require that you build the jdk
 221         project first, provided that you use a pre-built version of JDK 7.
 222 
 223     Java (TM) Management Extensions (JMX(TM)) API (directory "jmx")
 224         For working on JMX source code. Creates ../dist/lib/jmx.jar.
 225 
 226         This ant-based project does *not* require that you build the jdk
 227         project first, provided that you use a pre-built version of JDK 7.
 228 
 229     Jar & Zip (directory "jarzip")
 230         For working on jar & zip. It builds the zip library (including
 231         native code), the jar library, and the jar tool. Creates an
 232         executable jar program in ../build/*platform*-*arch*/bin/jar.
 233 
 234         This is a make-based project: In order to build this project, you
 235         should build the jdk project first, since AWT and Java2d include
 236         native code.
 237 
 238     Swing (directory "swing")
 239         For working on Swing. Creates ../dist/lib/swing.jar. Supports
 240         running and debugging the SampleTree demo.
 241 
 242         This ant-based project does *not* require that you build the jdk
 243         project first, provided that you use a pre-built version of JDK 7.
 244 
 245     In addition, there are projects for building the compiler, javadoc,
 246     and related tools, in the OpenJDK langtools component.  These
 247     projects are separate from those described here, and have their
 248     own set of guidelines and conventions. For more details, see the
 249     README files in make/netbeans in the OpenJDK langtools component.
 250 
 251 Running Tests
 252     We use the jtreg test harness, described more fully at
 253     http://openjdk.java.net/jtreg
 254 
 255     The OpenJDK tests are in the default Java package, are public classes,
 256     and have a "static void main(String[] args)" with which they are
 257     invoked. Some tests are actually shell scripts, which might compile
 258     code, etc. jtreg is quite flexible.
 259 
 260     To run tests for a project, use *Test Project* from NetBeans. From the
 261     command line, you can invoke "ant jtreg" on any individual project's
 262     build.xml file.
 263 
 264     In either NetBeans of on the command line, jtreg prints summary output
 265     about the pass/fail nature of each test. An HTML report of the entire
 266     test run is
 267 
 268     ../build/*platform*-*arch*/jtreg/*ant-project-name*/JTreport/report.html
 269 
 270     In that same JTreport directory are also individual HTML files
 271     summarizing the test environment, test passes and failures, etc.
 272 
 273     More detail on any individual test is under
 274 
 275     ../build/*platform*-*arch*/jtreg/*ant-project-name*/JTwork.
 276 
 277     For example, details about the awt/Modal/SupportedTest/SupportedTest
 278     test are under the JTwork directory at the same pathname as the test
 279     itself in a ".jtr" file. For example:
 280 
 281     ../build/*platform*-*arch*/jtreg/*ant-project-name*/JTwork/awt/Modal/SupportedTest/SupportedTest.jtr
 282 
 283     Sometimes you will see that running jtreg has resulted in a failure.
 284     This does not always mean that a test has an error in it. Jtreg
 285     distinguishes between these two cases. There are a number of tests that
 286     are "ignored", and not run, and these are reported as failures.
 287 
 288     You can run a single test by right clicking on it and choosing *Run
 289     File* from the context menu. Similarly, you can debug a single test by
 290     choosing *Debug File*.
 291 
 292 Debugging
 293     Debugging is enabled by default in ant-based projects, as if
 294     "-g:lines,vars,source" were given. You can alter these settings via
 295     entries in one of the configuration properties files. For example:
 296 
 297      javac.debug=false
 298      javac.debuglevel=<debug level options>
 299 
 300     To debug a project or test, use NetBeans in the normal way, with *Debug
 301     Project* or *Debug File*. Note that not all projects provide a target
 302     that can be debugged, but tests can be debugged.
 303 
 304 Creating Javadoc
 305     You can create Javadoc for any of the projects: just choose *Generate
 306     Javadoc for Project* from the NetBeans menu. Your default browser will
 307     open up, displaying the just-generated javadoc.
 308 
 309     Javadoc gets generated into a separate subdirectory for each project.
 310     For example, the Jar & Zip project's javadoc gets generated in
 311 
 312     ../build/*platform*-*arch*/jtreg/*ant-project-name*/javadoc/jarzip
 313 
 314 Cleaning projects
 315     Each project can of course be cleaned. Make-based and ant-based projects
 316     differ a little in what exactly gets cleaned. In both cases, all jtreg
 317     results and javadoc are removed.
 318 
 319     In ant-based projects, project-specific files as determined by the
 320     project's build.properties file are removed from the classes and gensrc
 321     directories that are under ../build/*platform*-*arch*.
 322 
 323     In make-based projects, "make clean" is run in the same directories as
 324     "make all" is run when building the project.
 325 
 326     Please note that the jdk project is "special" with respect to
 327     cleaning: in this case, the entire ../build directory is removed.
 328     Similar for the world project.
 329 
 330 Creating your own NetBeans project
 331     The project's we've provided are hopefully a useful starting point, but
 332     chances are that you want to work on something else. This section will
 333     describe how to select an existing project, and then adapt it to your
 334     needs.
 335 
 336   Considerations
 337     The first consideration is whether or not the code in which you're
 338     interested needs anything beyond javac and copying of resources to
 339     build. If so, then you'll need to create a make-based project. If not,
 340     an ant-based project is possible. See the project descriptions above to
 341     learn which are make-based, and which are ant-based.
 342 
 343     The second consideration is to consider the files that you'll need. Each
 344     project is defined by 3 files:
 345 
 346     * build.xml
 347         This is the ant build script. For a make-based project, they tend to
 348         have a target for "make clean" and another for "make all", each of
 349         which invokes "make-run" in the same set of directories. Take a look
 350         at jarzip/build.xml for an example.
 351 
 352         For an ant-based project, there might be nothing, with all the work
 353         done via the declaration of properties in the build.properties file.
 354         Take a look at jconsole/build.xml for an example, and notice how it
 355         overrides the -pre-compile and -post-compile targets that are
 356         defined in common/shared.xml (where they are defined to do nothing).
 357 
 358     * build.properties
 359         This file defines the directories (and possibly files) that are
 360         included in and excluded from. Basically, a file is considered to be
 361         in a project if it is mentioned in the includes list, or is
 362         contained under a directory mentioned in that list, *unless* it is
 363         explicitly excluded or is contained under a directory that is
 364         excluded. Take a look awt2d/build.properties for an example.
 365 
 366     * nbproject/project.xml
 367         This file defines a project for NetBeans for a "freeform" project.
 368         Each declares several entity references, which are used later in the
 369         project. For an example, see javadoc/nbproject/project.xml, which is
 370         an ant-based project. Compare that with
 371         jarzip/nbproject/project.xml, which is make-based. Not much
 372         difference! That's because while the jarzip project is make-based,
 373         it does not have any platform-specifc native code. Contrast that
 374         with awt2d/nbproject/project.xml, which does have native code;
 375         notice that it uses platform-specific entity references.
 376 
 377     In summary, we recommend exploring the given projects, and choosing one
 378     that most closely suits our needs.
 379 
 380   Example: A project for working on collections
 381     Let's create a project to work with on the collections classes. There's no native
 382     code here, so an ant-based project will do. Therefore, the jconsole
 383     project is a reasonable project to use as a starting point.
 384 
 385    Clone the existing project
 386     Make a directory for the collections project next to the existing projects:
 387 
 388         % mkdir -p collections/nbproject
 389 
 390     Copy files from the jconsole project:
 391 
 392         % cp jconsole/build.properties collections
 393         % cp jconsole/build.xml collections
 394         % cp jconsole/nbproject/project.xml collections/nbproject
 395 
 396    Change the set of files included in the project
 397     The collections sources are all under one directory, and we want to include
 398     them all. The same is true of the tests. So edit
 399     collections/build.properties so that it contains these lines:
 400 
 401         includes=\
 402             java/util/
 403         excludes=\
 404             java/util/Calendar.java,\
 405             java/util/jar/,\
 406             java/util/logging/,\
 407             java/util/prefs/,\
 408             java/util/regex/,\
 409             java/util/spi/,\
 410             java/util/zip/,\
 411             **/*-XLocales.java.template
 412         jtreg.tests=\
 413             java/util/**/*Collection/ \
 414             java/util/**/*Map/ \
 415             java/util/**/*Set/ \
 416             java/util/**/*List/
 417 
 418     Notice the trailing "/" in some of those pathnames: that tells NetBeans to
 419     treat the path as a directory and include (or exclude) everything beneath
 420     it in the hierarchy.  Note also how we include java/util, but then exclude
 421     several directories under that which are not related to collections.
 422 
 423     The build.xml for collections is about as simple as can be. First, change the
 424     name of the project:
 425 
 426         <project name="collections" default="build" basedir=".">
 427 
 428     Then remove the -pre-compile target from the build.xml.  Change the
 429     -post-compile target to create collections.jar without any manifest, and
 430     to only contain the collections-related classes.  The jar task now looks
 431     like this:
 432 
 433         <jar destfile="${dist.dir}/lib/collections.jar">
 434             <fileset dir="${classes.dir}">
 435                 <include name="java/util/*.class"/>
 436                 <exclude name="java/util/Calendar*.class"/>
 437             </fileset>
 438         </jar>
 439 
 440     Also, change the clean target to remove collections.jar instead of
 441     jconsole.jar.
 442 
 443     Now edit project.xml file. NetBeans uses an internal name and a
 444     user-visible name, both of which should be changed:
 445 
 446         <name>Collections</name> <!-- Customized -->
 447 
 448         <property name="name">collections</property> <!-- Customized -->
 449 
 450     Inside of <ide-actions>, you'll see actions defined for "run" and
 451     "debug". The Open JDK sources don't include any interesting Collections
 452     demos, but leave these here for now: Chances are you'll find or create
 453     some collections app of your own, and want to run and or debug it.
 454 
 455     Now, open the Collections project in NetBeans. You'll find that it operates
 456     just like all the other projects.
 457 
 458     If/when you want to have this project run a collections demo, change the run
 459     target in collections/build.xml to invoke it in whatever manner is appropriate
 460     for the app. From NetBeans, you should be able to run and debug the app,
 461     including setting breakpoints in collections code.
 462 
 463 Appendix 1: Customizations
 464     There are several ways to customize NetBeans projects. These projects
 465     share a common structure, based on common/shared.xml and
 466     common/make.xml. Because of that sharing, some mechanisms described
 467     below apply to most any project.
 468 
 469     Several properties can be user-defined (and several should not be
 470     user-defined!). There are different properties files read. Some default
 471     targets can be overridden.
 472 
 473   Property files
 474     When projects are started, and when when ant runs (whether from NetBeans
 475     or the command line), these properties files are loaded in the order
 476     shown:
 477 
 478         ${basedir}/nbproject/private/build.properties
 479         $HOME/.openjdk/${ant.project.name}-build.properties
 480         $HOME/.openjdk/build.properties
 481         ${basedir}/build.properties
 482 
 483     Recall that with ant, once a property is defined, its value cannot be
 484     changed, so it's "first one wins".
 485 
 486     To set or change a property for all your projects, put the change into
 487     $HOME/.openjdk/build.properties. This will affect all projects,
 488     regardless of how many copies of the Open JDK sources you have
 489     installed.
 490 
 491     Let's say you have 2 copies of the Open JDK sources installed on your
 492     machine. To set or change a property for only the jconsole projects, but
 493     for both of them, make the change in
 494     $HOME/.openjdk/${ant.project.name}-build.properties. If you wanted to
 495     make the change for only one of them, do it in that project's
 496     ${basedir}/build.properties or
 497     ${basedir}/nbproject/private/build.properties.
 498 
 499     Note that the ${basedir}/build.properties file is provided as part of
 500     the Open JDK sources. If you want to make a change for a particular
 501     project, you can do so there. To be sure that you don't ever
 502     accidentally check it in to the Open JDK sources, you might prefer to
 503     change it in ${basedir}/nbproject/private/build.properties.
 504 
 505   User-definable Properties
 506     You can provide your own definitions for the properties listed below. We
 507     don't recommend overriding the definitions of other properties.
 508 
 509     The following two properties should be set before you try to use the
 510     projects with NetBeans or ant:
 511 
 512     * bootstrap.jdk
 513         Default: None. Please set this, normally in
 514         $HOME/.openjdk/build.properties.
 515 
 516     * jtreg.home
 517         Default: None. Please set this, normally in
 518         $HOME/.openjdk/build.properties.
 519 
 520     These options are for configuring the behavior of make:
 521 
 522     * use.make
 523         Default: Not set. Set this, normally in ${basedir}/build.properties,
 524         for a project which is make-based.
 525 
 526     * make
 527         Default: The right make for the platform, at the normal location, set
 528         in *install-dir*/jdk/make/netbeans/common/make.xml
 529 
 530     * make.options
 531         Default: Empty string. Set this to any options you want to pass to
 532         make, normally in ${basedir}/build.properties.
 533 
 534     The remaining options are for use at your discretion:
 535 
 536     * javac.options
 537         Default: -Xlint
 538 
 539     * javac.debug
 540         Default: true
 541 
 542     * javac.debuglevel
 543         Default: lines,vars,source
 544 
 545     * javadoc.options
 546         Default: Empty string.  Some projects will need to set this to
 547         increase the heap for running javadoc.  For example, see the jconsole
 548         project.
 549 
 550     * javadoc.packagenames
 551         Default: "none".  Set this only if your project has packages that
 552         should be javadoc'd which are outside of those listed in the javadoc
 553         target's packageset.  See the jconsole project for an example.
 554 
 555     * jtreg.tests
 556         Default: None. Set this to a list of tests and/or directories
 557         containing regression tests, normally in
 558         ${basedir}/build.properties.
 559 
 560     * jtreg.options
 561         Default: Empty string. See http://openjdk.java.net/jtreg
 562 
 563     * jtreg.vm.options
 564         Default: Empty string. See http://openjdk.java.net/jtreg
 565 
 566     * jtreg.samevm
 567         Default: false. See http://openjdk.java.net/jtreg
 568 
 569   User-overridable Targets
 570     The following targets are provided for your convenience in customizing
 571     various standard actions of the build process. The default action for
 572     each one is to do nothing.
 573 
 574     These come in pairs, allowing your scripts to take some action before or
 575     after a standard action.
 576 
 577     * -pre-init
 578         Runs before any other initialization has been done.
 579 
 580     * -post-init
 581         Runs before after all other initialization has been done.
 582 
 583     * -pre-compile
 584         Runs before compilation, whether via ant or make. Note that in the
 585         case of make, it is before the -build-make target has run, not after
 586         each individual make-run has run.
 587 
 588     * -post-compile
 589         Runs after compilation, whether via ant or make.
 590 
 591     * -pre-jtreg
 592         Runs before regression tests are run.
 593 
 594     * -post-jtreg
 595         Runs before after regression tests are run.
 596 
 597     In a make-based project, you should override these targets to do the
 598     build and clean actions required of your project.
 599 
 600     * -build-make
 601     * -clean-make
 602 
 603 Known Issues
 604 
 605   Can't run nor debug a single test in the JConsole test
 606     In most projects, you can run a single test by opening it in the editor,
 607     and choosing Run File from the context menu.  If you try this with the a
 608     JConsole test, instead you'll see that *all* tests from *all* projects
 609     are run.  The workaround is to not try to run a single JConsole test.
 610     Debugging is similarly problematic (both running and debugging use the
 611     same underlying infrastructure).
 612 
 613     If you do Run File a JConsole tests, you can always stop them by pressing
 614     the stop button in the NetBeans output window.  But you'll be surprised to
 615     learn that they are actually still running in the background.  The only
 616     way out of this situation is to exit NetBeans.  A few more tests will run,
 617     but after restarting NetBeans things will be OK.
 618 
 619 Attribution
 620     UNIX is a registered trademark in the United States and other countries,
 621     exclusively licensed through X/Open Company, Ltd.
 622