Friday, December 19, 2014
A 2-in-1 laptop that just works under Linux: Dell Inspiron 13 7000 Series i7347
Monday, July 28, 2014
How I learned to program in Scala: The Nexus 5 experiment
Few months back I broke up my long term affair with Mono and I started looking into the the Play Framework from TypeSafe as a replacement stack.
Through Play Framework, I discovered Scala and the wonders of functional programming. My interest grew even deeper when I installed Scala on my laptop and tried some example code in the REPL tool (think Scala interactive shell).
However, I found very soon that I was not able to dedicate enough time during the week to learning Scala due to my full time day job doing .Net development.
Something had to be done.
I thought, I have this wonderfully powerful device on me all the time - my Nexus 5. Surely, I should be able to put it to use to help me spend more time with Scala. So began the experiment.
I rooted my Nexus 5, installed "Linux Deploy" from Google Play Store and installed a chroot Arch Linux environment. I also installed JuiceSSH client and a VNC viewer application. I already had "Terminal IDE" installed which comes with a great android keyboard geared towards software development on Android.
The last piece to the puzzle, I bought a $25 ANKER bluetooth keyboard compatible with my Nexus 5.
I fired up the Arch chroot on my phone, downloaded tmux and vim using pacman and oracle java 7 packages from AUR (some PKGBUILD tweeking was needed).
Then I installed TypeSafe Activator from AUR. I also downloaded vim plugins like vim-scala and CtrlP which proved to be of great help.
It worked!!!
Using the setup described above, I was able to not only learn how to program Scala, I am also able to write software using Play Framework. I can test the same on my phone's browser. The code is backed up on github and I can work on the same codebase from anywhere - as long as I have my Nexus 5 and data connection.
And after the recent KitKat update with Cast Screen - I am able to cast my phone's screen to my big screen HD TV over ChromeCast. This solves the issue of developing on the relatively small Nexus 5 screen.
This experience has made me appreciate VIM, TMUX, and the terminal in general at a whole new level. Even when on my laptop, I now find myself doing more and more coding in VIM instead of IntelliJ.
Think about it, you can now get a decent android box or even a phone, and with a setup similar to what I described, have an almost full fledged development environment. Rich graphical applications can be written in Scala using Swing (sigh) and possibly other graphical toolkits and can be tested within the Arch (or other Linux distro) chroot using VNC.
Side note about Oracle Java instead of OpenJDK: I went with Oracle Java instead of OpenJDK due to an "issue" with OpenJDK on arm chips. Its something to do with JVM running in "mixed mode".
Monday, March 17, 2014
CloudNotes - New project - using the Play Framework
Currently, the application features:
- Create and share notes using a web interface
- Notes dimension and position on screen are stored along with notes - think web based collaborative brainstorming tool
- GoogleDocs like collaborative editing of notes, although not yet realtime.
- User authentication
- Access Control List on Notes and entries
- Realtime interface with AJAX calls (currently causes full postbacks)
- Mobile and desktop clients
- Items reordering
- Checklist module
DigitalOcean offers cloud hosting for as low as $5/month or $0.007/hr for dedicated server with:
- 512MB Memory
- 1 Core Processor
- 20GB SSD Disk
- 1TB Transfer
- Additional bandwidth transfer is only 2¢ per GB
Monday, August 26, 2013
Update 1 - Progress so far - IrrlichtDotNet - .Net library for irrlicht that works under Linux
After I made the declaration of starting this project on irrlicht forums, roxaz from the forums expressed interest in the project and immediately forked it on github. We bounced around ideas and while I won't yet merge all of his modifications into my repo, I did like many of this ideas and implemented them after tweaking them to fit in with my code. The ideas that I implemented from his repo are:
- folder reorganization
- a python script that refreshes the CS project file with all the SWIG generated cs files
- make.sh file to automate many initial steps
Friday, July 26, 2013
Linux compatible .Net bindings for irrLicht using SWIG
Ever since I tried IrrLicht, an Open Source 3d Graphics library, I fell in love with it. It is a C++ library and my C++ isn't as good as I'd like it to be and I am more comfortable with C# under .Net.
Since IrrLicht is open source, I figured, someone might have written an .Net binding for it, and I was correct. A few such bindings do exist, although, they are truly only .Net bindings for IrrLicht for Windows platform only.
I also attempted to use MonoGame, which is known to work under Linux, but without any success.
A few days ago, while researching an unrelated subject, I stumbled across SWIG. SWIG stands for Simple Wrapper and Interface Generator. It is used when you want write wrappers to your C/C++ code for other languages. It also happens to support C#. So I decided to give it SWIG a swing and initial results were more than promising.
I decided to test it but exposing the Main method of my C++ test code written to try IrrLicht and called it from a .Net application. It worked!
I decided to take a shot at generating a wrapper for IrrLicht itself. So far, using the bindings that I was able to create with SWIG, I have been able to create simple 3d scenes in C# code.
I've created a project on GitHub to create a Linux compatible .Net binding for IrrLicht using SWIG. The repo is at https://github.com/jimmy00784/IrrlichtDotNet.
Initially, much of the focus will be on creating a Linux centric binding. However, since SWIG is cross platform, if the community is interested in the effort, it could become more cross platform than that.
Sunday, January 20, 2013
Day 2 - Porting nopCommerce to Linux - built in data storage
I set my breakpoint on the InstallController.cs and began walking through the code line by line to see where it had failed. I landed on SqlCeConnectionFactory.cs file line 41.
Contract.Requires(!string.IsNullOrWhiteSpace(providerInvariantName));
I tested the value of the providerInvariantName parameter to see if it was indeed null or whitespace, but it wasn't. For now I decided to comment this line and see if I could proceed. Same error. Examining the stack trace I found that Database.cs in the EntityFramework project had another Contract clause.
Contract.Requires(value != null);
And again, value wasn't null. It seemed like Contract clause wasn't behaving as designed. I decided to comment this one out as well. I found another one in EntityFramework, and then another one. After commenting out quiet a few of these over the next few trial runs, I decided to comment them all using Find and Replace. After fixing some compiler errors EntityFramework compiled without errors. Time to commit changes.
In first try I got the familiar Feature Not Implemented error.
Setup failed: The requested feature is not implemented.
However, an empty database did get created. I did a search and commented Contract.Requires from the EntityFramework project. I also set a breakpoint on the FailFast method in the Environment.cs core file which gets invoked when Contract clause failed.
Setup failed: The provider did not return a ProviderManifest instance.
Examining the stack trace hinted to this location: EntityFramework/Core/Common/DbProviderServices.cs:208.
There was also an inner exception being raised.
Invalid URI: The format of the URI could not be determined: System.Data.Resources.SqlClient.SqlProviderServices.ProviderManifest.xml
Further exploring down the stack trace took me to EntityFramework.SqlServer/SqlProviderManifest.cs:78 which passed a baseURI parameter. For some reason Mono didn't like the value that was being passed. I used an overloaded method that did not require baseURI to see if it'd let me proceed.
Setup failed: The requested feature is not implemented.
This was being raised from the EntityFramework.SqlServer project. I did another search and comment on Contract.Requires this time on the EntityFramework.SqlServer project.
After another round of placing breakpoints and tracing through the code, I found that the stack overflow was being caused by EntityFramework/Core/Common/Utils/Memorizer.cs:71 when attempting to evaluate result.GetValue(). I surrounded it with a try catch and returned the default value of the generic TResult in case of an exception to see if it'd let me proceed.
Setup failed: An unexpected exception was thrown during validation of 'Name' when invoking System.ComponentModel.DataAnnotations.MaxLengthAttribute.IsValid. See the inner exception for details.
This was coming from EntityFramework/Internal/Validation/ValidationAttributeValidator.cs:75. Inner exception hinted of an unimplemented function.
IsValid(object value) has not been implemented by this class. The preferred entry point is GetValidationResult() and classes should override IsValid(object value, ValidationContext context).
In order to proceed, I forced a ValidationResult of Success.
Setup failed: The handle is invalid.
Reviewing the stack trace took me to EntityFramework/Core/Metadata/Edm/LightweightCodeGenerator.cs:193. Examining the code showed that CreatePropertyGetter was creating a dynamic method to map to the getter method of a property on an Entity. After some more trial and error, it became apparent that while the Type handle was mapping correctly, the RuntimeMethodHandle held an invalid value. Fortunately, the getter method on a property has the naming convention of get_PropertyName. This could come in handy to boot strap this code to allow proceeding further. Time to commit changes and review the work.
I reviewed the database that was created by the application, and I see tables being created. This means that EntityFramework is facilitating table creation which is good news. This is a good stopping point for the day.
Thursday, January 17, 2013
Day 1 - Porting nopCommerce to Linux
Note: When modifying files in MonoDevelop that originate on Windows platform, and when a source control like Git is involved, it is best to not have MonoDevelop change line endings from windows to unix format to keep you commits clean.
Note: The code changes made during this experiment are available on GitHub at https://github.com/jimmy00784/nopCommerce-Linux-Mysql
The primary challenge I face is that in order to utilize Entity Framework and ASP.NET MVC 3 for .Net development, I had to upgrade the stable Mono 2.10.x to Mono 3.0.3 development release. I also had to upgrade MonoDevelop to 3.1.0 development release. This has broken the debugging capabilities from within MonoDevelop.
For porting nopCommerce, initially, I thought that simply switching the .Net Entity Framwork dlls with the Mono's dlls would be enough to run nopCommerce. I downloaded the source code from nopCommerce and loaded it in MonoDevelop. At first glance it didn't look as bad. Looking closely it becomes clear that System.Data.Entity supplied by the project would not work with Mono under Linux and there were dependency issues with EntityFramework and SqlServerCe dlls. I also downloaded the source for EntityFramework for Mono and planned to load EntityFramework as a project instead of simply adding the dll reference to the project. From earlier experience, I knew I'd be making some code changes to the EntityFramework to make it work with nopCommerce.
I added a solution folder for EntityFramework to nopCommerce solution and then added EntityFramework, EntityFramework.SqlServer, and EntityFramework.SqlServerCompact projects to it. For a quick sanity check, I compiled these new projects. EntityFramework complained that the delay sign key provided couldn't be used for assembly signing. That was easily fixed by providing the '-delaysign' compiler arguement. Recompiling didn't cause the same error but instead caused other code related errors, all of which are 'Warning as Error' which could also be fixed by unchecking the "Treat warnings as errors" settings for the project. This fix would also have to be applied to any other projects that complain in similar fashion. Also, the System.Data.SqlServerCe.dll supplied with EntityFramework.SqlServerCompact wasn't compatible with Mono on Linux. I was able to download the file from my Windows installation and that seemed to work ok for the purpose of achieving an error free compilation. The intention here was not to fix the EntityFramework project but to tighten or loosen just enough screws to run nopCommerce under Mono under Linux.
Build: 0 Errors, 54 Warnings.
That's a good place to be. Since EntityFramework project compiled, I commited the changes to the git repository so it would serve as a checkpoint in case I needed to revert any changes I make to the framework.
I replaced the EntityFramework references from the nopCommerce project and use the Entity Framework project as reference instead. Changes would be made only to Nop.Data project and the other projects under the Libraries solution folder for now. I also upgraded the projects from Mono / .Net 4.0 to .Net Framework 4.5 as that's the version EntityFramework would compile under due to other dependencies that are only available under .Net Framework 4.5. Recompiling gave only one error though enough to halt compilation of the project.
Libraries/Nop.Data/Extensions.cs(19,19): Error CS0234: The type or namespace name `Objects' does not exist in the namespace `System.Data'. Are you missing an assembly reference? (CS0234) (Nop.Data)
This was in reference to System.Data.Objects namespace needed on that class. A quick examination revealed that ObjectContext also had an issue and the only way to fix it was to include System.Data.Entity.Core.Objects in the project. This was coming from the EntityFrameworks project I included in the solution. Since I was tracking my changes in Git, I renamed all System.Data.Entity.Core to System.Data to see what it'd do.
Buid: 49 Errors, 34 Warnings.
Most of these were instances of EntityState and DbFunction references complaining for missing System.Data.Entity namespace directive. Many more errors were revealed once these errors were resolved but fortunately those required the same fix. Once all the errors were resolved, I tried replacing the references from EntityFramework.dll, System.Data.Entity.dll, and System.Web.Entity.dll with the EntityFramework project in their place. The changes made to the files under EntityFramework solution folder would only be commited to Git if replacing the Entity Framework references did not generated any namespace related errors.
As mentioned earlier, the projects under the Library solution folders would have to be upgraded to use .Net Framework 4.5 from Mono / .Net 4.0 profile since Entity Framework requires .Net Framework 4.5 features. Similarly projects under the Presentation solution folder would need to be upgraded to use .Net Framework 4.5 and references to EntityFramework.dll and System.Data.Entity.dll would need to be replaced with the project reference to EntityFramework project instead. Since all these projects compiled well without any errors, I commited the changes made to EntityFramework projects to Git.
System.InvalidOperationException
I had seen this before. A small change in Global.asax.cs file was needed to resolve this. Adding the following lines in the beginning of Application_BeginRequest function and including the necessary namespace references does the trick.
var ob = typeof(AspNetRequestScopeStorageProvider).Assembly.GetType("System.Web.WebPages.WebPageHttpModule").GetProperty("AppStartExecuteCompleted", BindingFlags.NonPublic | BindingFlags.Static);
System.IO.DirectoryNotFoundException
Now I was getting somewhere. Searching for the path reference in the code took me to the InstallationLocalizationService.cs file which passes the location string to webHelper.MapPath method. This took me to MapPath function in the WebHelper.cs file in Nop.Core project. The else block was written for Windows environment. This was done by the .Replace('/', '\\') method. Searching for that string pattern revealed two places total where this was used. I could check for OperatingSystem information before deciding to use the Replace function. Surrounding the code with "if(Environment.OSVersion.Platform != PlatformID.Unix)" should be sufficient. Recompiling gave no errors but running the project again did. It is a different error this time.
At first glance it looked counterintuitive because ~/Views/Install/Index.cshtml did exist, but taking a closer look revealed that the system was looking for index with lower case "I" instead of upper case. I changed the URL in the address bar and used Install with upper case "I" and that landed me on the installation page.