<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7847888108943867988</id><updated>2011-10-02T00:04:43.231+10:00</updated><category term='NetBeans plugins'/><title type='text'>jusblad</title><subtitle type='html'>Stuff on programming, OS, and web development - from an enthusiastic Mac convert.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-7771041629022893944</id><published>2011-10-01T22:02:00.024+10:00</published><updated>2011-10-02T00:04:43.630+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans plugins'/><title type='text'>Making your own NetBeans modules</title><content type='html'>NetBeans 7 is a powerful, free IDE that provides lots of opportunities to customise. If you find yourself continuing to create code that does roughly the same thing (eg. PHP scripts), you may want to make your own intelligent, dynamic template file to make life easier. The technology used to do all this is NetBeans IDE API and FreeMarker - a templating system that provides heaps of functionality, only a small portion of which needs to be used in NetBeans when creating modules.&lt;br /&gt;&lt;br /&gt;As an exercise, I decided to make my own PHP template file module that lets you create a new PHP file that connects to a MySQL database and table, and runs a simple query against it. Because I keep forgetting the code (and because most of my PHP scripts do MySQL access), I decided to set up a NetBeans module that allows to you to creates a new PHP file with the shell code for database table access filled in. To use the templated file, it's just a simple right-click to get a panel where you provide a database name, a table name and the fields you want. Out pops a valid PHP script that opens the database, runs a &lt;code&gt;SELECT * FROM xxx&lt;/code&gt; etc. query against it, then prints a list of fields you have selected in the panel.&lt;br /&gt;&lt;br /&gt;There are some pretty good tutorials to do all this on the NetBeans sites, but a number of gotchas as you utilise version 7 - some of the tutorials are slightly out of date for this version. This posting should hopefully help you resolve those differences, and create your own customised template. Follow the tutorial on the NetBeans site &lt;a href="http://platform.netbeans.org/tutorials/nbm-filetemplates.html" target="_blank"&gt;NetBeans File Templates Tutorial&lt;/a&gt; while you read this post - I'm really just flagging a few tips to get it going on version 7, with a real-life example.&lt;br /&gt;&lt;br /&gt;We'll be using FreeMarker as a template language to link what you put on your 'new file' panel into the actual PHP file you create... this is the timesaving feature.&lt;br /&gt;&lt;br /&gt;You'll need the FreeMarker plug in for NetBeans, and I don't believe it's available from the standard plugin sites contained in Tools/Plugins, so you'll need to install the &lt;code&gt;.nbm&lt;/code&gt; file manually.&lt;br /&gt;&lt;br /&gt;Get the Freemarker Samples &lt;code&gt;.nbm&lt;/code&gt; by using the link on &lt;a href="http://netbeans.dzone.com/news/freemarker-netbeans-ide-60-first-scenario" target="_blank"&gt;NetBeans and FreeMarker Tutorial&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You should read this page top-to-bottom to get an understanding of FreeMarker's interface to NetBeans, and can even try out the tutorial to install a standard Java file creator if you wish. If you just want to download and install the &lt;code&gt;.nbm&lt;/code&gt; file, get it at &lt;a href="http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=3755" target="_blank"&gt;NetBeans FreeMarker Sample plug-in&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Press download, store it somewhere, then use Tools/Plugin/Downloaded and click 'install' to add it to NetBeans. It comes with a few samples that are immensely useful in understanding this beast.&lt;br /&gt;&lt;br /&gt;Unfortunately, it won't compile out of the box unless you remove an unnecessary dependency to &lt;code&gt;org.netbeans.modules.templates&lt;/code&gt;. Right click the project (FreeMarkerSupport) and edit the libraries list to remove it.&lt;br /&gt;&lt;br /&gt;As the tutorial goes on to say, add in the other required (but missing) dependencies: namely &lt;code&gt;'Java Project Support'&lt;/code&gt;, &lt;code&gt;'Project API'&lt;/code&gt;, and &lt;code&gt;'Project UI API'&lt;/code&gt;. You should now have a working FreeMarker plug in with a few samples (HTML file, Java file, and even a little form-letter writer).&lt;br /&gt;&lt;br /&gt;Now, to create your new module, select New Project, with a type of NetBeans Modules/Module. Give a meaningful name eg. &lt;code&gt;PHPMySQLTemplate&lt;/code&gt;, and an appropriate code base name eg. &lt;code&gt;org.yourorganisation.phpmysqltemplate&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Once you've done this, you can create the relevant files, compile and (most importantly), right click the project after compilation to Install/Reload in Development IDE. Create a wizard outline by following instruction 4 on the &lt;a href="http://netbeans.dzone.com/news/freemarker-netbeans-ide-60-first-scenario" target="_blank"&gt;NetBeans FreeMarker Tutorial&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This will give you most of the files you need namely: Java panels, a java Wizard Iterator, a module description html, and &lt;code&gt;layer.xml&lt;/code&gt;. You will be adding your own empty file to use a template (&lt;code&gt;.ftl&lt;/code&gt;) file.&lt;br /&gt;&lt;br /&gt;Because the purpose is to create our own panel, don't follow instruction 6 - we will customise our panel to collect a couple of fields and use those in the template. (Instruction 6 leaves out panel creation by just substituting the default Java file panels).&lt;br /&gt;&lt;br /&gt;Now: on to your own panels. This was a trial-and-error thing for me, but the FreeMarkerSupport Example files were enormously helpful. &lt;br /&gt;&lt;br /&gt;For your &lt;code&gt;xxxVisualPanel1.java&lt;/code&gt; file, just add the required text boxes/list boxes etc. you need to provide the dynamic data for your eg. PHP file. &lt;br /&gt;There's nothing too complex in here, but two things are important:&lt;br /&gt;1) Add your template variables eg.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;static final String DB_NAME = "db_name";&lt;br /&gt;static final String TABLE_NAME = "table_name";&lt;br /&gt;static final Object[] FIELD_NAMES = {"field_names"};&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;2) Provide accessor methods for your screen text boxes eg.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public String getDBName() {&lt;br /&gt;return jTextField1.getText();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Note the Letter example shows you how to get hold of &lt;code&gt;ListBox&lt;/code&gt; contents if you need that too.&lt;br /&gt;&lt;br /&gt;For your &lt;code&gt;xxxWizardPanel1.java&lt;/code&gt; file, you need to provide more accessor functions to get hold of the dynamic variables eg.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public String getDBName() {&lt;br /&gt;return ((PHPMySQLVisualPanel1) component).getDBName();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Most importantly, don't forget to update the &lt;code&gt;StoreSettings&lt;/code&gt; method with your dynamic screen variables eg.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public void storeSettings(Object settings) {&lt;br /&gt;((WizardDescriptor) settings).putProperty(PHPMySQLVisualPanel1.DB_NAME, getDBName());&lt;br /&gt;((WizardDescriptor) settings).putProperty(PHPMySQLVisualPanel1.TABLE_NAME, getTableName());&lt;br /&gt;((WizardDescriptor) settings).putProperty(PHPMySQLVisualPanel1.FIELD_NAMES.toString(), getFieldNames());  &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This step is the mechanism by which the dynamic screen variables get passed to the template file.&lt;br /&gt;&lt;br /&gt;The &lt;code&gt;xxxxWizardIterator.java&lt;/code&gt; file links it all together. In the instantiate method, you create a &lt;code&gt;HashMap&lt;/code&gt; containing the dynamic variables off the panel. Follow the example file closely so you fill in everything. In particular, note the linkage done by these lines of code:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;hashMap.put("db_name", wizard.getProperty(PHPMySQLVisualPanel1.DB_NAME));&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This puts &lt;code&gt;DB_NAME&lt;/code&gt; off the panel into the &lt;code&gt;HashMap&lt;/code&gt; which will be provided to the FreeMarker engine to create a variable you can use in your template like &lt;code&gt;${db_name}&lt;/code&gt;. Sticking to the lower/upper case standards here is helpful ie. make your template variables lower case. All the other code outside instantiate stays as is.&lt;br /&gt;&lt;br /&gt;The fun bit is creating your template. I used a PHP file, but of course your new file can be any type you like. The FreeMarker site has a list of all the macro instructions you can provide (eg. &lt;code&gt;#if&lt;/code&gt;s, and &lt;code&gt;&amp;lt;#list&lt;/code&gt;). A useful site to explore FreeMarker syntax is at &lt;a href="http://wiki.alfresco.com/wiki/FreeMarker_Template_Cookbook#Creating_presentation_templates" target="_blank"&gt;FreeMaker Template Cookbook&lt;/a&gt;. Again, follow the example &lt;code&gt;.ftl&lt;/code&gt; files to help create a template that should run/compile properly as soon as you add it to your next project.&lt;br /&gt;&lt;br /&gt;The &lt;code&gt;layer.xml&lt;/code&gt; file is very important. Use an example and modify it from there. Important things here are:&lt;br /&gt;folder xxx - tells NetBeans where the new file can be accessed eg. Templates/PHP&lt;br /&gt;You must also add the following line:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;attr name="javax.script.ScriptEngine" stringvalue="freemarker"/\&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;so that NetBeans knows you want to tell FreeMarker to use templating.&lt;br /&gt;You can also make an &lt;code&gt;.html&lt;/code&gt; file to describe your wizard file creation, and for completeness, you might want a 16x16 icon to show off your new file. There are two &lt;code&gt;.html&lt;/code&gt; files in use: one describes the wizard itself, and the other, some information on the file you are creating.&lt;br /&gt;&lt;br /&gt;Lastly, clean/compile and Install/Reload in Development IDE to install your template.&lt;br /&gt;&lt;br /&gt;When you compile, be careful of some of the libraries you linked in. The main issue I had was the auto-import fixer brought in &lt;code&gt;javax.tools.FileObject&lt;/code&gt; which is NOT the one you want: you want the wizard custom file object version:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;import org.openide.filesystems.FileObject;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If all goes to plan, you can now add a new file to any project, filling in a couple of custom items on the panel, then see these correctly inserted at the right places in your new file. As I mentioned, I used all this to create a ready-to-go PHP file that accesses a database table and prints a few fields. &lt;br /&gt;&lt;br /&gt;One last gotchya when it comes to using your new template: if you're using the &lt;code&gt;ListBox&lt;/code&gt;, you'll need to actually select all the values you want: a list box full of data, but unhighlighted brings in sweet FA!&lt;br /&gt;&lt;br /&gt;Given you are controlling the creation of your templated-file with FreeMarker and java code, you have opportunities to do all sorts of exciting things - my next idea is to actually pre-fill the table fields in the list box based on the selected database and table. This MySQL access code will go in &lt;code&gt;xxxVisualPanel1.java&lt;/code&gt; file, once the user has chosen a database and table.&lt;br /&gt;&lt;br /&gt;In summary, you can use NetBeans to 'intelligently' create new files for you using FreeMarker templating, and using Java code to interact with the NetBeans IDE. Nifty eh?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-7771041629022893944?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/7771041629022893944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2011/10/making-your-own-netbeans-modules.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/7771041629022893944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/7771041629022893944'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2011/10/making-your-own-netbeans-modules.html' title='Making your own NetBeans modules'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-3809411661949810959</id><published>2010-12-23T20:08:00.008+11:00</published><updated>2010-12-23T21:08:57.704+11:00</updated><title type='text'>Sorting in C#</title><content type='html'>Sometimes we all yearn for the days of DOS sort.exe, or MVS JCL's DFSORT. Sorts were big in the 2-3GL world of COBOL and the like as indexed files were not a given, and sequential file processing was the rule. Batch processing typically ran 'jobs' in steps, and one of those steps was inevitably a sort. Downstream process logic had precise dependencies on input data sort integrity and big-iron OS's all came with their own SORT utilities. The beauty of the sort step was it's clarity: you knew exactly what you wanted, and it was pretty easy to get it.&lt;br /&gt;&lt;br /&gt;Although sorts have dropped from their prime position in the pantheon of programming processes, they're still around. Uncommon, but when required, utterly unavoidable.&lt;br /&gt;&lt;br /&gt;Almost all programming languages make provision for sorting, and C#'s no exception. &lt;br /&gt;&lt;br /&gt;C# sorting comes in a few flavours. The simplest is the sort method that pops up implemented in all sort of useful .NET library set objects like Lists. Of course, this sort of solution is rarely practical given the restriction of having only one sort operand, and we more often end up having to delve into the world of interfaces and OO approaches involving object derivation from useful .NET library components.&lt;br /&gt;&lt;br /&gt;I recently had need to do a slightly-complicated sort on multiple keys, handling strings, numbers and datetimes. Here's a quick guide for this kind of situation, with a couple of learnt-the-hard way snippets.&lt;br /&gt;&lt;br /&gt;1) Create a custom sort function.&lt;br /&gt;This function is tasked with loading your data into a List (or some other aggregating .NET object type), defining and using your new custom sort IComparer object on this list and lastly, outputting your newly sorted List object into the output file. Running the sort itself involves calling the .Sort method on your list object, passing in the custom comparer object as the parameter.&lt;br /&gt;&lt;br /&gt;2) Create a custom IComparer object&lt;br /&gt;The magic (if you can call it that!) happens here.&lt;br /&gt;IComparer-like objects simply compare two bits of data and return a 1 if the first is 'bigger', -1 if it's 'smaller' and 0 if they're the same. It's up to you to implement the logic behind bigger and smaller and in the process you can analyse the records to sort to process date times, strings and numbers (or even other objects). The comparison logic resides in the Compare method you create in this object - it's compulsory.&lt;br /&gt;&lt;br /&gt;Two things are important to remember to get this object working correctly:&lt;br /&gt;&lt;br /&gt;a) ALL comparison logic paths must be tested. The compiler picks up the fact there are missing paths for you if you forget some, but I guess there's only so much it can do. To abuse a consulting world term, your testing must be 'MECE' : mutually exclusive, completely exhaustive.&lt;br /&gt; &lt;br /&gt;b) You should explicitly test for NULL against all the bits of the records you want to compare.  &lt;br /&gt;&lt;br /&gt;You can see that if you want to compare multiple parts of an object/record, you're going to end up with lots of if's and else's...especially given you need to check NULLs as well. The code can get quite ugly!&lt;br /&gt;&lt;br /&gt;The result of your hard work implementing custom sort functionality is quite impressive speed-wise. A few hundred thousand record file with 3 comparison operands runs in 5 or so seconds on my average-fast PC. This is your reward for obeying the .NET paradigm - a somewhat verbose but very well-specified and slightly abstract piece of code works efficiently!&lt;br /&gt;&lt;br /&gt;Here's a slightly schematic chunk of code explaining the above.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public static void SortMyFile() {&lt;br /&gt;    // Read the whole file into a List&lt;br /&gt;    List&lt;string&gt; myLines = new List&lt;string&gt;();&lt;br /&gt;    using (StreamReader r = new StreamReader("the file.txt")) {&lt;br /&gt;        string theLine;&lt;br /&gt;        while ((theLine = r.ReadLine()) != null)&lt;br /&gt;        {&lt;br /&gt;            myLines.Add(line);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    // Create the sort object and sort &lt;br /&gt;    MyVeryOwnComparer myVeryOwnComparer = new MyVeryOwnComparer();&lt;br /&gt;    // Call the List.Sort method with the sorter as parameter.&lt;br /&gt;    myLines.Sort(myVeryOwnComparer); &lt;br /&gt;    &lt;br /&gt;    // write out your sorted list &lt;br /&gt;    // using StreamWriter or the like&lt;br /&gt;           .&lt;br /&gt;           .&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Your iComparer derived comparing object.&lt;br /&gt;// Create the tests in the Compare method you must implement.&lt;br /&gt;// Don't forget all paths to be tested and test for NULL explicitly.&lt;br /&gt;public class MyVeryOwnComparer : IComparer&lt;string&gt;&lt;br /&gt;{&lt;br /&gt;    public int Compare(string x, string y) &lt;br /&gt;    {&lt;br /&gt;       // break up your x and y strings, &lt;br /&gt;       // convert elements as required and return&lt;br /&gt;       // 1's, -1's or 0's&lt;br /&gt;               .&lt;br /&gt;               .&lt;br /&gt;               .&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-3809411661949810959?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/3809411661949810959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2010/12/sorting-in-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/3809411661949810959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/3809411661949810959'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2010/12/sorting-in-c.html' title='Sorting in C#'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-498171836753126234</id><published>2009-08-31T15:57:00.021+10:00</published><updated>2009-08-31T16:51:40.482+10:00</updated><title type='text'>Java and C together</title><content type='html'>It may seem antithetical, but your bloated java code can utilise your nice lean C libraries quite easily using the JNI interface.&lt;br /&gt;&lt;br /&gt;There are two major tasks to get your C stuff into Java:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;A. Modify and compile your C file using JNI hooks:&lt;/h4&gt;&lt;br /&gt;1) Make a special Java C header by calling javah on your .c file:&lt;br /&gt;&lt;br /&gt; &lt;div class="codeview"&gt;javah myOriginalCFile.c -o myJavaCFile.h&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;2) Make a new JNI C file out of your original C file and include the JNI interface and your just-made javah header file. Export your functions to Java by modifying the function signature. Use JNI's special types (eg. jdbouble) for anything coming into your function from Java:&lt;br /&gt;&lt;div class="codeview"&gt;&lt;br /&gt; #include &amp;lt;jni.h&amp;gt;      /* Java Native Interface headers */&lt;br /&gt; #include "myJavaCFile.h"   /* Auto-generated header created by javah -jni */&lt;br /&gt; &lt;br /&gt;  JNIEXPORT jdouble JNICALL&lt;br /&gt;  myJavaCFunction(JNIEnv *env, jobject obj, jdouble x)&lt;br /&gt;  {&lt;br /&gt;    double x = 0.0;&lt;br /&gt;    /* Call the original C function */&lt;br /&gt;    y = myOriginalCFunction(x);&lt;br /&gt;    return y;&lt;br /&gt;  }&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;3) Compile your file into a shareable lib (architecure specific)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;B. Use your new .lib in Java  - there are 3 steps:&lt;/h4&gt;&lt;br /&gt;1) declare your C function in Java using the native keyword. 'native' says: it'll come from a library later. Do this in a static block of your class:&lt;br /&gt;&lt;div class="codeview"&gt;&lt;br /&gt;static {&lt;br /&gt;     private native double myCFunction(double x);&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;2) Get the library and load it. Note that you may want to set the library path either in the call arguments (&lt;code&gt;-DLD_DYNAMIC_LIBRARY&lt;/code&gt;) or call &lt;code&gt;set_library_path&lt;/code&gt;. Note that you don't need to include the file ending: Java will look for a .dll, .so, or .dylib depending on where you're creating your file.&lt;br /&gt;&lt;div class="codeview"&gt;&lt;br /&gt;System.loadLibrary("myLibName"); &lt;br /&gt;// or .dll or .dylib etc. &lt;br /&gt;// System will check for right ending itself&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;3) Call it! Make a new object of your class, and use the function eg.&lt;br /&gt;&lt;div class="codeview"&gt;&lt;br /&gt;MyClass mc = new MyClass();&lt;br /&gt;double myRtnValue = mc.myCFunction(2.33);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Tada.....C goodness for free!&lt;br /&gt;&lt;br /&gt;For a more complete (and much better description!) of this process, see the java documentation from Sun at: &lt;br /&gt;&lt;a href="http://java.sun.com/docs/books/jni/html/jniTOC.html"&gt;java.sun.com/docs/books/jni/html/jniTOC.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For a link to a practical implementation of a bessel function: &lt;br /&gt;&lt;a href="http://www.nag.co.uk/doc/techrep/html/tr3_00/TRExample1.html"&gt;&lt;br /&gt;www.nag.co.uk/doc/techrep/html/tr3_00/TRExample1.html&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;Bessel functions are solutions to Bessel's equation, and are useful for analysing wave propagation and decay in spherical or cylindrical coordinate systems: they are used extensively in signal processing and acoustics. Think drumskin vibrations varying over time. If you want to chart the y-displacement of the skin after your bang the drum, ask a Bessel function.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-498171836753126234?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/498171836753126234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/08/java-and-c-together.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/498171836753126234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/498171836753126234'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/08/java-and-c-together.html' title='Java and C together'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-2850215847049356829</id><published>2009-08-28T11:16:00.005+10:00</published><updated>2009-08-28T11:41:42.522+10:00</updated><title type='text'>Why does Carbon form 4 covalent bonds instead of 2?</title><content type='html'>Most people are not in the slightest bit interested in the answer to this question. For the 1% who are though, this vexing little question is at the heart of organic chemistry - that bitch of subject that seems to drive people alternately mad/ecstatic. I always knew C formed 4 bonds, and got through uni organic chem and some other stuff without really knowing/remembering why. So....years later, I decided to sort myself out.&lt;br /&gt;&lt;br /&gt;Here's the answer:&lt;br /&gt;&lt;br /&gt;Carbon's valence shell is configured 2s2 2p2 (remember the p shell can contain up to 6 electrons, in a 3-D 2px, 2py, 2pz shape). Two half-filled p orbitals should mean stable molecules like CH2 - the 2 electrons from the H filling the 2px and 2py subshells. But....these don't normally exist ...instead carbon likes to form 4 covalent bonds with other atoms. Why 4 and not 2? Because the 2s2 2p2 shell hybridizes. After hybridization there are NO LONGER any s or p shells. This is really important to understand. They've gone forever!&lt;br /&gt;&lt;br /&gt;2s2 2p2 becomes : sp3 sp3 sp3 sp3 (the hybrid).&lt;br /&gt;&lt;br /&gt;What's an sp3 shell look like? sp3 shells look nothing like s or p shells...more like a very short stocky baseball bats. They're called sp3 because the s and the 3 p shells combine to make 4 sp3 orbitals. Because there are 4 of them, and they like to be as far away from each other as possible, C forms (single bonding) tetrahedral shapes ie. 4 triangle surface planes.&lt;br /&gt;&lt;br /&gt;I'll try to put some picture in to explain this better...I admit that wasn't a great job. The most important thing I realised was that sp3 orbitals are not s and not p. They are completely different, and the old s and p orbitals have gone.&lt;br /&gt;&lt;br /&gt;How does a double bond work? Similar deal: let's take ethylene as an example:&lt;br /&gt;&lt;br /&gt;H2C=CH2&lt;br /&gt;&lt;br /&gt;1 x s and 2 p orbitals create 3 x sp2 orbitals. The remaining p orbital on the 2 C atoms forms a pi bond.&lt;br /&gt;&lt;br /&gt;A triple bond's no different: 1 x s and 1 x p form an sp orbital. 2 p's then form 2 pi bonds. Between the carbon atoms, you've got one sigma bond (from the sp's touching), and 2 pi bonds to make 3! (the sp hybrid has nothing to do with the normal p pi bonding). Easy eh? &lt;br /&gt;&lt;br /&gt;Hopefully this explanation also clears up that confusing issue of naming the hybrid orbitals. sp3 for 4 bonds, sp2 for double, and sp for triple never made any sense to me, until I realised they're just the formula that represents how many of the old s and p bonds combined.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-2850215847049356829?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/2850215847049356829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/08/why-does-carbon-form-4-covalent-bonds.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/2850215847049356829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/2850215847049356829'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/08/why-does-carbon-form-4-covalent-bonds.html' title='Why does Carbon form 4 covalent bonds instead of 2?'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-6336608040877105793</id><published>2009-07-12T19:08:00.003+10:00</published><updated>2009-07-12T21:07:41.681+10:00</updated><title type='text'>Where are our paths?</title><content type='html'>Lost when it comes to Leopard's paths? They're all important when you compile your own stuff and will drive you nuts at some stage, so after quite a bit of stuffing around (my incompetence, not theirs), I've decided to list the path to path in ORDER.&lt;br /&gt;&lt;br /&gt;The key thing to note is that in Leopard, in addition to the standard /etc/paths, Apple have created a 'path_helper' script (called from /etc/paths), that picks up path directories from two new special locations.&lt;br /&gt;&lt;br /&gt;1) A text file call /etc/paths&lt;br /&gt;2) any file you put in /etc/paths.d&lt;br /&gt;&lt;br /&gt;Before this, your own .bash_profile is read from ~/.bash_profile or, for root, /var/root/.profile in the standard way.&lt;br /&gt;&lt;br /&gt;So...the order for your paths is:&lt;br /&gt;~/bash_login or ~/.profile (if you have you path like xxxxx:$PATH)&lt;br /&gt;/etc/profile (mine contains JAVA_HOME)&lt;br /&gt;/etc/paths&lt;br /&gt;/etc/paths.d/*&lt;br /&gt;&lt;br /&gt;If you've installed your own software in /usr/local, you'll probably want to edit /etc/paths first, as this gets set up first too, and you generally want to override /usr/bin, /bin, /sbin and /usr/sbin to get your own stuff going first.&lt;br /&gt;&lt;br /&gt;The general commands in your script are simply&lt;br /&gt;XXXX=/your/path&lt;br /&gt;export XXXX&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-6336608040877105793?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/6336608040877105793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/07/where-are-our-paths.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/6336608040877105793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/6336608040877105793'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/07/where-are-our-paths.html' title='Where are our paths?'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-1656669462469717749</id><published>2009-07-12T17:36:00.009+10:00</published><updated>2009-07-12T18:10:55.538+10:00</updated><title type='text'>Entropy PHP and xdebug on Leopard</title><content type='html'>Like everything else *nix, Leopard comes with a crippled PHP. It's a PHP nonetheless, but as soon as you want to write interesting things you'll find it doesn't have many important modules compiled in.&lt;br /&gt;&lt;br /&gt;I mucked around with compiling my own into /usr/local/mysql but found the missing link was always GD....a bugger to compile in. Not wanting to use the bloated, and often outdated ports or fink versions, I relented and finally used a pre-compiled binary from entropy.ch provided by Marc Liyanage. This dude in Switzerland maintains a great binary, Leopard package installable version of PHP with lots of goodies. It's at &lt;br /&gt;http://www.entropy.ch/home, and it sure beats stuffing around with endless compile options from the raw php code.&lt;br /&gt;&lt;br /&gt;Of course, one other goody you'll want is xdebug by Derick Rethens - another deutschesprechende by the looks of it. This fantastic addition lets you debug your PHP scripts realtime, and hooked up to Komodo, Netbeans or Eclipse for instance, allows you to lazily trace through your code, inspecting variables (and changing them) as you go. It's a godsend to PHP developers everywhere and very popular, with new features added all the time. You can find xdebug at &lt;br /&gt;http://xdebug.org&lt;br /&gt;&lt;br /&gt;To get xdebug going in Marc's binaries you need to take care of a couple of gotchyas.&lt;br /&gt;1) compile it with CFLAGS=-arch x86_64 as that's what Marc's is.&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&gt;CFLAGS=-arch x86_64&lt;br /&gt;&gt;export CFLAGS&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;2) make sure your path finds Marc's PHP first, not Apple's or any other PHP's you've got lying around. This is really important, as otherwise you'll enter version issue in php.ini reminiscent of DLL hell! You do the standard phpize, and ./configure --enable-xdebug --with-php-config=path to php-config.&lt;br /&gt;&lt;br /&gt;Manually move the modules/xdebug.so into Marc's directory (mine was /usr/local/php5/lib/extensions/20090623).&lt;br /&gt;The last gotchya was tricky. You load your extra modules in the entropy version php in the php.d directory - just add a new file eg. 50-extensions-xdebug.ini. It will get picked up, however MOST IMPORTANTLY, even though you might have set your extensions_dir in the main php.ini, the [Zend] section in the 50-extensions-xdebug.ini file requires the FULL path to xdebug.so. Nothing else will do.&lt;br /&gt;&lt;br /&gt;Thanks to both these guys for making Leopard PHP development easy. Vielen Danke (or, as they say in der Schweize Danke vielmal) dufte Typen weil Ihr PHP coding leicht gemacht habt! (thanks guys you make PHP coding easy).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-1656669462469717749?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/1656669462469717749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/07/entropy-php.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/1656669462469717749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/1656669462469717749'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/07/entropy-php.html' title='Entropy PHP and xdebug on Leopard'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-2914748266660683157</id><published>2009-07-07T00:28:00.003+10:00</published><updated>2009-07-07T00:31:50.710+10:00</updated><title type='text'>Ruby - getting the latest on Leopard</title><content type='html'>Wanna upgrade Leopard's default ruby binary? Unlike most of the other Apple inclGNUsions like MySQL and PHP, they couldn't really cripple this one. Still, we all like the latest greatest stuff right?&lt;br /&gt;&lt;br /&gt;Per usual, the process can be painful. To cut a long story short, with a new 64-bit MySQL and PHP installation, you need to do this (in addition to your other ruby upgrade steps) to get the MySQL part going. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt; env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config&lt;br /&gt;&lt;br /&gt;Otherwise - you'll bomb out as Leopard tries to compile a universal binary ie. a whole lot of binary stuff you don't want/need and can't use. The use of the --with-mysql-config flag is a nifty way to get these things to just WORK with your MySQL installation. Kudos to MySQL for this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-2914748266660683157?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/2914748266660683157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/07/ruby-getting-latest-on-leopard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/2914748266660683157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/2914748266660683157'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/07/ruby-getting-latest-on-leopard.html' title='Ruby - getting the latest on Leopard'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-6044734242666024110</id><published>2009-06-13T16:22:00.002+10:00</published><updated>2009-06-13T16:38:58.189+10:00</updated><title type='text'>DBI and DBD::mysql on Leopard</title><content type='html'>I needed (wanted?) to use Perl's DBD::mysql module last night. OK, I thought, a quick perl -MCPAN -eshell and install should do the trick, as Leopard's Perl usually plays quite nicely with CPAN. Damn.....error after error in the compilation (the C bit), so off to google for a fix. OMG WTF AFAIK a quick google on using Perl's DBD::mysql module in Leopard brings up a whole pile of pleading postings from desperate and frustrated people. Cutting out the clueless postings (the ones with page after page of compilation errors and pointless 'try this' -  'try that' replies), it seems the problem is nearly always the same thing: the mysql socket, or rather, it's location. Two factors conspire against you using DBD::mysql - Apple's surprise exclusion of the MySQL headers, and DBD::mysql's expectation (I think) of a hard coded location for the mysql.sock file.&lt;br /&gt;&lt;br /&gt;To sort this mess out&lt;br /&gt;1) Get Apple's 'we're sorry here's the MySQL stuff' and install it. It's at http://support.apple.com/kb/HT3370&lt;br /&gt;2) Fix your php.ini file to use the same socket as DBD::mysql. I guess you could do it the other way round, but the Perl .pm module adjustment looked harder. Don't know where to find your php.ini? Shame on you! Anyway....&lt;br /&gt;&gt;php -i|grep php.ini will tell you where it lives&lt;br /&gt;&gt;nano your_location/php.ini and change mysql.default.socket = whatever DBD::mysql wants. In my case, it was /var/mysql/mysql.sock.&lt;br /&gt;&lt;br /&gt;OK, so now everybody should be using the one socket, so&lt;br /&gt;&gt;apachectl -restart&lt;br /&gt;and everything should be working. Check php -i|grep socket to make sure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-6044734242666024110?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/6044734242666024110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/06/dbi-and-dbdmysql-on-leopard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/6044734242666024110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/6044734242666024110'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/06/dbi-and-dbdmysql-on-leopard.html' title='DBI and DBD::mysql on Leopard'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-2616516058031661340</id><published>2009-05-16T02:27:00.005+10:00</published><updated>2009-05-18T22:37:02.442+10:00</updated><title type='text'>home automation</title><content type='html'>Bunnings is a day-spa for fellas. Satisfying our desire to make or fix things - real things, not sit-on-your-arse-in-an-office things, the place lets you think you're saving money too through DIY (although this is a fallacy - see below). The stores are cold and industrial looking, giving them instant cred in a world where every other shop is decked out like a funky bar and you feel pretty tough as you stride the gigantic aisles with shelves holding every kind of widget imaginable, almost literally like a kid in a lolly shop.  But while the massive range of stuff is probably Bunning's greatest asset, not far behind would be the staff and their attitude to customers. Where else does your standard-issue office guy get a chance to have a hardware-related conversation with (an apparently) real tradie? Certainly not with the ones who come to your house who seem to love confusing you with jargon, and even take delight in shaking their heads as they tell you the problem is much, much bigger than you thought.&lt;br /&gt;Nope, the Bunning's guys are almost always friendly and helpful, and happily talk to you as if you're one of them as you choose your 1/4" self-tapping holster bolts. For the 80 odd percent of us guys out there who earn money by doing stuff with Microsoft Office, a trip to Bunnings is a psychically nourishing experience.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* You don't save money at Bunnings: you end up going there 5 times to get 'just one more thing' for your pet project, and you end up with a whole lot of unused leftovers that are the result of impulse buying before you know what you actually would need if you had a clue. Some examples from my recent trips include:&lt;br /&gt;&lt;table&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Useless&lt;/td&gt;&lt;td&gt;Useful&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;A bucket of tile grouting&lt;/td&gt;&lt;td&gt;Cans of WD-40&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Half-used cans of Liquid Nails&lt;/td&gt;&lt;td&gt;Wrenches&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Dozens of super-glue tubes - dried hard&lt;/td&gt;&lt;td&gt;Nails of varying sizes&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-2616516058031661340?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/2616516058031661340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/05/home-automation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/2616516058031661340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/2616516058031661340'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/05/home-automation.html' title='home automation'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-1628823448224798584</id><published>2009-05-12T22:32:00.005+10:00</published><updated>2009-05-12T23:21:57.077+10:00</updated><title type='text'>Leopard and iconv</title><content type='html'>Anyone who uses Leopard's PHP realises pretty quickly that the binary is lacking some very basic modules, not the least of which is MySQL. Why provide MySQL, PHP, and a *nix platform and not put MySQL as a module into the PHP object? Don't try to answer this question - there is no answer. Put it down to Apple cuteness I guess.&lt;br /&gt;&lt;br /&gt;If you're PHPing on a Mac, your also probably recompiling your PHP object regularly, to pick up modules your latest pet needs. Chief among these as mentioned before would be MySQL, but gettext, curl, crypto and SSL would be up there too.&lt;br /&gt;Compiling these monster binaries on a Mac is not quite the *nix goodness one would hope for given the Darwin foundation - google around and you'll find a top 3 or so problems list that if nothing else, shows you that other people round the world are tearing their hair out too!&lt;br /&gt;&lt;br /&gt;My biggest problem always seems to be iconv. It seems Apple's version does/does not (?) include the functions lib_iconvopen and libiconv_close (or at least the .h files don't redefine the functions). Simple you might think: get a new iconv that works, compile it into /usr/local and away you go.  Wrong. You'll probably get a scrambled message telling you iconv functions ain't found or don't work.&lt;br /&gt;&lt;br /&gt;I always forget how I get out of this quagmire, so here I am documenting it here so I won't lose it, and you might find it helpful!&lt;br /&gt;&lt;br /&gt;::::::: AT THE LAST COMPILATION STEP WHERE libphp5.so IS CREATED, MANUALLY ORDER YOUR -L/libs and I/includes ARGUMENTS SO THE COMPILER PICKS UP CONSISTENT HEADER AND LIBRARIES GIVEN YOUR NEW MODULE BINARIES::::&lt;br /&gt;&lt;br /&gt;By the time the PHP make gets to this step, there are duplicated -l's -L's and -I's all over the place. Unfortunately, -L/usr/lib can come up first - making all the work you did compiling new add in modules useless. Simple eh? Yet it's amazing how many postings on various fora are out there still wondering how to deal with this nasty, but basic little problem. So...don't rely 100% on the output of ./configure - some handcrafting will get you to the Khubla Khan of 64-bit PHP &lt;i&gt;your way&lt;/i&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-1628823448224798584?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/1628823448224798584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/05/leopard-and-iconv.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/1628823448224798584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/1628823448224798584'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/05/leopard-and-iconv.html' title='Leopard and iconv'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-5970336723940773185</id><published>2009-04-27T01:13:00.034+10:00</published><updated>2009-04-27T14:44:35.761+10:00</updated><title type='text'>Commercial + java. Huh?</title><content type='html'>Being a semi-interpreted language (I'm not trying to start a religious war here), copy protection of java based software seems pretty lame at the moment (forever??). Yes, there are obfuscators out there, but at the end of the day, the .class files have to be processed by a JVM, leaving little to hide.&lt;br /&gt;&lt;br /&gt;Now people have lots of reasons for decompiling, not all of them nefarious and in my case recently, I just wanted to see what the hell the code was actually doing, as well as make a note of any open source libraries used. Being provided with a Mac OS X app bundle, you first need to explore the contents (right click - Show Package Contents and the java files should be in Resources somewhere. Don't forget a .jar is just a .zip). Once you've found the goodies, you can start the decompilation process. My needs for a decompiling this particular app  were simple: process a large number of class files in batch, keeping the directory structure intact, so that I could then use NetBeans to debug it as a new project. &lt;br /&gt;&lt;br /&gt;There are number of tools out there to decompile Java, and a great one that has a neat GUI interface is Monsieur Emmanuel Dupuy's straightforwardly named 'JD-GUI'. While it  produces nice looking code, deals with Java 6, and has a good interface, it only works on one .jar or .class file at a time. It's written in C++ using wxWidgets, which accounts for its speed. One great feature is that you can now take a whole .jar and save all its sources in a zip file with one click. Unfortunately, the author has no plans at this stage to release the code, or, maybe more usefully, 'JD-Core', the C++ library that does all the hard work, so for big java decompilation jobs, you'll have to go elsewhere unless you can be bothered decompiling each .jar individually.  You can get JD-GUI at &lt;a href="http://java.decompiler.free.fr"&gt;http://java.decompiler.free.fr/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The venerable JAD decompiler by Pavel Kouznetsov has been around forever, but is strangely now very difficult to find. The original domain kpdus.com has gone, but Tomas Varaneckas has kindly tracked it all down and is hosting all the versions on his own site at &lt;a href="http://www.varaneckas.com/jad"&gt;http://www.varaneckas.com/jad&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Let the decompilation begin...&lt;/h2&gt;&lt;br /&gt;OK....armed with JAD, I began the task. A good process is a repeatable process, so here's a quick guide for anyone inclined to muck around with their own java decompilation.&lt;br /&gt;&lt;br /&gt;1) Copy your compiled java directories somewhere new - jad can break stuff if you're not careful&lt;br /&gt;&lt;br /&gt;2) Run jad using a few special options to recursively get all the .class files, rename the default suffix of the decompiled code from .jad to .java, and put the source code somewhere OUTSIDE the .class directories. Here's a bash script I wrote to do all this quickly:&lt;br /&gt;&lt;br /&gt;&lt;div class="codeview"&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;# use jad Java decompiler recursively on all 3 class dirs,&lt;br /&gt;# putting .java files into ./src&lt;br /&gt;# options are:&lt;br /&gt;# -o overwrite without confirmation BE CAREFUL IN PRODUCTION DIR&lt;br /&gt;# -r recursive .classs search&lt;br /&gt;# -s append .java instead of .jad. BE CAREFULE IN PRODUCTION DIR&lt;br /&gt;# -d the directory you want decompiled INTO eg. src&lt;br /&gt;# Last parm: the files you want to decompile&lt;br /&gt;# com/**/*.class = in dir com, ALL child directories, all .class files.&lt;br /&gt; ~/Desktop/jad158g/jad -o -r -sjava -dsrc com/**/*.class&lt;br /&gt; ~/Desktop/jad158g/jad -o -r -sjava -dsrc nmfl/**/*.class&lt;br /&gt; ~/Desktop/jad158g/jad -o -r -sjava -dsrc org/**/*.class&lt;br /&gt;echo Finished decompiling com, nmfl, org.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The ** operator is interesting: it tells jad to recursively go as many layers deep as it need to pickup all the class file.&lt;br /&gt;While the script runs, you'll probably get a few message saying jad couldn't completely interpret some things eg. try { catch { stuff, and some specific IO things in particular. I'm not sure if this is Java 6 specific or not.&lt;br /&gt;&lt;br /&gt;Once you've run this script, go into the ./src directory and look at your nice new .java files. You'll get a new little header comment telling you Jad decompiled this work. Ignore the link - kpdus.com is no more.&lt;br /&gt;&lt;br /&gt;Decompilation is great, but if the code's been obfuscated, you've still got a bit more work on your hand. I'm no expert at the obfuscation side of things, so I'll put my project into NetBeans, have some guesses at the bizarre class names (d4eJH etc). and maybe do some refactoring if I can work out what's going on.....&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-5970336723940773185?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/5970336723940773185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/04/commercial-java-huh.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/5970336723940773185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/5970336723940773185'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/04/commercial-java-huh.html' title='Commercial + java. Huh?'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7847888108943867988.post-1723519023555299190</id><published>2009-04-26T23:49:00.005+10:00</published><updated>2009-05-16T02:25:57.282+10:00</updated><title type='text'>not another blog...</title><content type='html'>Q. Why did you create a blog?&lt;br /&gt;A: My virtual stuff is growing in size, and I need a place to put it.&lt;br /&gt;&lt;br /&gt;Not being able to remember stuff I've learnt about nerdy stuff annoys me, and I'm getting so much of this stuff now that I'm in danger of my virtual world stresses spilling over into the real world. The other downer about virtual stuff overload is that the more you get, the harder it is to find the one bit you really, really need, right now.&lt;br /&gt;&lt;br /&gt;That's one reason. This is a second:&lt;br /&gt;&lt;br /&gt;You know that feeling you get when you're stuck trying to work out a solution to a problem that's got you completely stumped, google it up with a few choice keywords and bingo, find an answer?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;mmmm.....feels good.....&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It feels so good because a) you know the writer went through the same crap you're going through right now, b) they worked out a solution and c) they bothered to write it down on their blog so others could benefit.&lt;br /&gt;&lt;br /&gt;If I can bring that feeling to a few people I'll be really glad I &lt;s&gt;succumbed&lt;/s&gt; &lt;s&gt;got sucked-into&lt;/s&gt; joined the blogosphere!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7847888108943867988-1723519023555299190?l=jusblad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jusblad.blogspot.com/feeds/1723519023555299190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jusblad.blogspot.com/2009/04/why-blog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/1723519023555299190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7847888108943867988/posts/default/1723519023555299190'/><link rel='alternate' type='text/html' href='http://jusblad.blogspot.com/2009/04/why-blog.html' title='not another blog...'/><author><name>jusblad</name><uri>http://www.blogger.com/profile/06078871055590116425</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
