UP | HOME

Notes on Using AWS (provisioning an instance, getting it set up for development, etc.)

Table of Contents

1 Overall Notes

Most of this page was built when I set up my first instance, around 2018-19. For more recent changes, look for "2023". See also notes for 2025.

2 Setting up an AWS instance

2.1 About spot instance pricing and availability

2.1.1 Pricing

Pricing is per instance-hour (or fraction thereof) until instance is stopped (probably the best option if you want to restart it later) or terminated (totally destroyed, not restartable later).

Reserved instances are cheaper than on-demand, but require 1- or 3-yr commitments (still pretty reasonable in the case of a micro or small instance).

2.1.2 Does the spot instance run again when the spot price comes back down?

2.1.3 What sort of state preservation (storage) do I need?

EBS?

S3?

2.2 Choosing an EC2 instance type

Spot pricing is cheapest, but arbitrary startup/shutdown issues make it more complex, along with the fact that your users simply might not tolerate your web app being down "for a while".

2.2.1 2023

The options are more greater. Plus, I want to connect a clone of elastic storage drive from my first instance from lo these many years ago.

2.2.1.1 Pricing

I think I still want an EC2 reserved instance savings plan.

Amazon, however, say, "We recommend Savings Plans (over Reserved Instances)."

I think I want an EC2 Instance savings plan (not reserved instance; although I'm not yet sure of the difference).

Their recommendation page (https://us-east-1.console.aws.amazon.com/cost-management/home?region=us-east-1#/savings-plans/recommendations?lookbackPeriodInDays=SIXTY_DAYS&paymentOption=ALL_UPFRONT&scope=PAYER&spType=EC2_INSTANCE_SP&termInYears=THREE_YEAR&tokens=%5B%5D) shows no recommendations. I think because my usage is < $0.10/hour? I think I paid something like $120 for a t2.micro instance for 3 years, which amounts to (/ 120.0 (* 3 365 24)) $0.005/hour.

I think my region is US-East (N. Virginia). Current node is in Availability Zone "us-east-1a". Answer: yes, N. Virginia. See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html.

There's a Compute pricing page here: https://aws.amazon.com/savingsplans/compute-pricing/.

On-demand instance pricing appears to be here: https://aws.amazon.com/ec2/pricing/on-demand/

Pick Instance name Hourly rate vCPUs Memory Always-on Total Comments
  t3.micro $0.0104 2 1 GiB $274.06  
  t3a.micro $0.0094 2 1 GiB $247.71 AMD, fewer FLOPS
  t2.micro $0.0116 1 1 GiB $305.68 More expensive!
X t4g.micro $0.0084 2 1 GiB $221.36 ARM-based AWS Graviton2 CPUs

Always-on calc: (* 3 366 24 0.0084)

Comments on t4g below.

The m-series is also general-purpose, but

  1. doesn't go below size "medium",
  2. doesn't appear to be burstable,
  3. has more memory/cpu,
  4. and the cheapest one is almost ten times a comparable-ish t-series.

So, basically, they're more for larger-scale systems, which I am not.

Savings plans compute pricing (use the "EC2 Instance Savings Plans" tab): https://aws.amazon.com/savingsplans/compute-pricing/

Us-east-1 t3.micro 3 yrs Linux shared tenancy all up front = $102.77 ($0.0039 multiplied out).

Which is $2.85/month (/ (* 0.0039 3 366 24) 36)

2.2.1.1.1 RESEARCH-DONE Tenancy

What's tenancy? Options are:

Dedicated instance
Instance runs on single-tenant hardware.
Dedicated host
Instance runs on a physical server. (Not sure how that's different from dedicated instance.)
Shared
This is the default. Multiple accounts on the same physical hardware. Which, fine, so long as it looks like one host to me. https://theithollow.com/2017/10/16/understanding-aws-tenancy/ recommends shared.
2.2.1.2 DONE Instance configuration
2.2.1.2.1 "jammy" vs. "focal" builds (tl;dr: major version number difference)

Two choices for Ubuntu 22.04 LTS, hvm virtualization, ENA enabled, root device type ebs: "jammy" build, "focal" build. What's the difference?

Ah, I see, I missed the version number difference. Jammy is 22.04, while Focal is 20.04.

2.2.1.2.2 t3 vs. t3a vs. t4g

t3a instances use AMD chips, look less optimized for floating-point ops and are slightly cheaper. I'm not doing intense FP calcs, maybe I should use t3a instead of t3.

2.2.1.2.2.1 t4g – wacky chip

t4g uses another weird chip, an ARM-based AWS Graviton2 processor. It's cheaper, nice, but how well will my workload (Java, Go) run on it? https://en.wikipedia.org/wiki/AWS_Graviton

Amazon claims their Corretto JVM runs fine on Graviton: https://github.com/aws/aws-graviton-getting-started/blob/main/java.md#:~:text=Java%20on%20Graviton&text=Java%20is%20well%20supported%20and,)%20supports%20Graviton%2Dpowered%20instances.

And it looks like Go runs fine, too: https://aws.amazon.com/blogs/compute/making-your-go-workloads-up-to-20-faster-with-go-1-18-and-aws-graviton/.

2.2.1.2.2.1.1 Does Amazon give back to Java w/their Corretto JVM?

Apparently, yes, at least some.

2.2.1.2.3 Firewall (security groups)

Current group seems to be launch-wizard-1.

Current config:

Name Security group rule ID IP version Type Protocol Port range Source Description
sgr-08642cbf72bac1cb1 IPv4 SSH TCP 22 0.0.0.0/0  
sgr-0af3b8d6607c6cdcb IPv4 Custom TCP TCP 8443 0.0.0.0/0 HTTPS
sgr-0145f40c7b5f3bb85 IPv4 Custom TCP TCP 8080 0.0.0.0/0 HTTP
sgr-0c95244b206ed9bda IPv4 HTTP TCP 80 0.0.0.0/0  
sgr-00788c1ae28c5b690 IPv4 HTTPS TCP 443 0.0.0.0/0  
sgr-0836297035b643dbf IPv4 Custom TCP TCP 453 0.0.0.0/0 HTTPS
sgr-01041fa45d0603774 IPv4 Custom TCP TCP 90 0.0.0.0/0 HTTP
2.2.1.2.4 Storage

Space: existing instances, root drive:

original /dev/sda1 8 GiB
web 2 /dev/sda1 12 GiB
web 3 /dev/sda1 12 GiB
2.2.1.2.4.1 gp2 vs. gp3

See https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-storage-compare-volume-types.html.

Hard to tell the difference, but…

  gp3 gp2
Default/baseline IOPS 3,000 3/GiB (minimum 100 IOPS). Can burst to 3,000 IOPS
Default/baseline throughput 125 MiB/s 128-250 MiB/s, depending on volume size
Max throughput 1,000 MiB/s 250 MiB/s
Price $0.08/GiB/month $0.10/GiB/month

I think gp3 is the play.

2.2.1.2.4.2 DONE Adding new volume created from snapshot of old instance

So, at this point, I have a naked Linux instance.

Still need to install Java, Tomcat, JspWiki. I wonder if I can just slap on a new volume created from a snapshot of the previous instance's root volume and go from there.

2.2.1.2.5 Advanced Details – I don't think this is needed

Header says it.

2.3 Launch and connect simple instance

2.3.1 On-demand instance – the more expensive (but simpler) option

Launch isn't too hard. I picked an AMI Linux instance (described below) and fired it up.

Amazon Linux image I used:

  • amzn-ami-pv-2013.03.1.x86_64-ebs (ami-05355a6c)
    • Description: Amazon Linux AMI x86_64 PV
    • Amazon's extended description: EVS-Backed, PV-GRUB image. Linux 3.4, AWS tools, repository access to multiple versions of MySQL, PostgreSQL, Python, Ruby, and Tomcat
    • Platform: Amazon Linux

Connecting is more of an issue. I need a .pem file, and I need to either (a) find the one I used to create the keypair in the AWS console, or (b) create a new keypair (and matching .pem file). (Note: it turns out you can download a .pem ("privacy-enhanced email" – the concept is dead but the file format lingers on) when you create a keypair. Don't lose the .pem file because I don't see how you can download it again. Your browser will put in the (default) download directory.

2.3.2 Spot instance – cheaper but a little more complex to set up

This might be unworkable. Looks like the persistent volumes (EBS) are allocated per-zone (e.g., us-east-1a), but the spot instance could be launched in any zone, so if it gets relaunched into another zone, the persistent volume won't be available. Might be better to just use an on-demand instance, until you can figure out (a) how to make a spot instance recover from interruptions, and (b) how to set things up so users can know the spot instance is down for the time being and to be patient. Note that this last requirement might be stupid, because users simply might not be able to tolerate an instance being down, period.

As above (On-demand instance), but…

When hitting "Launch instance":

  • Use the "Classic dialog" and select "Request Spot Instances".
  • Mark it a persistent request (which, I think means it'll be re-evaluated when the price goes so high the instance is shut down), and
  • In the "Storage Device Configuation" screen, edit the config to turn off the "Delete on termination" flag for the root device.

Note that this instance will run until you cancel your spot request. You can't terminate it (if you try, it'll just respawn). If you want to kill it, you'll have to cancel the spot request itself.

2.4 TODO Routing www2.how-hard-can-it-be.com to the AWS instance

Consider allocating an Elastic IP address and using your DNS solution (dyndns.org, in my case) to map it to a particular hostname.

2.4.1 Or use ddclient, command-line DynDNS interface

(Note: don't forget the long-term plan to move to Route53, which will completely invalidate this approach.)

Install from DynDNS.org. https://help.dyn.com/ddclient/

If you're lucky, Past You already did this and set it up in /etc/init.d/ddclient (start/stop script attached to booting the instance), and configured it at /etc/ddclient.conf.

If you're slightly less lucky, Past You changed the DynDNS password at some point and you need to go update the config. Use quotes if the password has spaces or other shell-special characters.

You can always generate a new config at https://account.dyn.com/tools/clientconfig.html.

sudo /etc/init.d/ddclient restart

to restart after fixing the config. Check log output in /var/log/syslog.

2.5 Software installation and configuration

Note: you probably want to stay far, far away from Wildfly (JBoss) and Eclipse (at least… don't let RedHat get their claws on it, or you will constantly be fighting with it and doing research to figure how to fix the latest weirdness that doesn't work like the docs say it should). I wouldn't even bother with Apache if you want to do something with a Java server. Just straight Tomcat seems to be the simplest solution. It's plenty capable of handling all the Java server-side stuff you'll probably want to use.

See my notes on JspWiki.

2.5.1 Apache

Install:

sudo yum install ...

Configure to run at boot:

sudo chkconfig --add httpd
sudo chkconfig --level 5 httpd on

2.5.2 WildFly (JBoss 8)

2.5.2.1 Install
2.5.2.1.1 Download .tgz file from http://wildfly.org
wildflyTarFile="<path-to-downloaded-image>"
cd /opt
sudo mkdir -p WildFly
cd WildFly
tar xvzf $wildflyTarFile
cd /opt/WildFly/<installed-directory>/bin
sudo ./standalone.sh    # Fire it up!
2.5.2.1.2 Open up WildFly to connections from the outside world
<interfaces>
  <interface name="management">
    <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
  </interface>
  <interface name="public">
    <!-- <inet-address value="${jboss.bind.address:127.0.0.1}"/> -->  <!-- Commented out -->
    <any-address/>  <!-- Add this line. -->
  </interface>
2.5.2.1.3 If you want, change the ports from 8080/8443 to 80/443
<socket-binding name="http" port="${jboss.http.port:80}"/>     <!-- Was 8080 -->
<socket-binding name="https" port="${jboss.https.port:443}"/>  <!-- Was 8443 -->
2.5.2.1.4 Make the host something other than "localhost"? (Not sure this works yet.)
<host name="default-host" alias="how-hard-can-it-be.com">
    <location name="/" handler="welcome-content"/>
</host>
2.5.2.1.5 Add a user for jboss to run under
# useradd jboss
2.5.2.2 Run
/opt/WildFly/wildfly-8.0.0.Alpha4/bin
sudo ./standalone.sh

2.5.3 Amazon Corretto (OpenJDK implementation that runs on tg4 (ARM))

2.5.4 Aptitude – curses-based apt client

apt install aptitude
sudo apt install aptitude

2.5.5 Authbind

You'll need this to allow non-root processes to open ports < 1024.

2.5.6 Tomcat (2023)

See:

As of JSPWiki v2.12.0, Tomcat 10 is NOT supported, only Tomcat 9. You can live adventurously, if you want, and try the Tomcat migration tool(s), but I choose not to at this time.

Also, there are no prompts on where to install tomcat9 when you use aptitude (or, presumably, apt-get).

2.5.7 DONE Creating fixed user and group ids (2023)

2.5.7.1 Problem

Might need to move the user/data volume to another VM at some point in the future, and it would be useful to be able to create users (e.g., "tomcat") and groups (e.g., "sysport") with fixed ids (e.g., 200) so the previous user volume can simply be dropped into the new VM.

Note the following on my old instance:

ls -l server.xml
-rw-r----- 1 root tomcat8 6567 Mar  6  2017 server.xml

ls -ln server.xml
-rw-r----- 1 0 116 6567 Mar  6  2017 server.xml

So, group 116 is tomcat8 there.

However, when I snapshot the volume and create a new volume from the snapshot and mount it on the new VM, I see the following, when examing the same files (mounted on a new mountpoint):

ls -l server.xml
-rw-r----- 1 root landscape 6567 Mar  6  2017 server.xml

ls -ln server.xml
-rw-r----- 1 0 116 6567 Mar  6  2017 server.xml

So, the group id (116) came across just fine, but on the VM, it corresponds to group "landscape" (whatever that is), instead of "tomcat8".

2.5.7.2 DONE Solution
adduser --uid <n>
addgroup --gid <n>

(along with other options).

To find a good id…

Users sorted by uid:

cat /etc/passwd | awk -F: '{printf "%5d\t%5d\t%s\n", $3,$4,$1 }' | sort -k 1n

Groups sorted by gid:

cat /etc/group | awk -F: '{printf "%5d\t%s\n", $3, $1}' | sort -k 1n

Maybe 300 is a good user id, and 80 is a good group id? Or 300 for both? Looks like apt creates tomcat user and group, so what I did is install it, uninstall it, then modify the user/group as follows, then re-install it.

sudo groupmod -g 300 tomcat
sudo usermod -u 300 -g 300 tomcat

2.6 DONE Creating and mounting an Elastic Block Store volume from an existing snapshot (2023)

I snapshotted the root drive (apparently, that was the only EBS volume I had attached to the old instance).

Looks like the general advice seems to be to have an "o/s" (a.k.a. "root") sort of volume and a "user" sort of volume, so when the o/s needs a big upgrade (e.g., 16 –> 22), you can just spin up a new VM w/the new o/s, and attach the previous "user" volume at the same mount point and be in business. Hopefully.

Since I wound up creating a t4g instance (ARM chip), I just installed Apache Corretto using apt, and it wound up on the "o/s" drive. I think the decision procedure should be: if there's an apt package, go ahead and run it; but if there's not and the install starts by extracting files to some arbitrary path, put that stuff on the user/data drive.

Amazon's best practice recommendations are here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-best-practices.html.

Even if I do this, it won't be a simple drop-in situation when I create a new VM and attach the volume because user and group ids may change across instances (e.g., "tomcat9" and "sysport" may wind up with different user and group ids). So we'll need to find a way to create these ids with constant values. See Creating fixed user and group ids (2023).


Looks like I originally created it as a gp2 type, but now I think maybe a gp3 type would be better. Can't really tell; I think the EBS volumes show up under "EC2-Other", so who knows?

2.6.1 How to mount a new volume

2.6.1.1 First, find it after attaching

(Note that "attaching" is not the same as "mounting".)

Ok, I created it, and attached it, but I don't see it. It's supposed to be attached as /dev/sdf or /dev/xvdf, I think.

Note that the root volume is supposed to be /dev/sda1.

findmnt shows / is the mount point for /dev/nvme0n1p1, with filesystem type of ext4. I don't see any other ext4 devices mounted.

https://aws.amazon.com/blogs/compute/how-to-mount-linux-volume-and-keep-mount-point-consistency/

ssh to the machine and…

lsblk

Aha, there it is, nvme1n1 with one partition (nvme1n1p1).

t3 and, I guess, t4g, systems use NVMe block devices built on Nitro. When googling NVMe, StackOverflow has a hit that says the data goes away when the instance is stopped (not just terminated), but this is discussing instance stores, not EBS volumes. Here's Amazon's documentation on EBS and NVMe: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html.

findmnt (mount being obsolete now) tells me that nvme0n1p1, the main partition on the volume created with this snapshot, is mounted on /. (There's another partition, nvme0n1p15, that appears to be a 99 MB boot partition.)

2.6.1.2 Mount it

So, we just need to mount the new volume somewhere, I think.

sudo file -s /dev/nvme1n1p1 reports to me, if I'm reading the output correctly

/dev/nvme1n1p1: Linux rev 1.0 ext4 filesystem data, UUID=45131f33-7efa-487c-a104-839d87a3f3ea, volume name "cloudimg-rootfs" (extents) (large files) (huge files)

that this volume has an ext4 filesystem on it (as opposed to just being a blank volume ready for formatting).

blkid -o export /dev/nvme1n1p1 yields the following (note that we're querying the partition):

DEVNAME=/dev/nvme1n1p1
LABEL=cloudimg-rootfs
UUID=45131f33-7efa-487c-a104-839d87a3f3ea
BLOCK_SIZE=4096
TYPE=ext4

The UUID will be constant for this volume.

Important note:

Current /etc/fstab contains the following:

LABEL=cloudimg-rootfs   /        ext4   discard,errors=remount-ro       0 1
LABEL=UEFI      /boot/efi       vfat    umask=0077      0 1

Note that the current root volume has a label of cloudimg-rootfs, which is the same as the volume we want to attach. That will cause a name collision if we modify fstab to mount them both at boot time, so I think we need to change the spec for the root volume to go by UUID, not label.

findmnt reports the root partition mounted with the following options: rw,relatime,discard,errors=remount-ro.

I think we can use the same options for the new volume. So, new line added to /etc/fstab:

UUID=45131f33-7efa-487c-a104-839d87a3f3ea       /mnt/1  ext4    discard,errors=remount-ro       0 2

…and it works! (So far.)

Next steps are to install Corretto, tomcat and jspwiki, probably on the additional volume. Old wiki pages will be found at /mnt/1/usr/share/jspwiki. See jspwiki-custom-properties – Configuration of various filepaths on host system.

3 Server Updates

yum update

4 General Admin

If your tiny 8 GB default disk drive on your Amazon EC2 instance is filling up with linux headers (in /usr/src) and images (in /lib), you should be able to remove them with sudo apt-get autoremove (unless things have gotten real bad).

Also, use ncdu to see what's taking up so much space.

4.1 Connecting with SSH

Log on to your AWS console, and go to your EC2 instance. Hit "Connect". You'll get instructions on how to connect using a standalone SSH client.

You'll need to specify the location of your private key (*.pem) file properly, plus the IP address of your instance, but it'll work.

Pretty sure I documented elsewhere that you do need to download that .pem file and save it.

5 App Development

5.1 Git

5.1.1 Global setup

Files:

  • /etc/gitconfig – Doesn't seem to be present on my windows/cygwin system.
  • ~/.gitconfig
  • .git/config – Per-repo/per-repo-subdir-specific config.

Commands:

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
git config --list

git uses the last value that it sees

5.1.2 Initialize local repository

Two choices: from scratch or by cloning a remote repository.

5.1.2.1 From scratch (including first local commit)

In top directory of project:

git init
git add <already-existing-file>
git commit
5.1.2.2 Clone remote repo
git clone git://github.com/schacon/grit.git
git clone user@server:/path.git # Uses SSH

Clones into current local directory. Without further arguments, names remote repo "origin" and local branch "master".

5.1.3 Initialize remote repository

Do it on http://github.com.

5.1.4 Link existing remote repo to existing local repo

git remote add origin https://github.com/JohnL4/rc.git
git pull                        # Looks like there's no other way to do this.

5.1.5 Subsequent local checkins

git status                      # Get status
git add <file>                  # Stage changes
git commit
5.1.5.1 .gitignore

Quoting from http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository:

The rules for the patterns you can put in the .gitignore file are as follows:

  • Blank lines or lines starting with # are ignored.
  • Standard glob patterns work.
  • You can end patterns with a forward slash (/) to specify a directory.
  • You can negate a pattern by starting it with an exclamation point (!).

Glob patterns are like simplified regular expressions that shells use. An asterisk (*) matches zero or more characters; [abc] matches any character inside the brackets (in this case a, b, or c); a question mark (?) matches a single character; and brackets enclosing characters separated by a hyphen([0-9]) matches any character in the range (in this case 0 through 9) .

Here is another example .gitignore file:

# a comment - this is ignored
# no .a files
*.a
# but do track lib.a, even though you're ignoring .a files above
!lib.a
# only ignore the root TODO file, not subdir/TODO
/TODO
# ignore all files in the build/ directory
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .txt files in the doc/ directory
doc/**/*.txt

Also:

Another useful thing you may want to do is to keep the file in your working tree but remove it from your staging area. In other words, you may want to keep the file on your hard drive but not have Git track it anymore. This is particularly useful if you forgot to add something to your .gitignore file and accidentally staged it, like a large log file or a bunch of .a compiled files. To do this, use the –cached option:

git rm --cached readme.txt

5.1.6 Push from local repository to remote repository

Push from local "master" branch to remote "origin" repo:

git push

5.1.7 Pull from remote repository to local repository

Pull from remote repository (default "origin") into local repository and then merges from local repo into current working branch (default "master"?):

git pull

Only pull to local repository, no get/merge into local working branch directory:

git fetch

5.2 Maven

5.3 Eclipse

5.3.1 Setup

5.3.1.1 Wildfly

If working w/JBoss (WildFly), you'll need to install some tools from RedHat. It looks like Eclipse comes with JBoss software sites pre-configured, but I recall having done something to install WildFly tools. Try Window | Preferences | Server | Runtime Environments | Add | Download Additional Server Adapters (a link), and go from there.

5.3.1.2 JDKs and JREs

Window | Preferences | Java | Installed JREs

Let Eclipse search for JREs, rather than try to configure them yourself. Restrict the search to directories where you know you have good JREs (e.g., c:\Java\jdk1.7.0_45).

5.3.1.3 Web Servers

Window | Preferences | Server | Runtime Environments

Again, let Eclipse search for WildFly (after you install it), starting with a known directory (e.g., c:\usr\local\wildfly-8.0.0.Beta1). Associate the server with a JDK JRE (which should have been found in the previous search (in JDKs and JREs).

5.3.1.4 Maven

As far as the JBoss Quickstarts are concerned, I don't advise importing the existing projects into Eclipse if you can't make them work from the command line. Instead, just import the source artifacts (beans.xml, maybe web.xml, static web content, dynamic (Java) web content, etc.) Then you can select "Run On Server", pick the Wildfly server you set up in Wildfly, and be off to the races. Hopefully.

5.4 JBoss

5.4.1 Stupid JBoss tips

5.4.1.1 Directory permissions

If you install to a directory not generally-writable, be sure to run your various admin batch files as Administrator. Or chown the directory (recursively) to the userid you'll be running the server as.

5.4.1.2 Shutting down a JBoss instance
{JBOSS_HOME}/bin/jboss-cli.sh --connect command=:shutdown

(Worked for me, Windows 7, Wildfly 8.0 beta1, cygwin)

5.5 General Java/Javascript web app development

5.5.1 Java

5.5.1.1 DONE CDI – Context and Dependency Injection
  • CLOSING NOTE [2013-12-05 Thu 20:51]

(See JBoss helloworld quickstart.)

This is basically how to hook up your business-logic classes and servlets w/out going through reams of configuration.

The CDI spec basically says that every injection point (@Inject) is satisfied by exactly one class or there's an error.

  • [X]

    The type of the injection point is exactly the same as the type of the class (there's some noise about raw types and parameterized types and types of type parameters, but… bascially identical types), or (See section 4.3 ("Specialization") of the JSR-299 CDI spec) a specializing (subclassing) bean can use the @Specializes annotation to indicate to the container that it's specializing another bean (e.g., a mock bean can specialize the intended production bean).

    However, don't specialize decorators or interceptors. The spec says, "If an interceptor or decorator is annotated @Specializes, non-portable behavior results." I think this means they wash their hands of the matter.

  • [X] Do injectable beans have a default annotation of @Default? (injection points do, unless you give another annotation.) Yes, if they don't declare a qualifier. See Section 2.3.1. ("Built-in qualifier types") of the JSR-299 CDI spec.
5.5.1.2 IN-PROGRESS JSF

JSR-344.

5.5.2 Javascript (GWT, Angular, etc.)

Created: 2025-02-19 Wed 15:31

Emacs 27.2 (Org mode 9.4.4)

Validate