JVM Projects with Pants
Assuming you know the basic Pants concepts and have gone through the first Tutorial, you've made a great start towards using Pants to work with Java and Scala code. This page goes into some of the details.
If you are accustomed to the Maven tool and contemplating moving to Pants, you are not alone; Pants for Maven Experts has some advice.
Relevant Goals and Targets
When working with JVM languages, the following goals and targets are especially relevant.
Deployable Bundle Runnable Binary, optionally with non-JVM files
Deployable bundles are directories, optionally archived, that contain all files necessary to run the application. The
bundle
goal is used to create these deployable bundles from eitherjvm_binary
orjvm_app
targets.Bundling a
jvm_binary
target is appropriate when your application is entirely jar-based; that is, it's entirely class files and resources packaged inside the jars themselves. If your application requires "extra stuff" (e.g.: start scripts, config files) use ajvm_app
which allows you to include files in the bundle directory that supplement the binary jar and its dependencies. You can learn more about bundles.
Runnable Binary
On its own, a
jvm_binary
BUILD target describes an executable.jar
(something you can run withjava -jar
). The jar is described as executable because it contains a manifest file that specifies the main class as well as classpath for all dependencies. If your program contains only jars (and resources packaged in those jars), this is all you need to run the binary. Use./pants binary
to compile its code;./pants run
to run it "in place".
Importable Code
java_library
BUILD targets make Java source codeimport
-able. The rule of thumb is that each directory of.java
files has aBUILD
file with ajava_library
target. A JVM target that has ajava_library
in itsdependencies
can import its code.scala_library
targets are similar, but compiled with Scala.To use pre-built
.jar
s, a JVM target can depend on ajar
, a reference to published code; thesejar
s normally live in a directory called 3rdparty.Pants can
publish
a JVM library so code in other repos can use it; if the*_library
target has aprovides
parameter, that specifies the repo/address at which to publish.An
annotation_processor
BUILD target defines a Java library one containing one or more annotation processors.
Tests
A
junit_tests
BUILD target holds source code for some JUnit tests; typically, it would have one or morejava_library
targets as dependencies and would import and test their code.Pants also includes support for using the ScalaTest framework. The testing framework automatically picks up scala tests that extend the org.scalatest.Suite class and runs them using org.scalatest.junit.JUnitRunner.
Most other scala test frameworks support running with JUnit via a base class/trait or via a
@RunWith
annotation; so you can usejunit_tests
for your scala tests as well.The Pants
test
goal runs tests.
Generated Code
A
java_thrift_library
generates Java code from.thrift
source; a JVM target that has this target in itsdependencies
canimport
the generated Java code. Ajava_protobuf_library
is similar, but generates Java code from protobuffer source. Ajaxb_library
definition generates code to read and write XML using an XML schema (.xsd files).
BUILD for a Simple Binary
The Pants Build Java hello world
sample
code shows the BUILD file for a simple Java binary (in the main/
directory):
jvm_binary(name = 'main-bin', dependencies = [ 'examples/src/java/org/pantsbuild/example/hello/greet', 'examples/src/resources/org/pantsbuild/example/hello', ], source = 'HelloMain.java', main = 'org.pantsbuild.example.hello.main.HelloMain', basename = 'hello-example', )
This small program has just one dependency. It is a library, a java_library
, a compiled set of
source code from this workspace.
Depending on a Library
The rule of thumb is that each directory of .java
or .scala
files
has a library target. If you find yourself thinking "we should move some
of this code to another directory," you probably also want to set up a
BUILD
file with a java_library
(or scala_library
) target. Here we
see the library target which main-bin
depends on. This library target
lives in hello/greet/BUILD
:
# Note that the target has no explicit name, so it defaults to the name # of the directory, in this case 'greet'. # It also has no explicit sources, so it defaults to the sources implied # by the target type, in this case "globs('*.java')". java_library( dependencies = [], # A more realistic example would depend on other libs, # but this "hello world" is pretty simple. provides = artifact(org='org.pantsbuild.example', name='hello-greet', repo=public,), )
This library could depend on other build targets and artifacts; if your
code imports something, that implies a BUILD
dependency.
A Test Target
The Pants Java Hello World example tests are normal JUnit tests. To run them with Pants, we need a target for them:
junit_tests( dependencies=[ 'examples/src/java/org/pantsbuild/example/hello/greet', 'examples/src/resources/org/pantsbuild/example/hello', ], )
As with other targets, this one depends on code that it imports. Thus, a typical test target
depends the library that it tests and perhaps some others (here, junit
).
The dependency on junit
is a "third party" dependency, a pre-compiled artifact whose source
lives somewhere outside the workspace.
Depending on a Jar
The test example depends on a jar, junit
. Instead of compiling from
source, Pants invokes the resolver to fetch such jars. To reduce the danger of
version conflicts, we use the 3rdparty idiom: we keep references to
these "third-party" jars together in BUILD
files under the 3rdparty/
directory. Thus, the test has a 3rdparty
dependency:
junit_tests( dependencies=[ 'examples/src/java/org/pantsbuild/example/hello/greet', 'examples/src/resources/org/pantsbuild/example/hello', ], )
The BUILD
files in 3rdparty/
have targets like:
jar_library(name='junit', jars = [ jar(org='junit', name='junit-dep', rev='4.11').with_sources(), ], dependencies = [ ':hamcrest-core', ], )
Those jar()
things are references to public jars.
You can read more about
JVM 3rdparty dependencies.
The Usual Commands: JVM
Make sure code compiles and tests pass:
Use the test
goal with the targets you're interested in. If they are test targets,
Pants runs the tests. If they aren't test targets, Pants still compiles them since it knows it
must compile before it can test.
$ ./pants test examples/src/java/org/pantsbuild/example/hello/:: examples/tests/java/org/pantsbuild/example/hello/::
Assuming you use junit_test
targets, output from the junit
run is written to
.pants.d/test/junit/
; you can see it on the console with --output-mode=ALL
:
$ ./pants test.junit --output-mode=ALL examples/tests/java/org/pantsbuild/example/hello::
Run just that one troublesome test class: (assuming a JUnit test; other frameworks use other flags)
$ ./pants test.junit --test=org.pantsbuild.example.hello.greet.GreetingTest examples/tests/java/org/pantsbuild/example/hello/::
Packaging Binaries
To create a bundle (a binary and its dependencies, perhaps including helper files):
$ ./pants bundle --bundle-jvm-archive=zip examples/src/java/org/pantsbuild/example/hello/main ...lots of build output... 08:50:54 00:02 [create-monolithic-jar] 08:50:54 00:02 [add-internal-classes] 08:50:54 00:02 [jar-tool] created dist/hello-example.zip 08:50:54 00:02 [dup] 08:50:54 00:02 [apk] 08:50:54 00:02 [apk-bundle] SUCCESS $
This generates a zipfile with runnable contents; instead of a zipfile, we could have put the contents a directory tree, a giant jar, or something else. Learn more about bundles.
Toolchain
Ivy
Pants uses Ivy to resolve jar
dependencies. To change how Pants
resolves these, configure resolve.ivy
.
Coursier
Starting at release 1.4.0.dev26
, Pants added an option to pick coursier
as the JVM 3rdparty resolver, with performance improvement being the main motivation. The goal is to retire ivy
eventually.
Limitation
- Currently coursier only supports maven style repo resolves. Resolving with ivy settings is still not mature.
- Coursier does not do publishing.
Example config to use coursier
For Pants >= 1.7.x
# This will turn on coursier and turn off ivy. [resolver] resolver: coursier [resolve.coursier] # jvm option in case of large resolves jvm_options: ['-Xmx4g', '-XX:MaxMetaspaceSize=256m'] [export] # Same if needed for large resolves jvm_options: ['-Xmx4g', '-XX:MaxMetaspaceSize=256m'] [coursier] repos: ['https://repo1.maven.org/maven2', 'https://dl.google.com/dl/android/maven2/'] # Change the following if you choose to [build coursier jar from scratch](https://github.com/coursier/coursier/blob/master/DEVELOPMENT.md#build-with-pants) # or to fetch from different location. bootstrap_jar_url: <url> version: <version>
- To inspect the resolve result, specify
--resolver-coursier-report
-
To show coursier command line invocation, use
-ldebug
./pants --resolver-resolver=coursier resolve.coursier --report examples/tests/scala/org/pantsbuild/example/hello/welcome -ldebug
For Pants <= 1.6.x
# This will turn on coursier and turn off ivy. [resolver] resolver: coursier [export] # Same if needed for large resolves jvm_options: ['-Xmx4g', '-XX:MaxMetaspaceSize=256m'] [coursier] # Change the following if you choose to [build coursier jar from scratch](https://github.com/coursier/coursier/blob/master/DEVELOPMENT.md#build-with-pants) # or to fetch from different location. bootstrap_jar_url: <url> version: <version> fetch_options: [ # Specify maven repos '-r', 'https://repo1.maven.org/maven2/', '-r', 'https://dl.google.com/dl/android/maven2/', # Quiet mode '-q', # Do not use default public maven repo. '--no-default', # Concurrent workers '-n', '10', # Specify the type of artifacts to fetch '-A', 'jar,bundle,test-jar,maven-plugin,src,doc,aar' ]
Nailgun
Pants uses Nailgun to speed up compiles. Nailgun is a JVM daemon that runs in the background. This means you don't need to start up a JVM and load classes for each JVM-based operation. Things go faster.
Zinc
Pants uses Zinc, a dependency tracking compiler facade that supports sub-target incremental compilation for Java and Scala.
Java9 vs Java8, Which Java
Pants first looks through any JDKs specified by the paths
map in pants.ini's jvm-distributions
section, eg:
[jvm-distributions] paths = { 'macos': [ '/Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk', '/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk', ], 'linux': [ '/usr/java/jdk1.8.0_152', ] }
If no JVMs are found there, Pants uses the first Java it finds in JDK_HOME
, JAVA_HOME
,
or PATH
. If no paths
are specified in pants.ini, you can use JDK_HOME to set the Java version
for just one pants invocation:
$ JDK_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64 ./pants ...
If you sometimes need to compile some code in Java 8 and sometimes Java 9, you can define jvm-platforms in pants.ini, and set what targets use which platforms. For example, in pants.ini:
[jvm-platform] default_platform: java8 platforms: { 'java7': {'source': '7', 'target': '7', 'args': [] }, 'java8': {'source': '8', 'target': '8', 'args': [] }, java9': {'source': '9', 'target': '9', 'args': [] }, }
And then in a BUILD file:
java_library(name='my-library', sources=globs('*.java'), platform='java8', )
You can also override these on the cli:
./pants compile --jvm-platform-default-platform=java9 examples/src/java/org/pantsbuild/example/hello/main
If you want to set the -bootclasspath
(or -Xbootclasspath
) to use the
appropriate java distribution, you can use the $JAVA_HOME
symbol in the
args
list. For example:
[jvm-platform] default_platform: java8 platforms: { 'java7': {'source': '7', 'target': '7', 'args': ["-C-bootclasspath:$JAVA_HOME/jre/lib/resources.jar:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/jre/lib/sunrsasign.jar:$JAVA_HOME/jre/lib/jsse.jar:$JAVA_HOME/jre/lib/jce.jar:$JAVA_HOME/jre/lib/charsets.jar:$JAVA_HOME/jre/lib/jfr.jar:$JAVA_HOME/jre/classes"] }, }
Your -bootclasspath
should be designed to work with any compatible version of
the JVM that might be used. If you make use of [jvm-distributions]
and have
strict control over what jvm installations are used by developers, this means you
probably only have to make it work for one version of the JDK. Otherwise, you
should design your bootclasspath to reference the union of all possible jars
you might need to pull in from different JVMs (any paths that aren't available
will simply be ignored by java).
Note: Currently, pants is known to work with OpenJDK and Oracle JDK version 7 or greater.
Bundles: Deploy-able Runnable File Trees
You can enjoy your web service on your development machine's
localhost
, but to let other people enjoy it, you probably want to copy
it to a server machine. With Pants, the easiest way to do this is to
create a bundle: a directory tree of .jar
and helper files.
Our "hello world" sample application needs a configuration file to run
correctly. (You can try to run without the configuration file, but the
program crashes immediately.) We define a jvm_app
that represents a
runnable binary and "bundles" of extra files:
# Note that the target has no explicit name, so it defaults to the name # of the directory, in this case 'main'. jvm_app( basename = 'hello-example', dependencies = [ ':main-bin' ], bundles = [ bundle(relative_to='config', fileset=globs('config/*')) ] )
Here, we keep the extra files in a subdirectory, config/
so that they
don't clutter up this directory. (In this simple example, there's just
one file, so there isn't actually much clutter.) By using the
bundle
's
relative_to
parameter, we "strip off" that
subdirectory; in the generated bundle, these extra files will be in the
top directory.
(If you want to set up a tree of static files but don't need it to be
runnable, you can define a jvm_app
target with bundles (and/or
resources) but whose jvm_binary
has no source or main; the resulting
bundle will have the files you want (along with a couple of
not-so-useful stub .jar
files).)
Generating a Bundle
Invoke ./pants bundle
on a JVM app or JVM binary target:
$ ./pants bundle examples/src/java/org/pantsbuild/example/hello/main:main
With options, you can tell Pants to archive the bundle in a zip, a tar, and some other common formats. See the bundle help for built-in choices.
Contents of a Bundle
The generated bundle is basically a directory tree containing .jar
s
and extra files. The .jar
in the top-level directory has a manifest so
you can run it with java -jar
:
$ cd dist/hello-example-bundle/ $ java -jar hello-example.jar 16:52:11 INFO : Hello, world!
The "bundle" is basically a tree of files:
$ cd dist/hello-example-bundle/ $ find . . ./greetee.txt ./hello-example.jar ./libs $ jar -tf hello-example.jar META-INF/ META-INF/MANIFEST.MF com/ org/pantsbuild/ org/pantsbuild/example/ org/pantsbuild/example/hello/ org/pantsbuild/example/hello/main/ org/pantsbuild/example/hello/main/HelloMain.class org/pantsbuild/example/ org/pantsbuild/example/hello/ org/pantsbuild/example/hello/world.txt org/pantsbuild/example/hello/greet/ org/pantsbuild/example/hello/greet/Greeting.class
That greetee.txt
file came from the bundles=
parameter.
The libs/
directory contains 3rdparty jars (if any). The jar
in the top directory
contains code compiled for this target.
Deploying a Bundle
Instead of just creating a directory tree, you can specify bundle --bundle-jvm-archive=zip
to
./pants bundle
to generate an archive file (a .zip
, monolithic .jar
, or some other
format) instead.
To use such an archive, put it where you want it, unpack it, and run:
$ ./pants bundle --bundle-jvm-archive=zip examples/src/java/org/pantsbuild/example/hello/main ...lots of build output... 10:14:26 00:01 [create-monolithic-jar] 10:14:26 00:01 [add-internal-classes] 10:14:26 00:01 [jar-tool] created dist/hello-example.zip 10:14:26 00:01 [dup] 10:14:26 00:01 [apk] 10:14:26 00:01 [apk-bundle] SUCCESS $ # let's use it: $ mkdir tmp; cd tmp $ unzip ../dist/hello-example.zip Archive: ../dist/hello-example.zip inflating: greetee.txt inflating: hello-example.jar $ java -jar hello-example.jar Hello, Bundled-File World! Hello, Resource World! $
Omitting or Shading the Contents of a Binary
Omitting
Sometimes you want to leave some files out of your binary.
You can omit jars from the binary by means of the jvm_binary
's deploy_excludes
parameter.
For example, if you're making a binary to run on Hadoop and there are some "standard jars"
already on the destination machines, you can list those in deploy_excludes
.
More generally, you can omit files from the binary jar with deploy_jar_rules
. For example, a
3rdparty dependency might have a transitive dependency with a bad manifest file. If you try to run
the jar you might get Invalid signature file digest for Manifest main attributes
. If you don't
actually use the code in that transitive dependency, you might work around the error by omitting
the dependency.
To tell Pants to omit some files from the binary, set the deploy_jar_rules
parameter of
jvm_binary
to a jar_rules
.
E.g., to omit all files containing the regexp Greeting
, you might set
deploy_jar_rules=jar_rules(rules=[Skip('Greeting')])
After building our hello
example, if we check the binary jar's contents, there is no
Greeting.class
(and running that jar crashes; we omitted a class this binary needs):
$ ./pants binary examples/src/java/org/pantsbuild/example/hello/main:main $ jar -tf dist/hello-example.jar META-INF/ META-INF/MANIFEST.MF com/ org/pantsbuild/ org/pantsbuild/example/ org/pantsbuild/example/hello/ org/pantsbuild/example/hello/main/ org/pantsbuild/example/hello/main/HelloMain.class org/pantsbuild/example/ org/pantsbuild/example/hello/ org/pantsbuild/example/hello/world.txt $
Shading
Sometimes you have dependencies that have conflicting package or class names. This typically occurs in the following scenario: Your jvm_binary depends on a 3rdparty library A (rev 1.0), and a 3rdparty library B (rev 1.3). It turns out that A happens to also depend on B, but it depends on B (rev 2.0), which is backwards-incompatible with rev 1.3. Now B (1.3) and B (2.0) define different versions of the same classes, with the same fully-qualified class names, and you're pulling them all onto the classpath for your project.
This is where shading comes in: you can rename the fully-qualified names of the classes that
conflict, typically by applying a prefix (eg, __shaded_by_pants__.org.foobar.example
).
Pants uses jarjar for shading, and allows shading rules to be specified on jvm_binary
targets with
the shading_rules
argument. The shading_rules
argument is a list of rules. Available rules
include: shading_relocate
,
shading_exclude
,
shading_relocate_package
, and
shading_exclude_package
.
The order of rules in the list matters, as typical of shading logic in general.
These rules are powerful enough to take advantage of jarjar's more advanced syntax, like using wildcards in the middle of package names. E.g., this syntax works:
# Destination pattern will be inferred to be # __shaded_by_pants__.com.@1.foo.bar.@2 shading_relocate('com.*.foo.bar.**')
Which can also be done by:
:::python shading_relocate_package('com.*.foo.bar')
The default shading prefix is __shaded_by_pants__
, but you can change it:
shading_relocate_package('com.foo.bar', shade_prefix='__my_prefix__.')
You can rename a specific class:
shading_relocate('com.example.foo.Main', 'org.example.bar.NotMain')
If you want to shade everything in a package except a particular file (or subpackage), you can use
the shading_exclude
rule.
shading_exclude('com.example.foobar.Main') # Omit the Main class. shading_exclude_package('com.example.foobar.api') # Omit the api subpackage. shading_relocate_package('com.example.foobar')
Again, order matters here: excludes have to appear first.
To see an example, take a look at testprojects/src/java/org/pantsbuild/testproject/shading/BUILD
,
and try running
./pants binary testprojects/src/java/org/pantsbuild/testproject/shading jar -tf dist/shading.jar
Target Scopes
Overview
Pants supports marking targets with one or more scope
values which the JVM backend will use to filter
dependency subgraphs at compiletime and runtime. Scopes are also used for unused dependency
detection: only default
scoped targets are eligible to be considered as "unused" deps.
Correspondence with other build systems
Scopes in pants are similar to scopes in other build systems, with the fundamental difference that they apply to targets (the "nodes" of the build graph), rather than to dependency "edges". The reason that Pants differs in this regard is that, in a monorepo, it is strongly encouraged to make changes to your dependency targets (which benefits all consumers) rather than to work around an issue in a dependency by making a local change to your target.
Scope values
Pants' built in scopes are:
default
: The "default" scope when a scope is not specified on a target.default
targets are included on classpaths at both compiletime and runtime, and are the only targets eligible for unused dep detection.compile
: Indicates that a target is only used at compiletime, and should not be included in runtime binaries or bundles. javac annotation processors or scalac macros are good examples of compiletime-only dependencies.runtime
: Indicates that a target is only used at runtime, and should not be presented to the compiler. Targets which are only used via JVM reflection are good examples of runtime-only dependencies.test
: Indicates that a target is used when running tests. This scope is typically used in addition to another scope (e.g.:scope='compile test'
). Targets which are are provided by an external execution environment are good examples of compile+test dependencies.forced
(available from pants 1.1.0): Theforced
scope is equivalent to thedefault
scope, but additionally indicates that a target is not eligible to be considered an "unused" dependency. It is sometimes necessary to mark a targetforced
due to false positives in the static analysis used for unused dependency detection; if possible, you should always prefer to mark a targetruntime
orcompile
if that more accurately describes their usage.
Setting target scopes
To set the scope of a target, you should generally prefer to pass the scope
parameter for
that target:
java_library(name='lib', .., scope='runtime', )
Multiple scopes can be specified. The equivalent of Maven's provided
scope can be expressed by
specifying both compile and test scopes.
java_library(name='lib', .., scope='compile test', )
If the scope of a target is not matched for a particular context, the entire subgraph represented
by the dependency will be pruned. This means that if a dependency 'B' of a target 'A' is marked
compile
(for example), the dependency targets of 'B' will only be included at compiletime (unless
'A' has other dependency paths to those targets).
One effect of this behavior is that you can introduce intermediate aliases to "re-scope" a target when consumers need to use it in multiple ways:
# An alias of `:lib` which consumers can use to indicate that they only need it at compile time. target(name='lib-compile', dependencies=[':lib'], scope='compile', ) java_library(name='lib', .., scope='default', )
Finally, for cases where only a few consumers need to "re-scope" a particular target, it is possible
to change the scope of a single edge locally to a consumer via the scoped
macro (which, under the
hood, uses the previous technique of creating an intermediate alias):
java_library(name='lib', dependencies=[ scoped('src/java/the/best/lib', scope='compile'), 'src/scala/some/other/lib', ], )
Dependency Hygiene
As the set of targets in a repository grows larger, it becomes increasingly important that they observe good dependency hygiene. In particular, following the 1:1:1 rule helps keep useful code self-contained. But even while observing 1:1:1, it's possible to declare and use dependencies that add little or no benefit for a target.
For example: a particularly large target may expose many different APIs. In cases where other targets depend on the large target, they might need only a fraction of those APIs. But because they can't declare a dependency on a smaller subset of the large target, they are forced to build the entire dependency. Even in the presence of distributed builds and caching, this slows down your build!
To help users address these problems for JVM targets, pants has a dep-usage.jvm
task which
supports scoring and summarizing the fractions of each dependency that a target uses.
For local analysis
In the default output mode ("summary" mode) the dep-usage.jvm
task outputs targets ordered by
a simple 'badness' score. The "badness" score is intended to indicate both how easy the dependency
would be to remove (based on the maximum fraction used by each dependee) and how valuable it would
be remove (based on a estimate of the transitive cost to build the dep).
Stat explanation:
max_usage
: fraction of the dependency target is being used. 0 means the target is safe to drop.cost_transitive
: the cost to bring in this target including its transitive dependencies in the build process-
badness
:cost_transitive/max_usage
, so the lower the better.:::shell $ ./pants -q dep-usage.jvm examples/src/scala/org/pantsbuild/example/hello/: [ {"badness": 0, "max_usage": 1.0, "cost_transitive": 0, "target": "//:scala-library-synthetic"}, {"badness": 8872, "max_usage": 0.125, "cost_transitive": 1109, "target": "examples/src/java/org/pantsbuild/example/hello/greet:greet"}, {"badness": 16410, "max_usage": 0.1, "cost_transitive": 1641, "target": "examples/src/scala/org/pantsbuild/example/hello/welcome:welcome"} ]
The above example indicates that within the scope of the scala examples, the
examples/src/scala/org/pantsbuild/example/hello/welcome
target is the worst dependency. This is
because it has a high transitive "cost" to build, and sees a maximum of 10% usage by its dependees.
For global analysis
The summary mode is great when users want to inspect their own targets. But for more in-depth
analysis, disabling summary mode (by passing the --no-summary
flag) will output raw usage data
for each dependency edge. This mode does no aggregation, so using it effectively usually means
doing analytics or graph analysis with an external tool.
Compiler Plugins
Pants has robust support for both developing and using compiler plugins for javac and scalac. For more details:
Further Reading
If you use Scala, see Scala Projects with Pants.
If you know Maven and want to know Pants equivalents, see Pants for Maven Experts.


Aggregated service data for {{ organisation.name }}
{{ to_3_sf(volume_summary.total_received) }} transactions received
More info
A transaction is the specific instance of a user’s interaction with a service by which they update their status with government. It starts when it is received by the service and ends when it has an outcome.
A channel is the way the service receives the transaction. It is the initial method of contact even if additional information is collected in other ways afterwards.
Channels used to access the service
Online {{ to_3_sf(volume_summary.received_online) }} ({{ volume_summary.received_online_pct_total }}%)
The transaction must be received online. Doesn’t include services where you use an online tool to fill out a paper form or transactions received via web chat.
| Organisation | Online transactions | Total transactions | Percentage online |
|---|---|---|---|
| {{ row.name }} | {{ to_3_sf(row.transactions_received_channel_count) }} | {{ to_3_sf(row.transactions_received_count) }} | {{ pct_of(row.transactions_received_channel_count, row.transactions_received_count) }}% |
Phone {{ to_3_sf(volume_summary.received_phone) }} ({{ volume_summary.received_phone_pct_total }}%)
The transaction must be received via the phone. Doesn’t include IVR or purely informational calls that don’t affect the outcome of a transaction.
| Organisation | Phone transactions | Total transactions | Percentage phone |
|---|---|---|---|
| {{ row.name }} | {{ to_3_sf(row.transactions_received_channel_count) }} | {{ to_3_sf(row.transactions_received_count) }} | {{ pct_of(row.transactions_received_channel_count, row.transactions_received_count) }}% |
Paper {{ to_3_sf(volume_summary.received_paper) }} ({{ volume_summary.received_paper_pct_total }}%)
The transaction must be received via a paper form filled out by hand. The form can be sent in any way including by post, email, fax or uploading.
| Organisation | Paper transactions | Total transactions | Percentage paper |
|---|---|---|---|
| {{ row.name }} | {{ to_3_sf(row.transactions_received_channel_count) }} | {{ to_3_sf(row.transactions_received_count) }} | {{ pct_of(row.transactions_received_channel_count, row.transactions_received_count) }}% |
Face-to-face {{ to_3_sf(volume_summary.received_face_to_face) }} ({{ volume_summary.received_face_to_face_pct_total }}%)
The transaction must be received through a face-to-face meeting with someone working for the service. Doesn’t include handing in a paper form in person.
| Organisation | Face-to-face transactions | Total transactions | Percentage face-to-face |
|---|---|---|---|
| {{ row.name }} | {{ to_3_sf(row.transactions_received_channel_count) }} | {{ to_3_sf(row.transactions_received_count) }} | {{ pct_of(row.transactions_received_channel_count, row.transactions_received_count) }}% |
Other {{ to_3_sf(volume_summary.received_other) }} ({{ volume_summary.received_other_pct_total }}%)
Any other way the user provides the information needed to complete a transaction that doesn’t fit into the Online, Phone, Paper and Face-to-face channels.
| Organisation | Other transactions | Total transactions | Percentage other |
|---|---|---|---|
| {{ row.name }} | {{ to_3_sf(row.transactions_received_channel_count) }} | {{ to_3_sf(row.transactions_received_count) }} | {{ pct_of(row.transactions_received_channel_count, row.transactions_received_count) }}% |
{{ to_3_sf(transactions_with_outcome_count) }} transactions ending in an outcome
More info
The delivery of the service is measured by the number of outcomes it produces.
Depending on the service, some transactions may take time to reach an outcome and therefore won’t be directly related to those received in the same period.
For example, if a service is seasonal and a transaction takes several months to reach an outcome it could show a many transactions received with no outcomes in the first month and more outcomes than received in later months.
Delivery of the service
Ending in an outcome {{ to_3_sf(transactions_with_outcome_count) }}
The number of transactions where no further decisions will be made for that transaction. For example:
- payment of a benefit isn’t an outcome — the decision about whether to award it or not is
- renewing a licence is a new transaction as it needs a new decision
| Organisation | Calls to get information | Call sample size | Percentage of calls to get information |
|---|---|---|---|
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
Ending in user's intended outcome {{ to_3_sf(transactions_with_users_intended_outcome_count) }} ({{ pct_users_intended_outcome }}%)
A subset of the transactions ending in an outcome where the outcome is what the user set out to achieve. For example:
- the user applying for a visa and being granted that visa
- the user sending money to a prisoner and the prisoner receiving the money
- the user reporting a crime and having the report accepted and processed
| Organisation | Calls to get information | Call sample size | Percentage of calls to get information |
|---|---|---|---|
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
7.2m calls received
More info
These are the total number of calls received by the service including calls that aren’t counted as a received transaction.
The 'reasons people called' are the initial reasons that triggered the user to contact the service via the phone, even if they then go on to discuss other subjects. Transactions received via the phone are not included in this list.
Reasons people called
Based on a sample of 10,000 calls
To get information 4k (40%)
Calls to get advice or guidance about the service. For example:
- to get information they couldn’t find online
- to learn about what the service is for
- to check that they’re eligible for the service
- to see how the service’s rules or process applies to them
- to check that a licence, visa etc is still valid
- to ask what to do if they’ve lost their licence, visa etc
- to find out why the service has sent them unexpected information
| Organisation | Calls to get information | Call sample size | Percentage of calls to get information |
|---|---|---|---|
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
To chase progress 3k (30%)
Calls to find out about a decision or action that the user expects the service to take. For example:
- to find out what has happened to information previously supplied
- to ask about the status of an application
- to find out when a payment will be made
- to ask why they haven’t heard from the service
| Organisation | Calls to get information | Call sample size | Percentage of calls to get information |
|---|---|---|---|
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
To challenge a decision 2k (20%)
Calls to dispute an instruction or request from the service or to appeal an outcome. For example:
- to appeal an outcome or decision
| Organisation | Calls to get information | Call sample size | Percentage of calls to get information |
|---|---|---|---|
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
Other 1.5k (15%)
Calls that don’t fit into the three previous categories. For example:
- to do a transaction
- to get help using the service
- to respond to a letter, call etc from the service
- to check that they’ve done the right thing
- to update their information when their situation changes
- to deregister from the service
- to tell the service its information is incorrect
| Organisation | Calls to get information | Call sample size | Percentage of calls to get information |
|---|---|---|---|
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
| Name of organisation | N | N | N% |
How this data is collected and calculated
This page is aggregated from data about services delivered by {{ organisation.name }}. It is currently made up of {% if organisation_type == 'department' and organisation.agencies.length > 0 %} {{ organisation.agencies.length }} agencies and {% endif %} {{ organisation.tasks.length}} services:
{% if organisation_type == 'department' and organisation.agencies.length > 0 %}{{ organisation.agencies.length }} agencies
-
{% for agency in organisation.agencies %}
- {{ agency.name }} {% endfor %}
{{ organisation.tasks.length }} services
-
{% for task in organisation.tasks %}
- {{ task.name }} {% endfor %}


--- layout: archive title: Zulip Chat Archive permalink: /stream/113488-general/topic/QED.20manifesto.20revisited.html ---
I was looking through Freek Wiedijk's "The QED manifesto revisited". A quote from it:
Finally, a multi-contributor library of formal mathematics should be created
that is well-organized. As I claimed in Section 2, the sociological puzzle has
not been solved yet of how to set up a library in such a way that it both
admits many contributors, but also stays well-organized. Current attempts
that have not yet been very successful in this respect are:
multi-contributor, but not really well-organized:
∗ MML
∗ Coq contribs
∗ AFPwell-organized, but not really multi-contributor:
∗ HOL Light library
∗ C- CoRN [4]
A good first goal for this library will be to formalize ‘all of undergraduate
mathematics’. This will take more than a hundred man-years [20], which
means that it will need the involvement of a non-trivial number of con-
tributors. Also, with something like that it will be clear whether it is well-
organized or not.The success of Wikipedia suggests that it might be possible to solve the
puzzle of having both many contributors and still also have a well-organized
whole. However, aiming for a ‘Wikipedia for formalized mathematics’ is for
me too much like hoping that someone else will do the work. I will believe
that such an approach can be successful when I see it happening.
I guess the next time I see him I should ask him whether he can see it happening. He asked me in Pittsburgh how much of our 1st and 2nd year material had not yet been formalised in Lean, and Chris Hughes gave him a very complete answer. The big hole is complex analysis.
@Freek Wiedijk do you see these notifications?
{% endraw %}Last updated: Apr 24 2020 at 19:02 UTC


Healthify
Download App
Healthify for Doctors
Login/Sign Up
Profile
My Appointments
My Medical History
My Lab Reports
Inbox
Dashboard
Search Doctors
Book Lab Test
Buy Medicines
Health Products


These all are activities I love to do on a regular basis.
Soccer is a team sport played between two teams of eleven players with a spherical ball.
Dance is a performing art form consisting of purposefully selected sequences of human movement.
Salsa is a popular form of social dance that originated in the Caribbean.
Rock'n'Roll is a very athletic, competitive form of partner dance that originated from lindy hop.
Gardening is the practice of growing and cultivating plants as part of horticulture.
A film, also called a movie, motion picture, theatrical film, or photoplay, is a series of still images which, when shown on a screen, creates the illusion of moving images due to the phi phenomenon.
Meditate
Meditation is a practice where an individual operates or trains the mind or induces a mode of consciousness, either to realize some benefit or for the mind to simply acknowledge its content without becoming identified with that content, or as an end in itself.


Recipebook
Text
Ingredients
Instructions
Created Before
Created After
Vegetarian
Search Recipe
New Recipe
Showing:
0
of
0
results
Previous
1
2
3
Next
New Recipe
Title
Description
Portion Size
Is the recipe vegetarian
Instructions
Ingredients
Loading...


OTHELLO A film review by Mark R. Leeper Copyright 1996 Mark R. Leeper
Capsule: Laurence Fishburne and Kenneth Branagh bring the classic tale of suspicion and betrayal to the screen. The production is handsome but much cut down from the play and does not have the caliber of acting we have seen in other recent productions of Shakespeare plays. Rating: +1 (-4 to +4)
When adapting Shakespeare to the screen there are conflicts involved that the Bard never knew about. He wrote in an artificially poetic Elizabethan English that conveys better to a 20th century audience than many people realize, but still requires acting skill to help get the idea across. He also intended his plays to be an afternoon's entertainment that would last a lot longer than a standard film. Most film adaptations are nowhere near accurate representations of the plays. They are usually trimmed down, and often lines and even scenes are given out of order. There seems to be a particular respect for Shakespearean actors because it is no easy matter to make the original prose flow naturally. Orson Welles was a master filmmaker who had more experience than perhaps anyone else did at adapting the great works of literature to other media. But if you look at his own adaptation of OTHELLO one sees a tremendous visual style and only the barest respect getting the original play on film.
Kenneth Branagh has a better understanding than most about how to do cinematic adaptations of Shakespeare and did about as good a job as is possible for any director in his MUCH ADO ABOUT NOTHING. As an actor he has an expressive face and conveys by just slight exaggeration many of the ideas in his face. It takes extreme skill to do that without making the performance hammy and unrealistic, but Branagh is has the kind of face that allows him to convey much of the meaning. In MUCH ADO and now in OTHELLO one can almost tell what he is saying without hearing the words.
Unfortunately, in OTHELLO he is not directing, so is responsible for only his own performance. His acting is not shared by the other performers in OTHELLO making the understanding of this film much more labored than that of MUCH ADO. Laurence Fishburne does a reasonable but much more traditional Othello, conveying all the emotion, but without Branagh's articulation.
Unfortunately acting honors go only to these two. For once the two name actors really are the best thing on the screen. Irene Jacob is fetching as Desdemona, but her line readings are uninspiring. Much of the end of the play should work on pity for the wrongly accused Desdemona, but she just does not convey enough emotion to have us feel a lot of sympathy for her character. Other performances, with the possible exception of Anna Patrick as Emilia, get the lines read but are indifferent.
The play has moments of visual style as we might expect from Oliver Parker. Parker does not have much experience as director but is a familiar face acting in Clive Barker horror films, which themselves depend more on visual impact than on story. Occasionally we wonder why Parker dwells so long on a single scene. Even the very first scene, a gondola slowly making its way past the camera, seems to go on too long and then pay off with only a very trite image. Feeling the need for a little action he adds a minor chase scene, apprehending Iago, at the end.
This is a film that will be remembered as "1995's OTHELLO," not "The OTHELLO" in the same sense that MUCH ADO ABOUT NOTHING is the interpretation for our generation. I give it a +1 on the -4 to +4 scale.
Mark R. Leeper<EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Hero firefighter tragically dies while rescuing colleagues from massive blaze
Lt. Jason Menard helped a probationary firefighter to the stairs and then returned to rescue another trapped firefighter, helping out of the window of the burning property in
by Danya Bazaraa, https://www.mirror.co.uk/authors/danya-bazaraa/A hero firefighter tragically died while rescuing his colleagues from a fierce blaze.
Lt. Jason Menard, from Massachusetts, lost his life while saving two other members of his crew, officials said.
They had been called out to rescue a resident and baby when they became trapped in the massive fire, reported just before 1am on Wednesday.
Shocking photos and video footage show bright orange flames completely engulfing the building.
Mr Menard, a father of three, had been planning on going on a family trip to Disney World - but now his loved ones have to plan his send off.
A tweet by Worcester Fire Dept said: "It is with a heavy heart that Chief Michael Lavoie announces the devastating loss of Lt. Jason Menard, a member of WFD since 2010 assigned to Ladder 5, Group 2 at McKeon Road Fire Station.
"He leaves behind his wife Tina, 3 children & parents. Please keep them in your prayers."
Mr Lavoie told a news conference Mr Menard "heroically and selflessly saved his crew, helping a probationary firefighter to the stairs and then returning to rescue another trapped firefighter, assisting him out the window."
The blaze then overtook the third floor and Mr Menard was not able to escape.
Mr Menard helped with search and rescue mission inside the house, and made sure the mum and baby escaped safely.
He also helped free two colleagues, newlywed Chris Pace, and a probationary firefighter.
Massachusetts Governor Charlie Baker said: "It's because of brave men and women like Lt. Menard and his team that we all rest easy at night.
"We must always be eternally grateful for their service and their sacrifice.
"He epitomised the devotion, camaraderie and bravery that make up the fabric of the Worcester Fire Department."


Pilotsmith(India) Pvt. Ltd.
www.pilotsmithindia.com
Hi $Approver$,
Document is recalled by :$DocumentOwner$
Document Number:
$DocumentNo$
Date: $DocumentDate$
Thank you,
Team Pilotsmith
This is an autogenerated email system dont reply


[1]
unbeknown to us the hotel was in the midst of it.
[2]
the awards by also the hilton wanting the revenue from room sales.


WebRTC namespace for jsxc.
- Source:
Members
-
<static> AUTO_ACCEPT
-
should we auto accept incoming calls?
- Source:
-
<static> chatJids
-
bare jid to current jid mapping
- Source:
-
<static> conn
-
strophe connection
- Source:
-
<static> last_caller
-
jid of the last caller
- Source:
-
<static> localStream
-
local video stream
- Source:
-
<static> remoteStream
-
remote video stream
- Source:
-
<static> reqVideoFeatures
-
required disco features
- Source:
Methods
-
<static> getCapableRes(jid) → {Array}
-
Return list of video capable resources.
Parameters:
Name Type Description jid
- Source:
Returns:
- Type
- Array
-
<static> getTurnCrendentials()
-
Checks if cached configuration is valid and if necessary update it.
- Source:
-
<static> hangUp()
-
Hang up the current call.
- Source:
-
<private, static> init()
-
Initialize webrtc plugin.
- Source:
-
<private, static> initWindow(event, win)
-
Add "video" button to window menu.
Parameters:
Name Type Description event
win
jQuery window object - Source:
-
<private, static> noStunCandidates()
-
No STUN candidates found
- Source:
-
<private, static> onAddRosterItem(event, bid, data, el)
-
Add "video" button to roster
Parameters:
Name Type Description event
bid
bid of roster item data
data wich belongs to bid el
the roster item - Source:
-
<private, static> onCallIncoming(event, sid)
-
Called on incoming call.
Parameters:
Name Type Description event
sid
Session id - Source:
-
<private, static> onCallRinging()
-
Remote station is ringing.
- Source:
-
<private, static> onCallTerminated(event, sid, reason, text)
-
Called if call is terminated.
Parameters:
Name Type Argument Description event
sid
Session id reason
Reason for termination text
<optional>
Optional explanation - Source:
-
<private, static> onCaps(event, jid)
-
Update "video" button if we receive cap information.
Parameters:
Name Type Description event
jid
- Source:
-
<private, static> onIceConnectionStateChanged(event, sid, sess)
-
Extracts local and remote ip and display it to the user.
Parameters:
Name Type Description event
sid
session id sess
- Source:
-
<private, static> onMediaFailure()
-
Called if media failes.
- Source:
-
<private, static> onMediaReady(event, stream)
-
Called if video/audio is ready. Open window and display some messages.
Parameters:
Name Type Description event
stream
- Source:
-
<private, static> onMessage(e, from)
-
Check if full jid changed.
Parameters:
Name Type Description e
from
full jid - Source:
-
<private, static> onPresence(ev, status)
-
Update icon on presence.
Parameters:
Name Type Description ev
status
- Source:
-
<private, static> onRemoteStreamAdded(event, data, sid)
-
Called if we receive a remote stream.
Parameters:
Name Type Description event
data
sid
Session id - Source:
-
<private, static> onRemoteStreamRemoved(event, data, sid)
-
Called if the remote stream was removed.
Parameters:
Name Type Description event
data
sid
Session id - Source:
-
<static> reqUserMedia()
-
Request video and audio from local user.
- Source:
-
<static> setStatus(txt, d)
-
Display status message to user.
Parameters:
Name Type Description txt
message d
duration in ms - Source:
-
<static> snapshot(video)
-
Make a snapshot from a video stream and display it.
Parameters:
Name Type Description video
Video stream - Source:
-
<static> startCall(jid, um)
-
Start a call to the specified jid.
Parameters:
Name Type Description jid
full jid um
requested user media - Source:
-
<static> updateIcon(bid)
-
Enable or disable "video" icon and assign full jid.
Parameters:
Name Type Description bid
CSS conform jid - Source:


Prosecutor general of Ukraine says one of subordinates involved in extortion scheme in Odesa
Riaboshapka has elaborated on massive raids carried out in Ukraine's Black Sea port city.
One of the prosecutors employed by the Prosecutor General's Office could be charged with complicity in extortion, says Ruslan Riaboshapka, Ukraine's chief prosecutor.
"This is a case involving extortion of land allotment to persons who weren't entitled to get it. Unfortunately, one of the PGO prosecutors was involved in this case, and measures are now being taken to verify such involvement and establish the guilt of each group member," Riaboshapka said, according to TSN.
The prosecutor general added that the raids also have to do with the investigation into UAh 100 mln embezzlement by officials of the Odesa City Council and corruption at the Ukrainian Seaports Administration.
Riaboshapka noted that prosecutors handed suspicion notices to some officials of the Odesa mayor's office.
At the same time, officials affiliated with Seaports Administration used fictitious contracts to try to gain ownership of property worth some UAH 54 million.
"This has to do with the supply of certain products that were never supplied and seaport reconstruction that never happened," Riaboshapka noted.
As reported earlier, on November 22, mass raids and searches were carried out in Odesa.
Meanwhile, city mayor Gennady Trukhanov was urgently hospitalized on the same day and reportedly underwent surgery at a local clinic. No extensive reports have been released on his health condition.


A document type declaration, or DOCTYPE, is an instruction that associates a particular SGML or XML document (for example, a webpage) with a document type definition (DTD) (for example, the formal definition of a particular version of HTML).
Where metadata - information about the document - is placed. It is the first element inside an html element. Information here is not visibly displayed on the screen but can impact it.
<link rel="stylesheet" href="/assets/css_final/style.css" media="screen"> <link rel="stylesheet" href="/assets/css_final/print.css" media="print"> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"> <link rel="icon" href="/favicon.ico" type="image/x-icon">
<meta name="description" content="This is what is read by search engines and displayed in search results."> <meta name="keywords" content="word1, word2, word3"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="canonical" href="http://www.lmo.com">
<meta name="og:title" content="Title read by social media"> <meta name="og:site_name" content="LMO Advertising"> <meta name="og:description" content="Description read by social media"> <meta name="og:image" content="http://www.lmo.com/image.jpg"> <meta name="og:url" content="http://www.lmo.com">
Where content of is placed, this information is read by the user and has a direct impact an accessiblity and search engine optimization.

Sample Outline

Second Level Heading

Second Level Heading

Third Level Heading

Fourth Level Heading

Second Level Heading

Third Level Heading

Fourth Level Heading

Fifth Level Heading

Sixth Level Heading

Fourth Level Heading

Fifth Level Heading

Second Level Heading

HTML Description List Element, formerly known as a definition list

Firefox

A free, open source, cross-platform, graphical ...

The Red Panda also known as the Lesser Panda, Wah, ...

Firefox

Mozilla Firefox

A free, open source, cross-platform, graphical ...


Here are some audio files I've recorded in the recent past. I like to write and record my own songs as well as some covers by artists and bands I like. I also have done a couple of podcasts here and there. I would like to find a niche for podcasting and focus on providing quality content that is informative as well as entertaining.
You can check out some originals I've recorded over at my Soundcloud Here (Link opens in a new window.)
Stay tuned for podcasts, which are coming soon!


{% for row in rows %}
Dear {{ row.name }},
You have to make payment until {{ row.payday}}. If no payment is made your account will be suspended.
{% endfor %}


Reusing views in storyboards with Auto Layout
Solving real-life Interface Builder problems
For the past few months, I have been working on a rather big project using storyboards and Auto Layout. This has been a great learning experience, and I think I now have a much better understanding of the pros and cons of using Interface Builder vs. pure code. Half a year ago I still assumed that at some point a clear winner would emerge, or at least I would end up preferring one approach over the other. But today I find myself switching between these approaches depending on the project, or even mixing them within a single project. It usually depends on subtle things like the complexity of your application flow and the inheritance relationships between your view controllers.
In any case, I think being able to work with Interface Builder and Auto Layout is an important skill to have as an iOS developer. The first time you try to set up constraints for a non-trivial view hierarchy can be a frustrating experience, and your productivity will probably first take a hit when you start working with storyboards, but you end up with some valuable new tools in your belt and a much better understanding of UIKit, if nothing else. I plan to write more about this topic in the coming months, but today I would like to focus on reusable views in the context of storyboards and Auto Layout.
Reusing interface components
Just like there are many patterns for code reuse, there are also different ways to reuse interface components. To start with something very basic, consider a view controller that occurs in two different flows in your application, e.g. a settings screen that is shown during the activation flow, but can also be accessed later through a navigation drawer. When both flows are defined in the same storyboard, you can lay out the common view controller inside the story board and use multiple segues to link it to the different flows:
Keeping the entire flow of your application defined inside a single storyboard is not always a good idea. When the application grows and multiple developers start working on the same project, defining different flows (or subflows) in separate storyboards helps to avoid ugly merge conflicts. In this case you can define the common view controller in its own interface file and add a reference to it in the different storyboards:
Often you don’t want to reuse entire screens but only certain parts of it. One approach is to use the view controller containment feature, i.e. define a view controller for each reusable view and use embed segues to link these view controllers to container views in other view controllers. Again you have the option to either lay out the view controller for the reusable view inside the storyboard itself or in a separate interface file:
This approach works but in many cases feels like overkill because the additional view controllers clutter your code base and storyboards. A more lightweight way of working is to reference views rather than view controllers in your storyboards and define the reusable view in a separate interface file:
The problem
When building a storyboard, Interface Builder allows you to specify the runtime class of the views and view controllers in it. This is a consistent way to link generic interface components to custom code. When the storyboard is loaded into memory, instances of the corresponding classes will be instantiated through the initWithCoder:
initializer. But often you want to link code to interface files in the other direction: you want to specify that an object of a certain class should be instantiated by loading the view or view controller from an interface file.
In the case of a view controller, this is pretty straightforward. For a view controller that is referenced in a storyboard, it suffices to override the getter of the nibName
property in your view controller implementation and specify the name of the corresponding nib file:
@implementation MyViewController
- (NSString *)nibName
{
return @"MyViewController";
}
@end
You can also override the nibBundle
property in case your nib file is not included in the main bundle. Alternatively, if you want to be more explicit, you can override initWithCoder:
with the same effect:
@implementation MyViewController
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
return [self initWithNibName:@"MyViewController" bundle:[NSBundle mainBundle]];
}
@end
In fact, you don’t even need to specify the name of the nib file or the bundle here because they will default to the class name and the main bundle when you specify nil
.
But achieving something similar for views is much less obvious. There is no nibName
property defined on UIView. And even if you know the name of the interface file, there may be multiple views defined inside it and you cannot rely on the File’s Owner to resolve this like you can with view controllers.
Resolving the roadblocks
If you adopt the convention that the first view defined inside the nib is the one you are interested in, you might be tempted to write something like this:
@implementation MyView
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
NSBundle *mainBundle = [NSBundle mainBundle];
NSArray *loadedViews = [mainBundle loadNibNamed:@"MyView" owner:nil options:nil];
return [loadedViews firstObject];
}
@end
Unfortunately, the above code results in an infinite loop. When initWithCoder:
is first called, the nib is unarchived, but the view inside it is instantiated through the initWithCoder:
method, which loads the nib again, etc. I first tried to work around this by calling the super class initializer and checking the amount of subviews afterwards. If there are no subviews, the view is a placeholder view referenced from a storyboard and should be loaded from the nib instead. But if there are subviews, the view has been loaded from the nib already and the recursion should stop:
@implementation MyView
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (![self.subviews count])
{
NSBundle *mainBundle = [NSBundle mainBundle];
NSArray *loadedViews = [mainBundle loadNibNamed:@"MyView" owner:nil options:nil];
self = [loadedViews firstObject];
}
return self;
}
@end
When I tried this, the app crashed with an uncaught exception “This coder requires that replaced objects be returned from initWithCoder:”. It took me a while to figure this one out, but eventually I stumbled on a method in NSObject
called awakeAfterUsingCoder:
(not to be confused with awakeFromNib
), which is called after initWithCoder:
and allows you to substitute another object in place of the object that was decoded. So this is more or less what we were looking for:
@implementation MyView
- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
{
if (![self.subviews count])
{
NSBundle *mainBundle = [NSBundle mainBundle];
NSArray *loadedViews = [mainBundle loadNibNamed:@"MyView" owner:nil options:nil];
return [loadedViews firstObject];
}
return self;
}
@end
Dealing with constraints
So far, so good. We can now add placeholder views to a storyboard, set their class in the identity inspector, and dynamically replace those placeholders with actual content loaded from nib files, without breaking the view outlets in the storyboard. One problem that remains is that, without any precautions, we lose any view properties that depend on the context inside the storyboard. In order to solve this, we need to transfer the frame and the layout constraints from the placeholder view to the view that was loaded from the nib file, so the end result might look something like this:
@implementation MyView
- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
{
if (![self.subviews count])
{
NSBundle *mainBundle = [NSBundle mainBundle];
NSArray *loadedViews = [mainBundle loadNibNamed:@"MyView" owner:nil options:nil];
MyView *loadedView = [loadedViews firstObject];
loadedView.frame = self.frame;
loadedView.autoresizingMask = self.autoresizingMask;
loadedView.translatesAutoresizingMaskIntoConstraints =
self.translatesAutoresizingMaskIntoConstraints;
for (NSLayoutConstraint *constraint in self.constraints)
{
id firstItem = constraint.firstItem;
if (firstItem == self)
{
firstItem = loadedView;
}
id secondItem = constraint.secondItem;
if (secondItem == self)
{
secondItem = loadedView;
}
[loadedView addConstraint:
[NSLayoutConstraint constraintWithItem:firstItem
attribute:constraint.firstAttribute
relatedBy:constraint.relation
toItem:secondItem
attribute:constraint.secondAttribute
multiplier:constraint.multiplier
constant:constraint.constant]];
}
return loadedView;
}
return self;
}
@end
Now this is quite a bit of boilerplate code, so you probably want to move it to a category on UIView or something like that so your awakeAfterUsingCoder:
implementation can be reduced to a one-liner.
Intrinsic size of placeholder views
For components like labels and image views, the intrinsic size can be determined at runtime based on the content. Because of this, Auto Layout does not require you to fully constrain the width and height of these views. Custom views defined in a nib file may also be able to determine their intrinsic size dynamically, but when you add a placeholder view to a view controller in a storyboard, you need to consider this explicitly or Auto Layout will complain about missing constraints. Fortunately there is a dropdown in the Size inspector that allows you to specify that a view is just a placeholder and the width or height will be determined at runtime, when the placeholder has been replaced with actual content:
An alternative approach
So far we have assumed that the reusable view is defined as the first top-level object in the interface file. An alternative approach is to set the File’s Owner of the interface file to the reusable view class, and to consider the first top-level object in the interface file to be a subview of the reusable view that contains all the other subviews. Outlets can be linked to the File’s Owner rather than to the top-level (sub)view. This breaks the infinite initWithCoder:
loop so you don’t need to rely on awakeAfterUsingCoder:
. Instead of replacing the placeholder view, you are adding the subview loaded from the nib file to it. The advantage is that you don’t lose the context dependent view properties of the placeholder. However, in the case of Auto Layout, you still need to ensure that appropriate constraints are applied to the added subview:
@implementation MyView
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
NSBundle *mainBundle = [NSBundle mainBundle];
NSArray *loadedViews = [mainBundle loadNibNamed:@"MyView" owner:self options:nil];
MyView *loadedSubview = [loadedViews firstObject];
[self addSubview:loadedSubview];
loadedSubview.translatesAutoresizingMaskIntoConstraints = NO;
[self addConstraint:[self pin:loadedSubview attribute:NSLayoutAttributeTop]];
[self addConstraint:[self pin:loadedSubview attribute:NSLayoutAttributeLeft]];
[self addConstraint:[self pin:loadedSubview attribute:NSLayoutAttributeBottom]];
[self addConstraint:[self pin:loadedSubview attribute:NSLayoutAttributeRight]];
}
return self;
}
- (NSLayoutConstraint *)pin:(id)item attribute:(NSLayoutAttribute)attribute
{
return [NSLayoutConstraint constraintWithItem:self
attribute:attribute
relatedBy:NSLayoutRelationEqual
toItem:item
attribute:attribute
multiplier:1.0
constant:0.0];
}
@end
Bottom line
As your project grows, being able to reuse interface components becomes gradually more important. Because of this, it is worth investing some effort right at the start to develop some generic reuse strategies that cover the edge cases. I still hope that future versions of Xcode will make it easier to reuse views in storyboards, but for now I manage to get by with some common UIView categories.


|
Generated by JDiff |
||||||||
| PREV PACKAGE NEXT PACKAGE FRAMES NO FRAMES |
This file contains all the changes in documentation in the packagecom.google.inject.assistedinject
as colored differences. Deletions are shownlike this, and additions are shown like this.
If no deletions or additions are shown in an entry, the HTML tags will be what has changed. The new HTML tags are shown in the differences. If no documentation existed, and then some was added in a later version, this change is noted in the appropriate class pages of differences, but the change is not shown on this page. Only changes in existing text are shown here. Similarly, documentation which was inherited from another class or interface is not shown here.
Note that an HTML error in the new documentation may cause the display of other documentation changes to be presented incorrectly. For instance, failure to close a <code> tag will cause all subsequent paragraphs to be displayed differently.
ConstructorsWhen used in tandem with FactoryModuleBuilder, constructors annotated with {@code @AssistedInject} indicate thattheymultiple constructors can beinstantiatedinjected,by theeach with different parameters. AssistedInject annotations should not be mixed with {@literal @}FactoryProviderInject annotations.Each constructorThe assisted parameters must exactly match one corresponding factorymethod withinmethod within the factory interface.,butConstructorthe parametersmust be either supplied bydo not need to be in thefactorysameinterfaceorder.and marked withConstructors annotated with@Assisted,AssistedInjectorarethey must becreated by Guiceinjectableand receive all the benefits (such as AOP).@deprecatedObsolete Usage: When used in tandem with FactoryProvider
now,works betterconstructors annotated withthe standard{@literalcode @InjectAssistedInject}trigger a "backwards compatibilityannotationmode".When using thatThe assisted parametersannotation,mustparametersexactlyarematch onematched by namecorresponding factory methodandwithin the factory interfacetype rather thanand all must be in the samebyorderpositionas listed in the factory. Inadditionthis backwards compatable mode,valuesconstructorsthatannotated with AssistedInject are not createduseby Guice and thus receive none of thestandardbenefits.{@literal@Inject}Constructor
constructorparameters must be either suppliedannotation are eligible forby the factory interfacemethodand marked with@Assisted
, or they mustinterceptionbe injectable.@author <EMAIL_ADDRESS>(Jerome Mourits) @author<EMAIL_ADDRESS>(Jesse Wilson)
Obsolete. Prefer FactoryModuleBuilder for its more concise API and additional capability.Provides a factory that combines the caller's arguments with injector-supplied values to construct objects.
Defining a factory
Create an interface whose methods return the constructed type, or any of its supertypes. The method's parameters are the arguments required to build the constructed type.public interface PaymentFactory { Payment create(Date startDate, Money amount); }You can name your factory methods whatever you like, such as create, createPayment or newPayment.Creating a type that accepts factory parameters
{@code constructedType} is a concrete class with an {@literal @}Inject-annotated constructor. In addition to injector-supplied parameters, the constructor should have parameters that match each of the factory method's parameters. Each factory-supplied parameter requires an {@literal @}Assisted annotation. This serves to document that the parameter is not bound by your application's modules.public class RealPayment implements Payment { {@literal @}Inject public RealPayment( CreditService creditService, AuthService authService, {@literal @}Assisted Date startDate, {@literal @}Assisted Money amount) { ... } }Any parameter that permits a null value should also be annotated {@code @Nullable}.Configuring factories
In your module, bind the factory interface to the returned factory:bind(PaymentFactory.class).toProvider( FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));As a side-effect of this binding, Guice will inject the factory to initialize it for use. The factory cannot be used until the injector has been initialized.Using the factory
Inject your factory into your application classes. When you use the factory, your arguments will be combined with values from the injector to construct an instance.public class PaymentAction { {@literal @}Inject private PaymentFactory paymentFactory; public void doPayment(Money amount) { Payment payment = paymentFactory.create(new Date(), amount); payment.apply(); } }Making parameter types distinct
The types of the factory method's parameters must be distinct. To use multiple parameters of the same type, use a named {@literal @}Assisted annotation to disambiguate the parameters. The names must be applied to the factory method's parameters:public interface PaymentFactory { Payment create( {@literal @}Assisted("startDate") Date startDate, {@literal @}Assisted("dueDate") Date dueDate, Money amount); }...and to the concrete type's constructor parameters:public class RealPayment implements Payment { {@literal @}Inject public RealPayment( CreditService creditService, AuthService authService, {@literal @}Assisted("startDate") Date startDate, {@literal @}Assisted("dueDate") Date dueDate, {@literal @}Assisted Money amount) { ... } }Values are created by Guice
Returned factories use child injectors to create values. The values are eligible for method interception. In addition, {@literal @}{@literal Inject} members will be injected before they are returned.Backwards compatibility using {@literal @}AssistedInject
Instead of the {@literal @}Inject annotation, you may annotate the constructed classes with {@literal @}AssistedInject. This triggers a limited backwards-compatability mode.Instead of matching factory method arguments to constructor parameters using their names, the parameters are matched by their order. The first factory method argument is used for the first {@literal @}Assisted constructor parameter, etc.. Annotation names have no effect.
Returned values are not created by Guice. These types are not eligible for method interception. They do receive post-construction member injection. @param
The factory interface @author<EMAIL_ADDRESS>(Jerome Mourits) @author<EMAIL_ADDRESS>(Jesse Wilson) @author<EMAIL_ADDRESS>(Daniel Martin) @deprecated use FactoryModuleBuilder instead.


Detailed course offerings (Time Schedule) are available for
LATIN 101 Elementary Latin (5)
An intensive study of grammar, with reading and writing of simple Latin prose. First in a sequence of three. Offered: A.
View course details in MyPlan: LATIN 101
LATIN 102 Elementary Latin (5)
An intensive study of grammar, with reading and writing of simple Latin prose. Second in a sequence of three. Prerequisite: LATIN 101. Offered: W.
View course details in MyPlan: LATIN 102
LATIN 103 Elementary Latin (5)
Reading of selections from classical Latin literature. Third in a sequence of three. Prerequisite: LATIN 102. Offered: Sp.
View course details in MyPlan: LATIN 103
LATIN 300 Latin Language, Accelerated (5)
Intensive introduction to classical Latin. Not accepted as upper-division credit toward a major in Latin or classics. Does not satisfy foreign language proficiency requirement. Cannot be taken for credit if LATIN 101 already taken. Offered: WS.
View course details in MyPlan: LATIN 300
LATIN 301 Latin Language, Accelerated (5)
Intensive introduction to classical Latin. Not accepted as upper-division credit toward a major in Latin or classics. Does not satisfy foreign language proficiency requirement. Cannot be taken for credit if LATIN 101 already taken. Prerequisite: LATIN 300. Offered: SpS.
View course details in MyPlan: LATIN 301
LATIN 304 Introductory Readings in Latin Literature (5, max. 15) VLPA
Introduction to reading Latin literature in prose and poetry from various Latin authors; grammar review. Recommended: either LATIN 103 or LATIN 301. Intended to be taken prior to LATIN 305 or more advanced classes. Offered: S.
View course details in MyPlan: LATIN 304
LATIN 305 Introduction to Latin Literature (5) VLPA
Readings in prose and poetry from various Latin authors; elementary exercises in Latin prose composition. Offered: A.
View course details in MyPlan: LATIN 305
LATIN 306 Cicero and Ovid (5) VLPA
Readings from the orations of Cicero and the poetry of Ovid; elementary exercises in Latin prose composition. Prerequisite: LATIN 305. Offered: W.
View course details in MyPlan: LATIN 306
LATIN 307 Vergil (5) VLPA
Selections from the first six books of the Aeneid; elementary exercises in Latin prose composition or metrics. Prerequisite: LATIN 306. Offered: Sp.
View course details in MyPlan: LATIN 307
LATIN 401 Medieval Latin Literature to 1200 (3) VLPA Hinds
Texts read in Latin; cultural and historical contexts discussed. Presupposes year and a half of Latin or equivalent. Informal individual guidance available to members of class handling medieval or Renaissance Latin texts in their research.
View course details in MyPlan: LATIN 401
LATIN 402 Later Medieval and Renaissance Latin Literature (3) VLPA Hinds
Texts read in Latin; cultural and historical contexts discussed. Presupposes year and a half of Latin or equivalent. Informal individual guidance available to members of class handling medieval or Renaissance Latin texts in their research.
View course details in MyPlan: LATIN 402
LATIN 404 Advanced Readings in Latin Literature (5, max. 15) VLPA
Advanced readings in Latin literature in prose and poetry from various Latin authors; grammar review. Recommended: either LATIN 103 or LATIN 301. Intended to be taken prior to more advanced classes at the 400 level. Offered: S.
View course details in MyPlan: LATIN 404
LATIN 405 Undergraduate Seminar in Classics (5, max. 15)
Seminar on a broadly defined topic in classics. Includes reading in Latin or Greek as appropriate for individual students. Additional readings of works in English translation and works of scholarship chosen to give undergraduate majors familiarity with research methods and perspective on the discipline.
View course details in MyPlan: LATIN 405
LATIN 412 Lucretius (3) VLPA Blondell, Clauss
View course details in MyPlan: LATIN 412
LATIN 414 Seneca (3) VLPA Blondell, Gowing, Stroup
View course details in MyPlan: LATIN 414
LATIN 422 Livy (3) VLPA Clauss, Gowing, Stroup
View course details in MyPlan: LATIN 422
LATIN 423 Cicero and Sallust (3) VLPA Clauss, Gowing, Stroup
View course details in MyPlan: LATIN 423
LATIN 424 Tacitus (3) VLPA Clauss, Gowing, Stroup
View course details in MyPlan: LATIN 424
LATIN 447 Roman Lyric (3) VLPA Clauss, Connors, Hinds
View course details in MyPlan: LATIN 447
LATIN 449 Roman Elegy (3) VLPA Connors, Hinds
View course details in MyPlan: LATIN 449
LATIN 451 Roman Satire (3) VLPA Connors, Gowing, Stroup
View course details in MyPlan: LATIN 451
LATIN 457 Roman Drama (3) VLPA Connors
View course details in MyPlan: LATIN 457
LATIN 458 Roman Epic (3) VLPA Clauss, Connors, Hinds
View course details in MyPlan: LATIN 458
LATIN 461 Latin Literature of the Republic (3-5, max. 15) VLPA
Readings and discussion of selected authors from the era of the Roman Republic.
View course details in MyPlan: LATIN 461
LATIN 462 Latin Literature of the Augustan Age (3-5, max. 15) VLPA
Readings and discussion of selected authors from the Augustan era.
View course details in MyPlan: LATIN 462
LATIN 463 Latin Literature of the Empire (3-5, max. 15) VLPA
Readings and discussion of selected authors from the Roman Empire.
View course details in MyPlan: LATIN 463
LATIN 465 Roman Topography and Monuments (5, max. 10) VLPA Clauss, Gowing, Levin-Richardson, Stroup, Topper
Study of the material remains of ancient Rome from the archaic period through the imperial age. Reading of source materials and inscriptions in Latin. Conducted in Rome. Offered: Sp.
View course details in MyPlan: LATIN 465
LATIN 475 Improvement of Teaching: Latin (5) VLPA
Offered: jointly with EDC&I 438.
View course details in MyPlan: LATIN 475
LATIN 490 Supervised Study (*, max. 18)
Special work in literary and philosophical texts for graduates and undergraduates.
View course details in MyPlan: LATIN 490
LATIN 500 Grammar and Composition (5) Clauss, Gowing, Hinds, Stroup
Translation of passages from English to Latin for the purpose of acquiring advanced knowledge of the grammar and style of the classical tongue.
View course details in MyPlan: LATIN 500
LATIN 501 Vergil (5) Clauss, Hinds
The Aeneid.
View course details in MyPlan: LATIN 501
LATIN 502 Horace (5) Clauss
Odes or Epistles.
View course details in MyPlan: LATIN 502
LATIN 503 Plautus and Terence: Early Republican Literature (5) Connors, Stroup
Plautus and Terence.
View course details in MyPlan: LATIN 503
LATIN 504 Philosophy at Rome (5) Blondell, Stroup
Selected philosophical works of Cicero and other sources for Hellenistic and Roman philosophy.
View course details in MyPlan: LATIN 504
LATIN 506 Cicero (5) Gowing, Stroup
Select speeches, with attention to rhetorical theory and/or letters.
View course details in MyPlan: LATIN 506
LATIN 508 Silver Latin Literature (5) Connors, Hinds
Selections from Martial, Lucan, and Petronius.
View course details in MyPlan: LATIN 508
LATIN 510 Roman Historians (5, max. 10) Clauss, Gowing
Caesar, Livy, and Tacitus.
View course details in MyPlan: LATIN 510
LATIN 512 Augustan Poetry (5, max. 15) Clauss, Connors, Hinds.
View course details in MyPlan: LATIN 512
LATIN 520 Seminar (5, max. 45)
View course details in MyPlan: LATIN 520
LATIN 540 Topics in Latin Literary History (5, max. 25)
Reading of a range of Latin texts by various authors. Offered: AWSpS.
View course details in MyPlan: LATIN 540
LATIN 565 Seminar in Rome (5, max. 10) Clauss, Gowing, Levin-Richardson, Stroup, Topper
Study of selected topics and authors in Latin literature. Conducted in Rome.
View course details in MyPlan: LATIN 565
LATIN 590 Supervised Study (*, max. 18)
Prerequisite: permission of Graduate Program Coordinator.
View course details in MyPlan: LATIN 590
LATIN 600 Independent Study or Research (*-)
View course details in MyPlan: LATIN 600


Japan is an island country in East Asia. Located in the Pacific Ocean, it lies off the eastern coast of the Asian mainland and stretches from the Sea of Okhotsk in the north to the East China Sea and China in the southwest.
Standing on the River Thames, London has been a major settlement for two millennia, its history going back to its founding by the Romans, who named it Londinium.
India is the seventh largest country in the world. It is the main part of the Indian subcontinent. The countries next to India are Pakistan, Bangladesh, Myanmar, China, Bhutan, and Nepal. It is also near Sri Lanka, an island country.