Just completed the AngularJS implementation of Tic Tac Toe.
It is a static page on this site (just like the Lot Area Calculator).
Just completed the AngularJS implementation of Tic Tac Toe.
It is a static page on this site (just like the Lot Area Calculator).
This shows the way to get gradle to use a local Archiva server to publish your project artifacts.
IMPORTANT: You must configure your “guest” user in Archiva to have the correct permissions (roles) to publish to the Archiva server. To do this, in the Archiva WebUI (the default is http://localhost:8080), on the left side under “USERS”, click “Manage”, then click the blue pencil next to “guest”, then click the “Edit Roles” (next to the blue “Edit” button), then checkbox select “Global Repository Manager” and “Global Repository Observer” and press Update.
Interesting fact: Archiva will accept “SNAPSHOT” artifacts into its “internal” repository (i.e. the upload will succeed, and Archiva will store the artifacts in its “/repositories/internal/” directory). BUT it will not serve these artifacts, saying instead “managed repo is configured for release only”. If you accidentally publish SNAPSHOT artifacts to the “internal” repository, then you’ll have to clean your “/repositories/internal/” directory by hand – the WebUI won’t let you.
So, given that interesting fact, the “if” logic (below) looks for “SNAPSHOT” and sets the url to the correct location. Note that the single “maven { }” entry is different from how it was configured for resolving, where there were two entries. (See Gradle with Local Archiva).
This shows the correct ‘publishing’ section of your build.gradle file for publishing to your local Archiva server. This also shows how to publish your “-sources” artifact. Feel free to substitute “localhost” for the actual machine name or IP address of your Archiva server.
(2014/6/10 update: added ext.isReleaseVersion and added checks before using the .publishBaseUrl property before using it.)
Versions:
archiva: 2.0.1
gradle: 1.11
// Used in publishing - the new plugin: apply plugin: 'maven-publish' // Used in publishing - pom information: group = 'com.tiemens' version = '0.1-SNAPSHOT' project.ext.isReleaseVersion = !version.endsWith("SNAPSHOT") // Used in publishing - source artifact: task sourceJar(type: Jar) { from sourceSets.main.allJava } publishing { publications { mavenJava(MavenPublication) { from components.java artifact sourceJar { classifier "sources" } } } repositories { maven { if (project.hasProperty('publishBaseUrl')) { if (! project.ext.isReleaseVersion) { url project.publishBaseUrl + "/snapshots" } else { url project.publishBaseUrl + "/internal" } } else { // this is a notice that 'publish' requires .publishBaseUrl url "http://you.must.configure.project.publishBaseUrl" } } } }
Just for documentation, this shows the error message you get if you don’t set up your guest user with the proper roles.
$ gradle --debug publish
... snip ...
17:09:38.693 [DEBUG] [sun.net.www.protocol.http.HttpURLConnection] sun.net.www.MessageHeader@19507226 pairs: {PUT /repository/snapshots/com/tiemens/CardWar/0.5-SNAPSHOT/CardWar-0.5-20140421.220938-1.jar HTTP/1.1: null}{User-Agent: maven-artifact/3.0.4 (Java 1.7.0_45; Linux 3.2.0-31-generic-pae)}{Host: sitearchiva:8080}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}{Content-Length: 21915}
17:09:38.703 [DEBUG] [sun.net.www.protocol.http.HttpURLConnection] sun.net.www.MessageHeader@10775136 pairs: {null: HTTP/1.1 401 Unauthorized}{Date: Mon, 21 Apr 2014 22:09:38 GMT}{Set-Cookie: JSESSIONID=11ohtcvqtpqu3s9r3iis2a7c1;Path=/}{WWW-Authenticate: Basic realm="Repository Archiva Managed snapshots Repository"}{Content-Length: 0}{Server: Jetty(8.1.14.v20131031)}
17:09:38.737 [INFO] [org.gradle.api.internal.project.ant.AntLoggingAdapter] [ant:null] An error has occurred while processing the Maven artifact tasks.
Diagnosis:
Error deploying artifact 'com.tiemens:CardWar:jar': Error deploying artifact: Failed to transfer file: http://sitearchiva:8080/repository/snapshots/com/tiemens/CardWar/0.5-SNAPSHOT/CardWar-0.5-20140421.220938-1.jar. Return code is: 401
...snip...
More documentation links:
Shows example using authentication, instead of using “guest” with publish role:
http://forums.gradle.org/gradle/topics/maven_publish_and_setting_snapshotrepository_and_releaserepository
This shows the way to get gradle to use a local Archiva server to resolve dependencies (where the Archiva server in turn resolves to maven central).
(Side comment: documentation for gradle is sparse, incomplete and out-of-date – e.g. ‘mavenRepo’ shows up in many searches.)
So, if you’re interested in how to use a local Apache Archiva server in your environment, then this shows the correct ‘repositories’ section of your build.gradle file. In an upcoming post, I’ll document how to publish to your local Archiva server. Feel free to substitute “localhost” for the actual machine name or IP address of your Archiva server.
Versions:
archiva: 2.0.1
gradle: 1.10
repositories { maven { url 'http://localhost:8080/repository/internal' } maven { url 'http://localhost:8080/repository/snapshots' } // if your Archiva is set up correctly, // then you don't need mavenCentral() here: // mavenCentral() }
Just for documentation, this shows the “dependencies” section of the build.gradle file. If your Archiva is set up correctly, these 3 dependencies will actually download/store 8 .jar files (because of transitive dependencies).
dependencies { testCompile group: 'info.cukes', name: 'cucumber-java', version: '1.1.5' testCompile group: 'info.cukes', name: 'cucumber-junit', version: '1.1.5' testCompile group: 'junit', name: 'junit', version: '4+' }
Files that end up in your apache-archiva/repositories directory (showing just the .jar files):
apache-archiva-2.0.1/repositories/internal/junit/junit/4.11/junit-4.11.jar apache-archiva-2.0.1/repositories/internal/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar apache-archiva-2.0.1/repositories/internal/info/cukes/cucumber-html/0.2.3/cucumber-html-0.2.3.jar apache-archiva-2.0.1/repositories/internal/info/cukes/cucumber-java/1.1.5/cucumber-java-1.1.5.jar apache-archiva-2.0.1/repositories/internal/info/cukes/gherkin/2.12.1/gherkin-2.12.1.jar apache-archiva-2.0.1/repositories/internal/info/cukes/cucumber-junit/1.1.5/cucumber-junit-1.1.5.jar apache-archiva-2.0.1/repositories/internal/info/cukes/cucumber-jvm-deps/1.0.3/cucumber-jvm-deps-1.0.3.jar apache-archiva-2.0.1/repositories/internal/info/cukes/cucumber-core/1.1.5/cucumber-core-1.1.5.jar
Documentation – The good stuff:
http://www.gradle.org/docs/1.8-rc-1/release-notes.html — shows the change from mavenRepo to maven.
http://gradleproject.wordpress.com/2013/02/14/multiple-maven-repositories-in-gradle/ – now NOT to set up your repositories entry.
More Documentation – The list of things that don’t work:
http://gradle.1045684.n5.nabble.com/using-Archiva-maven-repo-w-Gradle-td4579298.html
http://joshdiehl.com/2011/07/11/using-apache-archiva-with-gradle/
Want something other than 640×480 with Ubuntu running in VirtualBox 4.3.x?
Follow these instructions.
From http://codsplaice.blogspot.com/2014/02/a-quick-post-on-how-to-get-ubuntu-1404.html
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install linux-headers-$(uname -r)
sudo apt-get install dkms build-essential
Then mount the install CD image for the Virtualbox tools and install them.
cd /media/$(id -nu)/VBOXADDITIONS*
sudo ./VBoxLinuxAdditions.run
Finally install the virtualbox-guest-x11 package.
sudo apt-get install virtualbox-guest-x11
To enable remote desktop in Ubuntu when “Settings” no longer shows the icon for “Desktop Sharing” or “Remote Desktop”, type:
$ vino-preferences
When your VNC client fails to connect with an error like “No matching security types” or “No security type suitable for RFB 3.3 supported” (or if you see a log line from vino-server like “Advertising security type 18”) then type:
$ gsettings set org.gnome.Vino require-encryption false
Then try to connect again.
For automatic provisioning that installs the official Oracle Java package, many paths lead to WebUpd8Team/java PPA and www.webupd8.org.
Currently, the apt-get-install oracle-java7-installer
command will fail, leaving a file at /var/cache/oracle-jdk7-installer/jdk-7u51-linux-*.tar.gz
that is a plain .html file that contains “Sorry! In order to download products from Oracle Technology Network you must agree to the OTN license terms”
Nothing I’ve tried will appease the Oracle license police.
Instead, my current “provision Java” script uses version “8” – as in “oracle-java8-installer
“, which is working.
So, if you have the luxury of using java8 instead of java7, you can just update your provisioning scripts. My current script (because I’m tired of searching for the instructions) is below.
Run these commands as root:
# we need this to avoid weird "IP not found" errors:
apt-get update
# if you need to get 'add-apt-repository', you need python-software-properties
#uncomment# yes | apt-get install python-software-properties
yes | add-apt-repository ppa:webupd8team/java
apt-get update
# there is a manual license screen here:
apt-get install oracle-java8-installer
I’ve always enjoyed finding bugs in languages. I still fondly recall finding a bug in Perl concerning the “while () { .. }
” construct and file names that evaluate to ‘false’, like a file named “0”, for example.
More recently, I discovered a Groovy bug in groovy.lang.SpreadMap
class (and therefore in the List.toSpreadMap() implementation). I’ve reported it (GROOVY-6403) and submitted a patch with a unit test.
Some observations:
The original example, with some additional (failing) asserts:
#!/usr/bin/env groovy def list = ['key', 'value', 'name', 'tim'] as Object[] def map = list.toSpreadMap() assert 2 == map.size() // ok assert 'value' == map.key // ok assert true == map.containsKey('key') // FAIL assert false == map.isEmpty() // FAIL assert 2 == map.keySet().size() // FAIL
Back to the Perl bug
For these code snippets, place files named “0”, “1” and “2” in the current directory. Perl 5 was used for this testing.
The one will print “File is 0”, “File is 1” and “File is 2”, but also prints “How did we get here if 0 is not true?” [In earlier versions of Perl, this would not print anything if the first file found was “0”. They’ve changed that. But, see the next example.]
#!/usr/bin/env perl while ($file = ) { print "File is $file\n"; if (! $file) { print "Huh? How did we get here if $file is not true?\n"; } }
This one just won’t print anything, since “0” is the first file it sees, and that evaluates to ‘false’. The extra variable assignment causes the hack fix to fail:
#!/usr/bin/env perl my $inside; my $file; while ($file = ($inside = )) { print "File is $file\n"; }
P.S. In case it is not obvious, do not use either of these constructs. In summary:
Some facts on the CPU: it is currently #24 on PassMark [10,121] cpubenchmark.net. Ahead of it are the Xeon E5-2xxx, the AMD FX-9590, and a few Core i7s (48xxK, 49xxK and 39xxK). A short while ago the 4770K was #17 and selling for ~$350.
The case was an Amazon lightning deal from November, 2012.
The CPU+Motherboard was supposed to be a combination deal for $420, but it ended up $445 because Microcenter is not fully competent. Even on the website, adding the $420 deal to cart ends up as $430. I only noticed that after I had made my in-store purchase.
The video card has a $25 rebate, not counted, since Gigabyte is not very good at fulfilling rebates. The card was installed later, so I’m able to report that the Intel HD Graphics 4000 produces a “Windows Experience” of 6.8/7.9. Not too shabby for built-in graphics. With the video card, this system scores a 7.8/7.9 – the “oh, so close” system. What was the 7.8? The CPU! I assume I could overclock it up to 7.9, but I would never leave it there.
All product links are from the actual vendor.
Item | Product | Cost |
---|---|---|
CPU | Intel Core i7 4770K 3.5Ghz (3.9GHz Turbo) Socket 1150 84W Four-Core Desktop | $300 |
RAM | G.SKILL Ripjaws 16GB (2 x 8GB) 240-Pin DDR3 SDRAM DDR3 2400 Desktop Memory Model F3-2400C11D-16GXM | $130 |
Motherboard | Gigabyte GZ-Z87X-UD4H LGA 1150 HDMI USB 3.0 | $176 |
Power Supply | Corsair Enthusiast TX650 Bronze certified | $65 |
Video | Gigabyte Radeon HD 7950 3GB 384-bit GDDR5 PCI Express 3.0 DVI/HDMI/DisplayPort Graphics Card, GV-R795WF3-3GD | $225 |
Case | Corsair Carbide 300R Mid Tower Case (Black) CC-9011014-WW | $55 |
SD Drive | Samsung 840 Pro 256GB SATA 6GB/s MZ-7PD256BW | $224 |
HD Drive | Western Digital 1TB Caviar Black WD1002FAEX | $85 |
BD/DVD/CD | Samsung Optical Drive SH-224DB/BEBE | $21 |
Keyboard | – | – |
OS | Windows 7 Professional SP1 64bit | $124 |
Total | – | $1405 |
WiFi | TP-LINK TL-WDN4800 N900 Wireless Dual Band PCI Express Adapter | $32 |
Ever wonder what the big Amazon instances would cost if you bought one (instead of rented)? Here is an attempt to answer that question. Note: Amazon EC2 provides more than just the hardware (e.g. network connectivity and bandwidth, for starters), so this isn’t quite an apples-to-apples comparison.
From the Amazon page, the short specifications are: 2 x Intel Xeon E5-2670 processors, 244 GiB RAM, 2x120GB SSD, 10GB Ethernet. Those CPUs provide 8 cores times hyper-threading each, for a total of 2x8x2 = 32 vCPUs and 88 ECUs.
According to Amazon prices in 2013, this virtual machine will cost you $3.50/hour for on-demand, which is $30,660 per year. (See “High-Memory Cluster On-Demand Instances, Eight Extra Large”).
So, of that $30,660 per year, what are the hardware costs?
Note that with “only” 16 memory slots, it needs 16GB sticks of ECC REG to achieve 256GB.
Note that the CPU does not come with coolers. I’ve never heard of the Dynatron brand, but it was one of the few “low height” fan/cooler combinations I could find. It is ridiculous to think of risking a $1,600 CPU like that. That detail is what prompted me to look at the “custom-build” shops – since they would have more experience in this critical area.
Here are a few custom-build shop prices, for comparison:
Caution: Unlike the other postings of mine, this is NOT a built machine. And, at $7,000+, it probably never will be built by me. It is pure “by the specifications” intellectual exercise. It should work, but all of my others builds actually work.
So – here is the machine I’ll build after winning the lottery:
Item | Product | Cost |
---|---|---|
CPU | Intel Xeon E5-2670 Sandy Bridge-EP 2.6GHz 3.3GHz Turbo Boost) 20MB L3 Cache LGA 2011 115W 8-Core Server Processor BX80621E52670, $1,599 each | $3,200 |
RAM | Kingston 64GB (4 x 16GB) 240-Pin DDR3 SDRAM ECC Registered DDR3 1600 Server Memory DR x4 Model KVR16R11D4K4/64, $656 each | $2,624 |
Motherboard | Dual LGA 2011 Intel C602 DDR3 1600 (with case) | – |
Power Supply | 740W (1+1) Redundant (with case) | – |
Video | (built in) | – |
Case | SUPERMICRO SYS-6027R-WRF 2U Rackmount Server Barebone Dual LGA 2011 Intel C602 | $1,199 |
SD Drives | SAMSUNG 840 Pro Series 128GB MZ-7PD128BW 2.5″ 128GB SATA III MLC Internal Solid State Drive (SSD), $140 each | $280 |
HD Drives | – | |
NIC | ntel E10G41AT2 AT2 Server Adapter 10Gbps PCI Express 2.0 x8 1 x RJ45 | $515 |
CPU Cooler | Dynatron R13 70mm 2 Ball Bearing CPU Cooler , $30 each | $60 |
OS | Ubuntu 12.04p2 LTS | $0 |
Total | – | $7,878 |
Ever wondered what an Amazon ECU is worth in terms of a PassMark-CPU Mark value? (see cpubenchmark.net for PassMark scores). One way to calculate the PassMark per ECU value comes directly from Amazon’s information where they describe the hardware behind some of their instance types. Two examples are (1) cr1.8xlarge listed as “2 x Intel Xeon E5-2670 processors” as “88 ECUs” and (2) cg1.4xlarge listed as “2 x Intel Xeon X5570” as “33.5 ECUs”.
Note: There is a separate multi-CPU PassMark page. It seems it is fair to use both the multi-CPU rating and to just times-by-two the single-CPU, so I’ll show both.
We can now compute PassMark per ECU value:
cr1.8xlarge | cr1.8xlarge | cg1.4xlarge | cg1.4xlarge | |
PassMark | 2×13,312 = 26,624 |
19,194 | 2×5,027 = 10,054 |
9,782 |
ECU | 88 | 88 | 33.5 | 33.5 |
PassMark/ECU | 302.5 | 218.1 | 300.1 | 292.0 |
This means an ECU is roughly equivalent to a 300 PassMark score.
Other pages have reported similar numbers: 400 and 384 and 400 and 400. [It is hard to tell how many of those “400”s are just copies from a single source.]
This topic became interesting when trying to troubleshoot performance “problems” of various EC2 m1.large instances. Knowing that an m1.large has 4 ECUs, and an ECU is worth 400 PassMarks [I’ll be generous], that gives a PassMark equivalent of 1,600. Looking at cpubenchmark.net, I (somewhat arbitrarily) picked the Intel Core2 Duo P8700@2.53GHz with a PassMark score of 1,674, and cross-referenced that CPU on wikipedia.org core2 microprocessors to arrive at a December 2008 date.
So: if you are noticing performance problems with your Amazon EC2 m1.large, it is because you are using a device with the equivalent power of a computer from 2009. Your m1.large has an generous amount of RAM (8GB), but its processing power is terrible.
Miscellaneous reference: nice ec2 instance comparison page.