You would think that a mug that has poisonous toxins in the glaze and paint would come from China, right? Well guess again. After going through a batch of company gifts, my wife came across a custom mug created by Ceramic Source. On the bottom of the mug was the ominous Prop 65 sticker:
"WARNING: The materials used as colored decorations on the exterior of this product contain lead and/or cadmium, chemicals known to the state of California to cause birth defects or other reproductive harm."
We just had a healthy baby boy and we were lucky my wife only used the mug as a pen case. It now will go into the garbage.
Don't buy drinking ware that contains toxins. It's unheard of in America and disturbing Ceramic Source can get away with manufacturing these mugs.
I decided to finally bite the bullet and get ProGuard working for some Android apps. It was hell getting everything working because of the shear number of moving parts: Android SDK, Eclipse, Libgdx, AdMob/Google Ads, apk signing, and the shitstorm ProGuard imposes on any project.
This is going to be another Impatient Guide, because I'd rather not relive configuration problems. The amount of time wasted getting technologies configured and working together is a time sink that gets in the way of making real progress and doing real work.
Step one: Turn on ProGuard for your Android project.
Navigate to your project. If you are using LibGdx and the standard configuration it will be named something like "<YourProjectName>-Android".
Open default.properties for editing
Add the line: proguard.config=proguard.cfg
Save and reopen Eclipse.
Step two: Update the Android SDK Location in Eclipse
Did you jump the gun and try to created a signed apk? Did you get this error?
"C:\Program' is not recognized as an internal or external command, and executable program, or command file."
Well, Proguard doesn't like spaces in paths, so update the Android SDK location to a short path form.
Open a command prompt: WIN+R -> cmd.exe
cd to the Android SDK location... e.g. "c:\Program Files (x86)\Android\android-sdk"
type: for /d %I in (*) do @echo %~sI
Copy the path. e.g. "C:\PROGRA~2\Android\ANDROI~1"
Paste the short form path in Eclipse: Window -> Preferences -> Android -> SDK Location
Hit apply or OK
Step Three: Tell ProGuard about dependent libraries
Did you try to export an application package again? Did you get errors like this?
"Warning: com.badlogic.gdx.scenes.scene2d.ui.utils.DesktopClipboard: can't find superclass or interface java.awt.datatransfer.ClipboardOwner"
or
"Warning: there were 28 unresolved references to classes or interfaces."
Well, you have to tell ProGuard dependent jar files, so it won't blow up. Add something like the following to the proguard.cfg file in your project directory. Your configuration will depend upon how your project is set up and make sure to use absolute paths.
That last one is only valid if you use the AdMob SDK.
Step Four: Fix runtime errors resulting from an overzealous ProGuard shrink
Did you export an .apk with joy, but become totally crushed when your application crashed? Did the crashes happen when you clicked on widgets?
It turns out that ProGuard is removing any code that appears to not be referenced/used. So, any OnClick* handlers specified in your Android layout xml files will be removed. Seriously. Take a look at <YourProjectName>-Android/proguard/usage.txt. That is stuff that was torn out from your code to "speed" up performance. Well, it crashes faster. That's for sure.
But you can't blame ProGuard. It can't read every file in your project that is SDK dependent and make the connection. ProGuard is nice, but it's no mindreader.
To fix this, open up proguard.cfg again and tell ProGuard to not touch any OnClick handlers:
-keepclasseswithmembers class * {
void onClick*(...);
}
If you want to make sure your advertisements from Google show up (com.google.ads*), add the following to your config file too:
-keep public class com.google.ads.** {*;}
Save it.
Step Five: Export the .apk and test it
You've probably already done this, but for reference:
Right Click on <YourProjectName>-Android -> Android Tools -> Export Signed Application Package...
Complete the form and generate the apk (e.g. yourproject.apk)
Make sure the app isn't already installed on your phone
First off: This is an Impatient Guide and it will be short on explanation and possibly accuracy
Second off: This method is a first attempt and is probably fraught with errors and inefficiencies, but it worked for me.
Let's get started!
Say you have a LibGDX project and you want to package it up for redistribution, but you don't want to give out a jar and would like it to be wrapped in a nice executable (.exe) just like any ordinary Windows binary. In addition, obfuscating the code to make reverse engineering more difficult might be something you want too.
Export a jar file with the Eclipse Export Wizard. I did this for my desktop version, by right clicking on the project "myapp-desktop" -> Export -> Java -> Runnable Jar File.
Plug in the usual stuff into the wizard, but choose "Copy required libraries into a sub-folder next to the generated JAR." Otherwise, ProGuard will make your life a nightmare when you try to obfuscate (e.g. "Warning: org.lwjgl.input.Controllers: can't find referenced class net.java.games.input.ControllerEnvironment").
Hit "finish" and the wizard will generate your shiny new .jar file.
Do 1 through 3 again, but in step 2 choose "Package required libraries into generated JAR." The jarinjarloader files and the MANIFEST.MF from this second generated JAR will be used later on.
Obfuscate your jar with ProGuard:
Run the GUI version of ProGuard: java -jar proguardgui.jar
In the Input/Output tab, click "Add input..." and enter the first generated JAR path.
Click "Add output..." and enter your output JAR... say (e.g. output.jar).
Click "Add..." in the Add libraries section and add the library export directory generated with the first JAR. If your export JAR name was foo.jar, the export dependencies should be in foo_lib.
In the Obfuscation tab uncheck "Use mixed-case class names."
Keep the default settings for now (you can tweak them later once you have this working).
Start processing the JAR. In the Process tab click Process!
If ProGuard finishes it will produce a nice obfuscated/shrunk JAR, output.jar.
Combine library dependencies into obfuscated JAR
The output.jar is not runnable as is. It needs to know how to find the library dependencies. You can pack the dependencies into the JAR with 7-zip. So, open output.jar in 7-zip.
Add/drag the contents of foo_lib (from step 2 in the first section) into the root level of the JAR (e.g. they should be in the same directory META-INF is in).
Extract the other JAR from the first section (see step 4) into a temp directory (e.g. temp).
In output.jar, clobber the file "META-INF/MANIFEST.MF" with the file from "temp/META-INF/MANIFEST.MF".
In output.jar, add the directory "org/eclipse" from "temp/org/eclipse".
Confirm the JAR is runnable: java -jar output.jar
Wrap your JAR in a Windows executable
Use Launch4j to wrap your JAR. Open the Launch4j GUI.
Add your output file: out.exe
Add your input JAR file: output.jar
In the JRE tab, set the Min JRE version (e.g. 1.6.0)
While trying to configure Nginx and PHP so that the PHP files would run from the same directory as static files, the error "290 rewrite or internal redirection cycle while internally redirecting to "/index.php"..." persistently recurred.
Everything worked fine after changing nginx.conf to the following (inside server {):
Say you want to request a collection from the server in backbone.js, but don't want to receive every single item available. Instead, you want to receive only the first 100 items. Well, jQuery.ajax options can be passed directly as fetch options. docs
So, when you want to fetch the collection call the following:
Here's a gorgeous music video by Beirut called The Rip Tide for your viewing pleasure.
It's a calling for my deep yearning to be on the deep sea and return to our mother's great bosom in perpetual undulation and rocking. The sea is like one grand lullaby.
I found myself wanting to test some PHP on my local Windows machine and wanted a lightweight, fast solution besides Apache. My motivation was getting a test environment with a RESTful serverside api for backbone.js testing.
Slim Framework (framework for writing RESTful APIs and applications)
Being no fan of PHP, getting this configuration was like putting salt on a wound, but it might be useful for those that want to get up and running in a very short time. I'll keep the explanations to a minimum to stay true to an Impatient Guide.
> curl.exe -i -X DELETE localhost/index.php/delete
HTTP/1.1 200 OK
Server: nginx/1.2.1
Date: Tue, 26 Jun 2012 00:35:50 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.4.4
This is a DELETE route
That's it. You're done. High Five!!
One neat thing about this toolchain is you can zip everything up and make it portable. There is no need to mess with installers, environment variables, etc...