Jordo Media RSS Feed Directory

Toggle Content Main Menu

Toggle Content User Info

Welcome Anonymous

(Register)

Toggle Content Top Ranked Feeds

Toggle Content Random Feeds

View the feed - Pandemonium Medicine Show

Jordo Media RSS / Atom Feed Directory

[ Directory - Main | Tags | Submit Feeds | New | Popular | Top Rated | Editor's Picks | Random ]

There are 44,721 Feeds and 130 Categories in our database


Main - Uncategorized - Feeds that are not yet Categorized - Pandemonium Medicine Show

[Comments | Print RSS/Atom Feed Printer Friendly Page | Email RSS/Atom Feed Send to a Friend | Is this your feed/content? | Feature this Feed ]

Title:

Pandemonium Medicine Show

Site URL:http://blogs.sun.com/bondolo/
Feed URL:http://blogs.sun.com/bondolo/feed/entries/rss  Pandemonium Medicine Show Feed
Subscribe: Subscribe to this feed Add to My Yahoo! Add to Google Add to MSN
Description:Weblog of Mike Duigou aka bondolo
Tags: None  [ Add Tags | What are Tags? ]
Feed Last Updated:Thu, 12 Nov 2009 10:03:48 -0800
Added on:26-Feb-2006 
Hits:12
Rating:N/A (0 votes) [ Rate this RSS/Atom Feed ]
Jordo Media is displaying this feed so that you can decide if you wish to subscribe to it or not. We are neither affiliated with the authors of this feed nor responsible for its content.
Please report inappropriate content to via the "Report Problem" link above.



Video of Shelley - Thu, 12 Nov 2009 10:03:48 -0800
The photo of Shelley in my last post was just a taste. Here's more!

This footage was taken primarily at the Bonneville salt flats in September. Notice at the end of the salt flats segment how she has drifted out the Audi logo at 95 KM/H. There's probably not very many human drivers who could drive with this accuracy. With more time Shelley could just as easily drift out a picture of Duke, the Java logo or the Mona Lisa... try that puny human!


Fastest Hardware I Have Ever Worked On! - Mon, 9 Nov 2009 21:22:06 -0800

Image of 'Shelley', an autonomous Audi TTS on the Bonneville Salt Flats at Sunset

Photo credit: Marcial Hernandez

Probably not what you thought you'd be seeing when you came to this page!

"Shelley" is the newest VW ERL test vehicle and will be conquering Pike's Peak in 2011. Yes, that's a Java logo and she is indeed "Java Powered"! Shelley will be using Java Realtime and Solaris for her driving control, GPS integration, telemetry logging and portions of her safety system.

My part, thus far, has been to provide a Solaris CAN bus driver. Which I, unfortunately, had to write in C.


Updated Java Store LRM Sample - Mon, 19 Oct 2009 18:11:35 -0700

As Octavian mentioned in his recent blog entry, Java Store and License Management, the Java Store will soon offer a simple license rights management system to developers. Octavain's post was based upon early work and, because there have been questions about it, I'm posting updated sample source code for the license management feature. Enjoy!

Java Store License Rights Management Sample
package com.sun.javastore.licenserightsapp;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

/**
 * A sample application demonstrating how to decode and verify the Java Store licensing rights object. This
 * sample shows the rights code executing within the {@code main()} method that normally starts your
 * application. In a real application you should move this code to wherever your application decides which
 * functions are available.  Note: An application can be run in demo/preview mode, in which case, none of
 * the rights objects are to be set, which is an indicator to the application that it is being run in such
 * mode.
 *
 * You may wish to use several copies of the code in different places in your
 * application to check for different rights. You should try to avoid using a pattern like :
 *
 *  
 *  public boolean featureUnlocked() {
 *     ... rights handling code ...
 *  }
 * 
* * as this is quite simple to replace with a method that simply returns "true" all the time. The more * you spread out the rights processing and checking within your code the harder it will be for attackers * to disable it. */ public class App { /** * The public key which must match the key which was used for signing the rights object. */ private final static byte[] TRUSTED_PUBLIC_KEY = { (byte) 0x30, (byte) 0x81, (byte) 0x9F, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8D, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x98, (byte) 0x21, (byte) 0xAE, (byte) 0x6C, (byte) 0x80, (byte) 0x97, (byte) 0x6F, (byte) 0xDE, (byte) 0xAD, (byte) 0xC4, (byte) 0x59, (byte) 0x44, (byte) 0x57, (byte) 0xCC, (byte) 0x3D, (byte) 0x7E, (byte) 0x48, (byte) 0x7B, (byte) 0xE2, (byte) 0xEE, (byte) 0xB2, (byte) 0xA3, (byte) 0xF7, (byte) 0x53, (byte) 0x03, (byte) 0x12, (byte) 0x07, (byte) 0x60, (byte) 0x3D, (byte) 0x5E, (byte) 0x5D, (byte) 0xEF, (byte) 0x89, (byte) 0xAF, (byte) 0xA4, (byte) 0x6E, (byte) 0x85, (byte) 0xE3, (byte) 0xB8, (byte) 0xD1, (byte) 0xF1, (byte) 0x4D, (byte) 0x8C, (byte) 0x8C, (byte) 0x10, (byte) 0xE5, (byte) 0x1A, (byte) 0x6F, (byte) 0x70, (byte) 0xE8, (byte) 0xAD, (byte) 0x54, (byte) 0x96, (byte) 0xB1, (byte) 0x61, (byte) 0xC5, (byte) 0xE5, (byte) 0x42, (byte) 0x83, (byte) 0x2B, (byte) 0xB2, (byte) 0xB1, (byte) 0x91, (byte) 0x6F, (byte) 0xB0, (byte) 0xFE, (byte) 0x0D, (byte) 0xAF, (byte) 0x60, (byte) 0xA9, (byte) 0xD5, (byte) 0x64, (byte) 0x82, (byte) 0x8F, (byte) 0x1F, (byte) 0xE5, (byte) 0x47, (byte) 0x45, (byte) 0x76, (byte) 0x00, (byte) 0xC1, (byte) 0x43, (byte) 0x29, (byte) 0x10, (byte) 0x33, (byte) 0x52, (byte) 0x49, (byte) 0x53, (byte) 0x0E, (byte) 0xC8, (byte) 0xD2, (byte) 0x98, (byte) 0x17, (byte) 0x7F, (byte) 0x6E, (byte) 0x8F, (byte) 0x41, (byte) 0x1C, (byte) 0xF6, (byte) 0xE4, (byte) 0x6F, (byte) 0x84, (byte) 0x1C, (byte) 0x39, (byte) 0xA7, (byte) 0x17, (byte) 0x8A, (byte) 0x31, (byte) 0x1A, (byte) 0x90, (byte) 0xD0, (byte) 0xA8, (byte) 0x44, (byte) 0x84, (byte) 0x73, (byte) 0x01, (byte) 0x1F, (byte) 0x51, (byte) 0x19, (byte) 0x43, (byte) 0x35, (byte) 0x2D, (byte) 0x3D, (byte) 0xC6, (byte) 0x2B, (byte) 0x68, (byte) 0x7C, (byte) 0x4F, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01 }; /** * Name of the property containing the encoded rights for this user/device/application. (BASE64) */ private final static String RIGHTS_BLOB_PROPERTY = "jnlp.javastore.appwrapper.rightsBlob"; /** * Name of the property containing the digital signature of the encoded rights object. (BASE64) */ private final static String RIGHTS_SIGNATURE_PROPERTY = "jnlp.javastore.appwrapper.rightsSig"; /** * Name of the property containing certificate of the signer of the encoded rights object. (BASE64) */ private final static String RIGHTS_CERTIFICATE_PROPERTY = "jnlp.javastore.appwrapper.rightsCert"; /** * The ID of the user running the application as provided by the Java Store wrapper. */ private final static String RIGHTS_USER_ID = "jnlp.javastore.appwrapper.UserID"; /** * The Product ID of this application as provided by the Java Store wrapper. */ private final static String RIGHTS_PRODUCT_ID = "jnlp.javastore.appwrapper.ProductID"; /** * The Version ID of this application as provided by the Java Store wrapper. */ private final static String RIGHTS_VERSION_ID = "jnlp.javastore.appwrapper.VersionID"; /** * The system fingerprint for this system as provided by the Java Store wrapper. */ private final static String RIGHTS_SYSTEM_ID = "jnlp.javastore.appwrapper.SystemID"; /** * Clock drift window. This is padding we add in time/date calculations to allow for differences between * the user's clock and the Java Store clock. */ private final static long MAX_CLOCK_DRIFT_WINDOW_MS = /*1sec*/ 1000L * /*1min*/ 60L * /*1hr*/ 60L * /*1/2day*/ 12L; /** * The basic right for purchased applications. If this right is absent or unavailable then the application * is in demo mode. */ private final static String BASIC_PURCHASED_RIGHT = "store:run"; /** * Main entry point. * * @param args command line arguments (if any). */ public static void main(String[] args) { // We will decide if this application should be running in demo mode or not. boolean demoMode = true; try { // Get the current time. long now = System.currentTimeMillis(); // Recover rights info objects from system properties and decode BASE64 data. byte[] rightsBlob = decodeBase64(System.getProperty(RIGHTS_BLOB_PROPERTY, "")); byte[] rightsSig = decodeBase64(System.getProperty(RIGHTS_SIGNATURE_PROPERTY, "")); byte[] rightsCert = decodeBase64(System.getProperty(RIGHTS_CERTIFICATE_PROPERTY, "")); // Ensure that all of the rights info components are available. if (rightsBlob.length <= 0 && rightsSig.length <= 0 && rightsCert.length <= 0) { throw new IllegalArgumentException("Rights objects unavailable."); } // Read in the certificate of the signer. CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream( rightsCert)); // verify that the public key in the presented signer certificate matches the one know to trust. if (!Arrays.equals(TRUSTED_PUBLIC_KEY, certificate.getPublicKey().getEncoded())) { throw new IllegalArgumentException("Incorrect signer."); } // Verify the signature using the certificate against the rights info blob. Signature signature = Signature.getInstance("SHA1withRSA"); signature.initVerify(certificate); signature.update(rightsBlob); if (!signature.verify(rightsSig)) { throw new IllegalArgumentException("Signature doesn't match."); } // We can now trust that the rights info blob is authentic. // The rest of the processing is devoted to using the rights info. // Read a Properties map from the rights info blob. Properties rights = new Properties(); rights.load(new ByteArrayInputStream(rightsBlob)); // Extract some values from the properties map // The ID of the product to which the rights are applied. int productId = Integer.parseInt(rights.getProperty("productId", "-1")); rights.remove("productId"); // The ID of the user holding the rights. int userId = Integer.parseInt(rights.getProperty("userId", "-1")); rights.remove("userId"); int systemId = Integer.parseInt(rights.getProperty("systemId", "-1")); rights.remove("systemId"); // The ID of the device on which the application is running. String deviceId = rights.getProperty("deviceId", ""); rights.remove("deviceId"); // Timestamp at which this rights info was generated in milliseconds since Midnight Jan 1, 1970 UTC ("the epoch"). long timestamp = Long.parseLong(rights.getProperty("timestamp")); rights.remove("timestamp"); // Print out the core properties of the rights info. System.out.printf("product : %d user : %d system : %d device : '%s' timestamp : %s \n", productId, userId, systemId, deviceId, new Date(timestamp)); // Perform checks upon the properties. // The product ID must be a positive number. int appProductId = Integer.parseInt(System.getProperty(RIGHTS_PRODUCT_ID, "-99")); if (productId != appProductId) { throw new IllegalArgumentException("Invalid product Id"); } // Normally the userID is > 0. If the userID is -1 then this is a preview or demo and we should // not expect any rights. int currentUserId = Integer.parseInt(System.getProperty(RIGHTS_USER_ID, "-99")); if (userId != currentUserId) { throw new IllegalArgumentException("Invalid user Id"); } // The ID of the system on which the application is running. int currentSystemId = Integer.parseInt(System.getProperty(RIGHTS_SYSTEM_ID, "0")); if (systemId != currentSystemId) { throw new IllegalArgumentException("Non-matching system Id"); } // Device ID must be present. This is used to track how many devices the user is installing the // application on. if (0 == deviceId.trim().length()) { throw new IllegalArgumentException("Invalid device Id"); } // Compare timestamp to current time allowing for clock drift. if ((timestamp < 0) || (now - timestamp < -MAX_CLOCK_DRIFT_WINDOW_MS)) { throw new IllegalArgumentException("Invalid time stamp"); } if (!rights.isEmpty()) { System.out.println(); } // At this point all remaining keys in the rights map should be single right descriptors. if ((-1 == userId) && !rights.isEmpty()) { System.out.printf("*** Rights Info should be empty when in demo/preview mode.\n\n"); } // Print out properties for each right in the rights info. for (Map.Entry aRight : rights.entrySet()) { String key = aRight.getKey().toString(); String value = aRight.getValue().toString(); // Not a right entry. if (!key.startsWith("right.")) { System.out.printf("\t** Unexpected property ** :: key : '%s' value : '%s'\n", key, value); continue; } // Process a single right descriptor. Value is a BASE64 encoded property map. Properties right = new Properties(); right.load(new ByteArrayInputStream(decodeBase64(value))); // Read the properties for this right from the property map. // the name of the right (not unique) String name = right.getProperty("name"); // receipt id of the Java Store purchase transaction which acquired this right. (unique) int receiptId = Integer.parseInt(right.getProperty("receiptId")); // payment processor name. String paymentProcessor = right.getProperty("paymentProcessor"); // transaction id from the payment service (unique per payment procesor) String paymentTransactionId = right.getProperty("paymentTransactionId"); // if true then right is currently granted otherwise false (refunded, revoked, etc.) boolean isGranted = Boolean.parseBoolean(right.getProperty("isGranted", "false")); // timestamp in millis since epoch at which the right becomes (or beacame) active. Not present for perpetual rights. long activation = Long.parseLong(right.getProperty("activation", "-9223372036854775808")); // timestamp in millis since epoch at which the right expires. Not present for for perpetual rights. long expiration = Long.parseLong(right.getProperty("expiration", "9223372036854775807")); // Calculate whether this right is currently available. Application functionality for // absent and unavailable rights should be disabled. boolean available = isGranted && // must be granted. (now + MAX_CLOCK_DRIFT_WINDOW_MS >= activation) && // and activated. (now - MAX_CLOCK_DRIFT_WINDOW_MS < expiration) && // and not expired. (userId > 0) && // for a specific user (not preview or demo). (null != name); // and not null; // print out properties for this specific right. System.out.printf("\tright : '%s' receipt id : %d payment : %s '%s' granted: %b \n" + "\t\tTimestamps: %s (activation) %s (expiration)\n" + "\t\t==> %s\n", name, receiptId, paymentProcessor, paymentTransactionId, isGranted, (Long.MIN_VALUE == activation) ? "perpetual" : new Date(activation), (Long.MAX_VALUE == expiration) ? "perpetual" : new Date(expiration), available ? "available" : "unavailable"); // See if we should disable demo mode based upon this right. if (available && BASIC_PURCHASED_RIGHT.equals(name)) { demoMode = false; } } } catch (Exception failure) { System.err.println("Failure processing Java Store Licensing Rights"); failure.printStackTrace(System.err); throw new IllegalStateException("Invalid Java Store Licensing Rights", failure); } // Print out our decision about whether we are running in demo mode. System.out.printf("\nApplication is running in %s mode.\n", demoMode ? "demo" : "purchased"); } /** * Decodes a BASE64 string into a byte array. * * @param encodedBASE64 A BASE64 encoded string with optional whitespace. * @return the decoded bytes. */ private static byte[] decodeBase64(String encodedBASE64) { ByteArrayOutputStream bos = new ByteArrayOutputStream(encodedBASE64.length()); int index = 0; int values = 0; int charsToBytes = 0; int trailing = 0; while (index < encodedBASE64.length()) { char c = encodedBASE64.charAt(index++); int v; // 6 bits if ('A' <= c && c <= 'Z') { v = (c - 'A'); } else if ('a' <= c && c <= 'z') { v = (c - 'a') + 26; } else if ('0' <= c && c <= '9') { v = (c - '0') + 52; } else if (c == '+') { v = 62; } else if (c == '/') { v = 63; } else if (c == '=') { v = Integer.MAX_VALUE; } else if (Character.isWhitespace(c)) { continue; } else { throw new IllegalArgumentException("Bad character in input @ " + (index - 1)); } values <<= 6; charsToBytes++; if (Integer.MAX_VALUE != v) { if (0 != trailing) { throw new IllegalArgumentException("Bad character in input @ " + (index - 1)); } values |= v; } else { trailing++; if (trailing > 2) { throw new IllegalArgumentException("Bad character in input @ " + (index - 1)); } } if (0 == (charsToBytes % 4)) { bos.write((byte) (values >> 16)); if (trailing < 2) { bos.write((byte) (values >> 8)); } if (trailing < 1) { bos.write((byte) values); } values = 0; } } return bos.toByteArray(); } }

And a unit test which invokes the sample code.

Java Store License Rights Unit Test
package com.sun.javastore.licenserightsapp;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Unit test for simple App.
 */
public class AppTest
        extends TestCase {

    /**
     * Create the test case
     *
     * @param testName name of the test case
     */
    public AppTest(String testName) {
        super(testName);
    }

    /**
     * @return the suite of tests being tested
     */
    public static Test suite() {
        return new TestSuite(AppTest.class);
    }

    /**
     * Rigourous Test :-)
     */
    public void testApp() {
        String SAMPLE_RIGHTS_BLOB =
                "I1dlZCBTZXAgMTYgMTc6MzM6NDQgUERUIDIwMDkKc3lzdGVtSWQ9MzU5Nzg3MQpyaWdodC4yPUkx" +
                "ZGxaQ0JUWlhBZ01UWWdNVGM2TXpNNk5EUWdVRVJVSURJd01Ea0taWGh3YVhKaGRHbHZiajB4TWpV" +
                "ek1UVXhNakV5TkRFNENtNWhiV1U5YzNSdmNtVmNPbk4xWW5OamNtbHdkR2x2YmdwcGMwZHlZVzUw" +
                "WldROWRISjFaUXB5WldObGFYQjBTV1E5TWdwd1lYbHRaVzUwVkhKaGJuTmhZM1JwYjI1SlpEMHhN" +
                "alFLWVdOMGFYWmhkR2x2YmoweE1qVXpNVFEzTmpFeU5ERTRDbkJoZVcxbGJuUlFjbTlqWlhOemIz" +
                "STlVR0Y1VUdGc1FWQUsKcmlnaHQuMT1JMWRsWkNCVFpYQWdNVFlnTVRjNk16TTZORFFnVUVSVUlE" +
                "SXdNRGtLYm1GdFpUMXpkRzl5WlZ3NmNuVnVDbWx6UjNKaGJuUmxaRDEwY25WbENuSmxZMlZwY0hS" +
                "SlpEMHhDbkJoZVcxbGJuUlVjbUZ1YzJGamRHbHZia2xrUFRFeU13cHdZWGx0Wlc1MFVISnZZMlZ6" + 
                "YzI5eVBWQmhlVkJoYkVGUUNnXD1cPQp1c2VySWQ9MQpwcm9kdWN0SWQ9Mwp0aW1lc3RhbXA9MTI1" +
                "MzE0NzYyNDYwMwpkZXZpY2VJZD05MzIxRTAyMy1DRUEyLTQxQTItODM1Mi1ERUVFODYxMDA4OEMK";

        String SAMPLE_RIGHTS_SIG =
                "GHNXWheMgBv8NC/jR9rVuwufyLgtirKsFq7C8dWL4Uzb4+3pZmfoqNLrxbXiTErCP4F42UnkP8mF" +
                "i8sFsdO99xGCuaa1zQqZO9zXNScKBxzRlKcSuzIRDynnq0CN9Wz82ibeA+b5S7HpsQ7nUbHb6SEu" +
                "9BqjArTEc8wu7RCcTZo=";

        String SAMPLE_RIGHTS_CERT =
                "MIIE5jCCA86gAwIBAgIQXqXlgX7rylXBGhLidL9EhzANBgkqhkiG9w0BAQUFADCBgzEdMBsGA1UE" +
                "ChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsx" +
                "JTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNjcmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBT" +
                "aWduaW5nIENBMB4XDTA5MDgyNzAwMDAwMFoXDTEyMDgyNjIzNTk1OVowbTEdMBsGA1UEChQUU3Vu" +
                "IE1pY3Jvc3lzdGVtcyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEQMA4G" +
                "A1UECxQHQ2xhc3MgQzEXMBUGA1UEAxQOU3VuIEphdmEgU3RvcmUwgZ8wDQYJKoZIhvcNAQEBBQAD" +
                "gY0AMIGJAoGBAJghrmyAl2/ercRZRFfMPX5Ie+LusqP3UwMSB2A9Xl3via+kboXjuNHxTYyMEOUa" +
                "b3DorVSWsWHF5UKDK7KxkW+w/g2vYKnVZIKPH+VHRXYAwUMpEDNSSVMOyNKYF39uj0Ec9uRvhBw5" +
                "pxeKMRqQ0KhEhHMBH1EZQzUtPcYraHxPAgMBAAGjggHtMIIB6TAJBgNVHRMEAjAAMA4GA1UdDwEB" +
                "/wQEAwIHgDBrBgNVHR8EZDBiMGCgXqBchlpodHRwOi8vb25zaXRlY3JsLnZlcmlzaWduLmNvbS9T" +
                "dW5NaWNyb3N5c3RlbXNJbmNDb3Jwb3JhdGVPYmplY3RTaWduaW5nQ2xhc3NDL0xhdGVzdENSTC5j" +
                "cmwwHwYDVR0jBBgwFoAUs0crgn5TtHPKuLsZt76BTQeVx+0wHQYDVR0OBBYEFJHwpfEC3ziinvN3" +
                "8dKlgVR5OrW1MDsGCCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29uc2l0ZS1vY3Nw" +
                "LnZlcmlzaWduLmNvbTCBuQYDVR0gBIGxMIGuMDkGC2CGSAGG+EUBBxcCMCowKAYIKwYBBQUHAgEW" +
                "HGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwcQYLYIZIAYb3AIN9nD8wYjAnBggrBgEFBQcC" +
                "ARYbaHR0cHM6Ly93d3cuc3VuLmNvbS9wa2kvY3BzMDcGCCsGAQUFBwICMCsWKU5vdCBWYWxpZGF0" +
                "ZWQgRm9yIFN1biBCdXNpbmVzcyBPcGVyYXRpb25zMBEGCWCGSAGG+EIBAQQEAwIEEDATBgNVHSUE" +
                "DDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQUFAAOCAQEAPoQ8RWJ6xfnY8YxHL3kEVEPxKyDAa+sG" +
                "Ng5Rw2SaXFek9KMfMvU6DUXdj/BYIuLu9S2cVIHlIyFINzT6gtxsDNTkByMmRys8lsCZhXv767Pe" +
                "b/KW2sZWA8fxSE6JDRpWsE7j4PSr3rBB6YNqCTX0qH5yzumx2Lfk28BILKW7ri4cmakaql+Vi+6q" +
                "QIqhxDu1FzAdbwp/DzAJYtafcAZa381jDH3kwpSXpP15V1jqZgGYs387hQEYDWie4J5sol7g0cN9" +
                "zlRZQMxwU6Rcz/nWiM24mGB/W0NH7ggMS7/AWz6efN534OAxgWuBA96Qwf7TWKdZWzWEdhZar483" +
                "hfmZiw==";

        System.setProperty("jnlp.javastore.appwrapper.UserID", "1");
        System.setProperty("jnlp.javastore.appwrapper.ProductID", "3");
        System.setProperty("jnlp.javastore.appwrapper.VersionID", "3");

        // This value will be calculated by the java store runtime.
        int systemId = "user".hashCode() ^ "os".hashCode();

        System.setProperty("jnlp.javastore.appwrapper.SystemID", Integer.toString(systemId));

        System.setProperty("jnlp.javastore.appwrapper.rightsBlob", SAMPLE_RIGHTS_BLOB);
        System.setProperty("jnlp.javastore.appwrapper.rightsSig", SAMPLE_RIGHTS_SIG);
        System.setProperty("jnlp.javastore.appwrapper.rightsCert", SAMPLE_RIGHTS_CERT);

        App.main(new String[0]);
    }
}

The Legacy List & The Two Words - Fri, 16 Oct 2009 15:26:38 -0700

The Two Words : Some relevant advice regarding legacy technology from Bob Newhart.

I've been compiling a list for the last couple of months of legacy technologies that I feel are well past their 'Best Before Date' and should be eliminated. Keeping them around in spite of better alternatives makes all of our jobs more complicated. The reasons for keeping the dead technologies alive end up sounding like delusional rationalizations.

I'm looking for suggestions of obsolete technologies which we would all be better off by getting rid of them. I'm not going to share the complete list I've compiled because I want people to come up with their suggestions. Some ideas to get you started:

  • Cylinder/Head/Sector Disk Addressing
  • Telnet/rsh/rlogin
  • Non-UTF character encodings
  • S-Video
  • ...

If there's a technology you're forced to use or support that's best destined for the boneyard please make the case for its obsolescence.


Upgrading a Solaris 10 ZFS Boot Installation - Sat, 3 Oct 2009 12:54:18 -0700
With Solaris 10u8 aka Solaris 10 10/09 due any day now I've been planning to upgrade my installations. When I originally installed Solaris 10u6 with ZFS boot I assumed that the upgrade process to 10u7 would be about the same as it has been for UFS boot installations. It turns out, unfortunately, that the Solaris 10 installer doesn't offer direct upgrades for ZFS.

After a few days of fruitlessly searching the Internet for a procedure to upgrade my ZFS boot installation from 10u6 to 10u7 I contacted my Solaris oracle, Dave Clack and, of course he knew exactly how to do it. Since lots of people will undoubtedly need this procedure in the next couple of weeks, here it is. This procedure also works for OpenSolaris. Dave's instructions mount the DVD ISO using lofi loopback. If, like me, you are running you Solaris installations in VirtualBox then you can just mount the image as a virtual DVD. The procedure remains the same with a few path changes.

Upgrade a Solaris 10 ZFS Boot Installation from one "u" level to another
lofiadm -a /share/iso/solaris_dvd.iso

mount -F hsfs /dev/lofi/1 /mnt

pkgrm SUNWlur SUNWluu SUNWluzone SUNWlucfg

cd /mnt/Solaris_10/Product

pkgadd -d . SUNWlucfg SUNWlur SUNWluu SUNWluzone 

10uX is currently installed version

10uY is the version number of the one you downloaded

lucreate -c 10uX -n 10uY

lustatus

luupgrade -u -n 10uY -s /mnt

luactivate 10uY

init 6

EDIT: removed un-needed SUNWrmvolmgrr step.


Second Order - Thu, 24 Sep 2009 15:05:46 -0700
I had "that argument" with someone again recently. You know, the one about Java performance vs. C code. It's an argument I am very tired of having and I'm tempted to go "Barney Frank" on the next person to suggest there's a difference that matters.

One of the supposed C advantages is supposed to be that it offers greater opportunity for optimization. Maybe I have been looking at the wrong code lately but I see very little code these days that instruction-wise optimization, inline assembly or hand tweaking makes better. The biggest problem is not that careful optimization of small functions doesn't produce speed improvements but that those speed improvements are, overall, of marginal benefit. Here's some really bad code:

StinkoCode.java
static void main(String[] args) {

    List sortedArgs = new LinkedList();

    for(String arg : args) {
        sortedArgs.add(arg);
        Collections.sort(sortedArgs);
    }

    System.out.println(sortedArgs);
}

Even though this is just a contrived example, yes, I do regularly see code this inefficient. Would optimizing the sort() operation have much impact on the overall behaviour of this program? How about the choice of LinkedList? Would using a bulk insertion strategy such as addAll() help? If there are many arguments passed in the biggest gains would almost certainly come from sorting the arguments only once and possibly using a different data structure to store the strings. Let's try that again:

BetterCode.java
static void main(String[] args) {

    String[] sortedArgs = Arrays.copyOf(args, args.length);
    Arrays.sort(sortedArgs);

    System.out.println(Arrays.asList(sortedArgs));
}

As cautions against premature optimization suggest, is critical to carefully examine the causes your hot code is burning so many cycles before optimizing. Frequently the real problem is with the calling code and not the exact piece of code which shows up in the profiler as your hot spot. When planning optimizations it's usually best to look "up the stack" and evaluate the usage pattern for the bottleneck code being called before diving in to make a targeted fix. Most likely, at best, you'll only get a marginal improvement by making a local optimization. For the really big wins you should be focusing on the higher order causes.

Raw Oysters don't need sauce - Sun, 14 Jun 2009 16:13:26 -0700
Cocktail sauce, lemon, Tabasco, Tapatio, mignonette... all are commonly offered as accompaniments to raw oysters. I say phooey to them all. A good raw oyster is perfect just by itself. Well almost... a fine Sazerac cocktail and oysters are a great combination.
Tom was Right - Thu, 11 Jun 2009 17:15:52 -0700
Tom Waits has always refused to have his music used in commercials. He has successfully sued those who have used his music without his authorization and also successfully sued companies who used sound-alike songs or singers. Reading about these lawsuits on Wikipedia a couple of years ago I felt that he was certainly within his rights to control how his music is used but he was perhaps a bit too hardline about restricting their use. Look what "Bombastic" did for Shaggy, etc. Having enjoyed Tom's music for more than 25 years I wish more people knew his music. Commercials seemed to me to be a fine way introduce people.

A couple of weeks ago I heard Tom Waits' distinctive voice over a commercial on Hulu and immediately drew my attention because it was entirely unexpected. The commercial is a PSA for Feeding America. I now understand why Tom has chosen not to dilute the effect he gives the commercial by also shilling for Pepsi and Chrysler.

In the deep dark past there was this one commercial for Purina though. I find his intonation hilarious.


alt Text - Sun, 29 Mar 2009 11:05:04 -0700
You want to know how to frustrate a web accessibility architect? Suggest you are adding alt tags to your images for the SEO benefits rather than for accessibility. It's true that image alt tags do increase page search rankings and the resulting tags are useful for those using non-visual browsers, but wasn't making your pages accessible reason enough?

If that doesn't work you can suggest that you'll continue to use tables for formatting even after you convert to CSS or include multiple invisible iframes on every page.

Polyorthographic - Mon, 16 Mar 2009 12:17:54 -0700
A few months ago I was updating my Wikipedia user page after seeing a user box on someone else's user page that I wanted on my own user page. I opted to browse a bit and see if there were other boxes that I might also want to add. One category of user box I wished to add to my page was to indicate my language preferences. Though I live and work in the United States I've remained a devout Canadian speller and used other idioms of Canadian writing (garbage not trash, holiday not vacation, etc.). Confronted with the options for spelling preferences I found that there was no existing user box for "I use Canadian spellings". I didn't wish to use the "I prefer United Kingdom spelling" user box because I don't use UK spellings for many words. I could have originated a new "Canadian spellings" user box but another of the existing choices intrigued me:

MIX : This user has been influenced by too many dialects of English to use one orthography, vocabulary and grammar consistently.

This polyorthographic user box doesn't accurately describe how I try to write. I do prefer to write using Canadian spellings and idioms, but it does reflect how I read. I'm comfortable reading almost all modern styles of written English. I opted to add this user box to my Wikipedia user page rather than creating a new Canadian English user box. I didn't feel that it was entirely accurate but felt the distinction wasn't worth fussing over.

Since adding the user box I've actually continued to think about it and how I use language, strange as that may sound. I discovered that my feelings about using Canadian style orthography were more complicated that I had thought. For example, last year while working on the JXSE Programmers Guide 2.5 I made the conscious decision to use American spelling and grammar to be consistent with the previous edition and the other chapters written by other people. Reasonable enough. Also, after reading about International English, Basic English, E-Prime and the Simplified Spelling Society (all courtesy of the zany link boffins at reddit.com) I decided to follow some of the rules that these simplified grammars advocate for my email and forum communications whenever I suspected that the reader might not be a native English speaker. I believe that using English that is less idiomatic has possibly made my writing easier to understand. Since I can never remember all of the English grammar rules anyway I'm also choosing to write only in the narrower style of the rules that I do know.

I'm finding myself becoming increasingly comfortable with being a polyorthographic English writer and now believe that the user box will eventually accurately reflect my writing. I'm also taking more of an interest in other ways I can continue to improve my written English.


It Just Doesn't Work that Way!! - Mon, 16 Mar 2009 12:15:23 -0700
The Consumerist is linking today to the innovative and pleasantly refreshing Aviary Terms of Service page. Wow! Why can't they all be like that?

I still convinced that the terms could be even shorter and less legally dense. (legal density--good or bad--discuss amongst yourselves).

Feeling Shmenge - Mon, 23 Feb 2009 10:54:49 -0800
Yup, it's homemade cabbage rolls and coffee. Both were made by me, not Mrs. Yachke. I'm not listening to polka music while I enjoy them.

Three small cabbage rolls with tomato sauce on a small plate with a large cup of steaming black coffee

For those not familiar with the Shmenge brothers, I refer you to a documentary made about their final concert The Last Polka.


Good Netkeeping - Wed, 11 Feb 2009 10:22:31 -0800

I'm getting really tired of every single website having it's own password policies. I'm sure everyone else is as well. About 10 years ago there was an effort by authors of Usenet client applications to develop a Good Netkeeping Seal of Approval. The practices it describes are intentionally minimal. The GNKSA doesn't specify how to write a Usenet reader but it does specify many important details that every client should follow.

This type of best practices effort for Internet applications is required now more than ever. It is incredibly frustrating that nearly every site and (ahem!) even different sites by the same company has a different policy for managing details such as permitted and acceptable passwords, account and password recovery mechanisms, email change policy, etc.


No password - Mon, 2 Feb 2009 12:01:58 -0800
I have been doing a lot of work using virtual machines (the simulates-a-computer kind not the Java kind). Since all of the virtual systems are NATed or have no networking and because I'm mostly doing driver development I am generally logged in as root and not using a password. Obviously, this has usage and security implications. For one thing, I can't assume that there is any kind of safety protection. If I screw up then the machine is screwed up. This applies to the security as well. If I do something stupid like download random software or go to arbitrary web sites then I could easily screw up the virtual machine.

So far I haven't managed to corrupt, infect or otherwise damage any of my virtual machines. I've found it kind of interesting how the direct knowledge that I have no "safety net" when operating these machines has impacted my thinking and choices. I've found I am a lot more thoughtful and cautious about the actions I take. I spend more time considering implications before hitting return. I'm coming to think that perhaps working in this way is possibly a good thing. Having to be certain before committing to actions has actually saved me time. I've made fewer repairable mistakes and frequently changed my mind as to how to correctly proceed rather than just barging ahead.

The moral of the story is (as usual) make good backups, play safe and be brave.

View as single page - Fri, 9 Jan 2009 17:12:50 -0800
I noticed another site, the Daily Beast, is now offering a "View as Single Page" link for their longer articles. Nice. Thanks. The Christian Science Monitor and New York Times also offer a "Single Page" link for most of their content. I have to ask though, why would anyone assume that I'd prefer the multiple page layout? I understand completely that breaking an article into multiple pages increases your advertisement impressions but is it really worth annoying your readers that much?

The worst sites are invariably computer gaming review sites. It's not uncommon to see 20 "page" articles (and sometimes with no way to jump ahead or Table of Contents). Given that the ads they are showing are generally the least profitable Adwords terms and they have no other sources of revenue it's perhaps understandable that they julienne their articles.

If print media is going to successfully transition from paper to online then making their product easy and pleasant to access has got to be more of a priority.

Advice for the holidays - Tue, 2 Dec 2008 11:17:57 -0800
Many people are still ruining the holiday season by serving their family and friends the dreaded cranberry cylinder:

loathsome canned cranberry sauce

This holiday disaster can be averted by preparing your own much tastier cranberry sauce from scratch.

Simple Cranberry Sauce Recipe
1lb/500g bag of fresh or frozen cranberries
1.5 cups of orange juice (approx).
1.5 cups of red port wine (approx).
dash of salt
2 cinnamon sticks
1 cup of sugar (approx./to taste)
zest of one orange or lemon (optional)

Ingredient notes

If cranberries are fresh then put them in the freezer overnight. Freezing
breaks the cell walls and they cook more quickly. I used to buy fresh 
berries but now just buy frozen if they are available. Unless the berries
are really old and have "freezer funk" you won't be able to tell the
difference.

I use frozen or "from concentrate" orange juice. Fresh orange juice is 
wasted on this recipe. 

You must use a very cheap port for this recipe. If it doesn't have a screw 
cap, you're doing it wrong! Cheap port has the right mix of acidity, sugar
and grapeiness to balance it's otherwise awful taste. The subtle, refined 
good taste of fine port can't stand up to the rest of the flavours in this
recipe. You must use wino port.

The cranberries, juice and port all have varying amounts of sugar so you 
have to adjust the sugar to your taste. As the sauce cools it will taste 
less sweet. 

Directions

Put frozen berries into a bowl of water big enough so that they float. Pick
out anything you wouldn't want to eat. This includes green berries, moldy 
berries, dry shrivelled berries, leaves, sticks, dirt, etc. 

Transfer cleaned berries to a small pot. The pot should be about half full 
with the berries in it. Add orange juice and port in equal measure until
some of the berries just begin to float. Add the cinnamon stick, salt and 
optional citrus zest.

Bring to a boil over medium heat. Reduce heat to low and simmer for about 2 
hours stirring every half hour. When most of the berries have lost their 
shape the sauce is done cooking. Turn off the heat and allow sauce to cool 
for 15 minutes. The sauce will thicken and gel as it cools.

Stir in the sugar a couple of tablespoons at a time tasting after each 
addition to see if the sauce is sweet enough. Sauce can be served warm or
can be chilled before serving in the refrigerator. 

I get "The Point" - Tue, 4 Nov 2008 14:52:20 -0800
I really like the new CBC Radio One show The Point. It's a breath of fresh air to hear from viewpoints that aren't defined and chosen solely by political affiliation. It's also a lot more interesting. So far the selection of guests has delivered some really smart, incisive, surprising and informative discussion. And it's not ever been strident, ignorant or boring. Great stuff!
"The Apprentice" Followup - Wed, 22 Oct 2008 15:49:43 -0700
About four years ago I wrote an entry about Jacques Pepin's memoir as a chef, The Apprentice. This morning Jacques was a guest on KQED Forum and I got to ask one of the questions I had about his memoir.

Reading the memoir, his transition between working in France and his move to the US had seemed abrupt and unexplained. So I asked, "Why did you move to America?" (at about 43:45 into the podcast). His answer, which is also in the podcast, was essentially that he came to America to learn English and see the place for a year or two. He didn't really plan to stay, but found he loved New York and chose to make America his home.

It was really great to speak to Jacques and get my question answered!

Less than 5 minutes later a friend called with the obligatory, "Holy crap! You were on Forum!" call. It was nice to know someone noticed!

Who am I writing this for? - Tue, 21 Oct 2008 15:24:16 -0700
I'm working with a new code base and a new build process for a small project I am working on. The project makes use of the 'jstyle' code style checker tool. I've been running seriously afoul of it's rules by having the timidity to leave extra whitespace at the end of lines and add extra whitespace in expressions.

I've complained before about overly rigorous coding standards but the "remove your extra whitespace" insistence is driving me nuts. I'm sorry, I just don't care. My editor puts in whitespace to make aligning text easier. I can't see whitespace and I normally don't scour my source to make sure that my editor hasn't added any. Since the compiler doesn't care, why complain about it? (I also happen to like using "flowed" format for Javadoc with the hope someday that my text editor will free me from having to do line wrapping manually within documentation comments).

There's a lot of stuff that just doesn't matter. There's a limit to how much "extra" energy people have for "doing the right thing". Being pedantic about minor issues depletes that energy without accomplishing much.

Vanilla Pudding - Wed, 15 Oct 2008 11:07:27 -0700
By special request I made cooked vanilla pudding from scratch last night. I've made custard from scratch before but this was the first time I've made pudding without a box. Here's the recipe I used: Vanilla Pudding Recipe.

As you can see the recipe isn't that difficult. It's not much harder than preparing packaged cooked pudding and it doesn't require any special ingredients. The result was quite good though perhaps a little sweet to my taste. It also wasn't perfectly consistent though I didn't stir it after chilling before serving. Having made scratch cooked pudding I now can't imagine buying boxed pudding again as it seems like a waste of money. Next time I'm going to try caramel pudding.

Caller ID : a curse? - Fri, 10 Oct 2008 15:12:15 -0700
Calling number identification is definitely a mixed blessing. I missed a call today while making my lunch. The call appears on my phone's display as being from the Sun main switchboard number. This mean that the call could be either an external call which was forwarded to my direct line by an operator or the automated attendant or it could be a call from another Sun employee. Unfortunately I'll probably never know who tried to call me. Whoever it was didn't leave a message and I can't call them back. I think I'd feel happier if I didn't know that I had missed the call. When I can't sleep tonight agonizing over who it was that called I will be cursing Theodore Paraskevakos, the inventor of caller ID.
The New JXTA Book - Tue, 7 Oct 2008 11:56:00 -0700
My copy of the recently published, Practical JXTA, arrived the other day. I have been thumbing through it during compiles. I haven't yet had time to read in detail more than the introduction, table of contents and the author bio.

Looking at the table of contents it appears that the book hits exactly the points that have traditionally (or recently) caused developers confusion and pain as they are learning JXTA. It also really helps that the book is based upon the latest JXSE 2.5 release. Some of the code shown in older books no longer compiles properly with the latest releases (and some of it I'm pretty sure never compiled). JXTA has evolved and improved a lot over the years and without new editions the older JXTA books, or at least their code examples, have become obsolete. Learning JXTA with a new up-to-date book should be a lot easier.

I'm looking forward to reading the entire book when I get the time.

Engineers into Capitalists? - Sun, 5 Oct 2008 12:20:03 -0700
Why is it that so many of the people who have made a significant contribution to technology as engineers and programmers transition into being venture capitalists or business people later in their careers?

I'm thinking of Bill Joy, Marc Andreessen, Bill Gates, Charles Simonyi and many others who did ground breaking work early in their careers as engineers and then left it all behind to work as businessmen. Somehow I don't think they did so because of a motivation to "get rich" as venture capitalists. There must be some attraction that escapes me. I've been coding since I was 12 years old and I can't ever imagine stopping. I don't even want to slow down! I wish I had more time to just hack code.

I've met many people in the industry who didn't have the passion I do for the actual work of programming. To them programming is "just a job" and it's not surprising to me that they could easily be drawn to other roles or professions. I don't even believe that it is a bad thing that they would choose to pursue what they are good at. (I'd really prefer it if people spent more time considering what they really excel at and pursuing those opportunities rather than being mediocre at what they are doing now.) Being a great technical director, people manager, product manager, QA engineer, customer engineer or technical writer are just as noble as being a coder.

Unfortunately, for me, the question of why a skilful technically minded person would choose to leave the engineering field for business remains unanswered.

I got thinking about this topic again after reading about Bill Gates’ Personal Easter Eggs in 8 Bit BASIC.

JTRES 2008 - Workshop on Java Technologies for Real-Time and Embedded Systems - Tue, 30 Sep 2008 16:36:11 -0700
Last week the Santa Clara Sun campus was host to two high-tech summits, the JVM Languages Summit which you have probably already heard of but another summit, JTRES, was also held concurrently.

JTRES is focused on the application of Java for Realtime and Embedded applications. Many of the presentations and discussions focused on the existing Realtime Specification for Java aka RTSJ 1.0 aka JSR 1 but there were also a lot of interest in RTSJ 1.1 aka JSR 282.

The presentations also made it clear that Java and virtual machine technology have advanced significantly since Java Realtime was first conceived. The technology has matured through solving real-world problems--people are using Realtime Java and developing greater experience with it every day. The operating systems are improving, the JVMs are improving, the APIs are evolving and the application best practices are growing. Interesting challenges certainly remain; performance (always), scalability (always) but also the need to evolve to better support CMT and virtualization.

The conference keynote was delivered by James Gosling who has been a long time supporter of the Java Realtime initiative. My take away from the keynote was his question, which I've already been asking myself for a while, "Why not make realtime part of every JVM?" Game programmers need it, media applications need it, networking technology like JXTA can benefit from it. Realtime Java is also very well suited for embedded applications such as car computers, factory floor automation, consumer entertainment and communication devices.

Banned Books Week 2008 - Fri, 26 Sep 2008 10:21:05 -0700
Banned Books Week 2008 is September 27th to October 4th this year. BBW was started by the American Library Association in 1982 in response to increasing challenges against books at libraries, schools and bookstores.

Free access to books is a critical part of keeping our society free, open and pluralistic.

Part of why I don't like driving... - Wed, 17 Sep 2008 12:40:36 -0700

Century after first fatality, safety is in the air

According to a 10-year average of National Safety Council statistics from 1996 to 2005, only two people died in commercial airline crashes per 10 billion miles travelled.

That compares to a death rate of five people per 10 billion miles on passenger trains. And in cars, 81 people died for every 10 billion miles travelled.


Abridgement Too Far - Tue, 16 Sep 2008 18:09:01 -0700
I've been trying for a couple of months to get an AudioBook version of The Amazing Adventures of Kavalier & Clay and have only found one edition on CD, an abridged version. I yesterday discovered that this is the only commercial AudioBook version and no unabridged version exists. Bummer! I won't buy, read or listen to abridged books. I do understand that audio books were originally abridged to make them more affordable. This is no longer a problem as MP3 compatible CD players are now very common.

As much as I hate abridged books it is especially galling is that the publisher would choose to abridge a 2001 Pulitzer Prize winning novel. The book won for what it is--either read that or don't bother.

Greasemonkey & Accessability - Mon, 15 Sep 2008 17:25:00 -0700
I've been busy learning to write JavaScript over the last couple of weeks. I am incredibly impressed with what you can build using XHTML+CSS+SVG+JavaScript in modern browsers. For some amazing examples of website remixing and mashups you have to try out Greasemonkey. This Firefox plugin allows you to dynamically alter third party web sites using scripts you download or write yourself.

The first script I've written is to improve the accessibility of a website by adding alt tags to their images. It turns out to be damn easy! Of course, putting in the tags at development time would be even easier, but getting some sites to improve their accessibility is about as much fun as pushing a rope. Unfortunately I can't name the website because using Greasemonkey violates their terms of service and I'd rather not get disconnected even though what I'm doing isn't illegal.

Interestingly, it seems that a number of JAWS's more "advanced" browser features could be fairly easily written as Greasemonkey scripts.

Paralympic Gold - Mon, 15 Sep 2008 12:48:26 -0700
Congratulations to Jessica Lorenz, a gold medal Paralympic athlete and very dear friend!

Some photos of the gold medal game and the triumphant American Ladies team, US claims title of Women's Goalball.

Congratulations to Mark Bristow, a double gold medal Paralympic athlete and Sun employee!

Some photos of Mark in action, Mark Bristow claims title of Men's 1km Time Trial (LC1), winning one of his gold medals and smashing a world record in the process!

I was already watching the Paralympics coverage closely in Women's Goalball. Having an additional competitor to cheer on for, a fellow Sun employee Mark, made the games that much more special! I can hardly wait for the Vancouver 2010 Winter Paralympics.

Sufficient Pixels - Thu, 11 Sep 2008 13:22:50 -0700
Finally, a decent sized monitor with just enough pixels : Barco LC-5621. Now all I have to do is convince my manager that I need it...


 
CPG-News Theme © Akamu


The logos and trademarks used on this site are the property of their respective owners.
We are not responsible for comments and contributions (photos, downloads, etc) posted by our users, as they are the property of the poster

Interactive software released under GNU GPL, Code Credits, Privacy Policy