Android Studio and Library Projects
This is basically a quick brain-dump post. I have previously attempted to get into Android application development, but with only 8-10 hours of "free" time per month, it was difficult to get traction with an app before the goog machine overhauled everything. This happened repeatedly. I had some great ideas for a mobile app over the weekend, and thought I'd give it another go and guess what? Everything is overhauled: Android Studio is the next big thing, ant builds are out and gradle builds are in. I decided to force myself to overcome my annoyances and try out Android Studio.
Android Studio is beautiful and operationally stable, although very buggy. I've found four bugs in less than two days. The biggest bug and usability issue, however, is in creating an Android Library project and adding a reference to it in another project.
Here are the steps I took to reference another project. These steps may not be accurate, but I don't care. I figured they may help save someone some time.
-
Create an Android library project using Android Studio.
There’s a bug in Android Studio 0.1.3 which apparently does not mark android library projects as library projects, so navigate to MyLibProject/MyLib and change the android plugin reference to:
apply plugin: 'android-library'
- Create a main application project, in my case MyApplication2
- Add library as git submodule or nested directory under MyApplication2
- Edit settings.gradle in the main project to:
include ':MyLibProject:MyLib’, ':MyApplication2'
- Edit MyApplication2/build.gradle to compile the lib project in the dependencies task:
compile project(':MyLibProject:MyLib’) - Navigate to your library subdirectory and execute:
gradle clean && gradle assemble
- Press CTRL+ALT+SHIFT+S to open the Project Structure dialog
- Create a new module, change module name and point content root to MyLibProject
- Change Package name to the package name of your lib and press Finish
- Click MyApplication2 (not MyApplication2Project) in the Project Structure dialog and select the Dependencies tab.
- Click the green plus icon and select Library|Java
- Select MyLibProject/MyLib/build/bundle/release folder, choose Project Library, and hit ok
- Save. The library should now be usable.
These instructions may seem a bit hurried, but it should get the job done. I've run through numerous attempts at different options, and these are the only ones that seem to have stuck.
I might also mention, I've created an ANDROID_HOME environment variable to load in my shell which points to the sdk directory under the android-studio installation. I've also downloaded gradle-1.6 to ~/bin, and symlinked gradle to ~/bin/gradle which adds gradle to my path.
“Unable to update the dependencies of the project”
I've recently had to switch from Visual Studio 2012 back to Visual Studio 2010 to do maintenance on another project. This project is currently stuck in Visual Studio 2010 until I have time to convert the old setup projects to WiX. I often receive the following error message during Release builds:
"Unable to update the dependencies of the project"
Closing Visual Studio 2010 and reopening seemed to have fixed the problem up until about a week ago. I've found that installing this hotfix seems to resolve the issue. The only problem is that I've had to install the hotfix multiple times.
The 'cause' on the hotfix page says the issue is a result of how Visual Studio 2010 refreshes dependencies. I wonder if this is handled by Windows Updates updating the .NET Framework? Whatever it is, it's pretty annoying to have to apply this patch regularly. I guess it's just another reason for developers to move setup projects to WiX.
git push: fatal: unable to read SHA1
Today, I was faced with an interesting error in a git repository. I am backing up a lot of old projects from during and after college into a private git repo. In doing so, I moved some folders around which disconnected a couple of binary files. After pushing, I received an error: unable to read [SHA1].
The fixes, in short:
$ git fsck $ git log --raw --all --full-history | grep SHA1-HERE $ git hash-object -w OBJECT-PATH-HERE $ git push
Here is the error and a walk-through of coming up with the fixes above:
jim at schubert in /media/16GB/projects/school on master $ git push Password: Counting objects: 1945, done. error: unable to find 2978ec4d75abb8c6bab225d8adfbd2bef064338a error: unable to unpack bddbd13afd698e5ba7d572c9270e52bcac862661 header error: inflateEnd: failed Delta compression using up to 2 threads. Compressing objects: 100% (1854/1854), done. fatal: unable to read 2978ec4d75abb8c6bab225d8adfbd2bef064338a fatal: The remote end hung up unexpectedly fatal: The remote end hung up unexpectedly fatal: write error: Bad file descriptor
After running git fsck, I found that I had two missing blobs:
jim at schubert in /media/16GB/projects/school on master* $ git fsck dangling tree dbe9172996edbb7df517b0305c38891d78b72f66 dangling tree fbf7d8336b5f2347da23eb8a3938de5ab18f783c missing blob 2978ec4d75abb8c6bab225d8adfbd2bef064338a missing blob bddbd13afd698e5ba7d572c9270e52bcac862661
To fix this, I had to get the filenames of these blobs and write them back into the repository:
jim at schubert in /media/16GB/projects/school on master* $ git log --raw --all --full-history | grep bddbd13 :000000 100644 0000000... bddbd13... A INFO 465/Project2/UseCase/Diagrams/Leader - Time & Mileage.vsd jim at schubert in /media/16GB/projects/school on master* $ git log --raw --all --full-history | grep 2978ec4 :000000 100644 0000000... 2978ec4... A INFO 465/Project2/Prototype/WebPrototype/WebPrototype/bin/WebPrototype.dll
Writing these files back into the repository, the push was successful. To write these back, do the following:
jim at schubert in /media/16GB/projects/school on master $ git hash-object -w INFO\ 465/Project2/UseCase/Diagrams/Leader\ -\ Time\ \&\ Mileage.vsd bddbd13afd698e5ba7d572c9270e52bcac862661 jim at schubert in /media/16GB/projects/school on master $ git hash-object -w INFO\ 465/Project2/Prototype/WebPrototype/WebPrototype/bin/WebPrototype.dll 2978ec4d75abb8c6bab225d8adfbd2bef064338a
System.Data.OracleClient and Windows 7… love at first sight!
</sarcasm>
I spent nearly two days trying to resolve this issue. My new desktop at work is running Windows 7 (64-bit) and some of our applications are still using System.Data.OracleClient as an adapter instead of Oracle's own ODP.NET. Microsoft's driver interops with Oracle's own client installed on the developer machine (oci.dll). We need to continue running our web applications under 32-bit IIS, which is where the problem lies.
FYI... According to Microsoft:
The types in System.Data.OracleClient are deprecated. The types are supported in version 4 of the .NET Framework but will be removed in a future release. Microsoft recommends that you use a third-party Oracle provider.
Back to the comment about IIS. Apparently, IIS 7 in Windows 7 is 64-bit only. Yes, you can set an application pool to 32-bit. That would be perfectly fine, except that Oracle's client native methods don't like running through WoW64. So, you have to install both the 64-bit client and the 32-bit client. After all, 32-bit adapter code can't call a 64-bit client. If you fire up procmon, though, you'll see that calling the 32-bit Oracle client still queries 64-bit settings (and fails if they don't exist). WoW64!, indeed.
Continue reading to see my resolution...
Note: this forces Oracle 11.2.0.1 to use 32-bit only in a 64-bit environment.
Hostgator: ssh warns ‘too many authentication failures’
I requested for HostGator to provide ssh access. Since then, I haven't used it. I attempted to ssh into the server today and received the message 'too many authentication failures'.
If you haven't done so already, create a PubKey:
ssh-keygen -t dsa
The ssh-keygen program will ask a few questions such as the key name and the passphrase. Enter whatever you'd like. I'll refer to the file as id_dsa.pub (which is the default name).
Navigate to your .ssh directory:
cd ~/.ssh
Make sure your file exists in this directory.
Now this one-liner does it all:
cat ~/.ssh/id_dsa.pub | ssh -p 2222 -o PubkeyAuthentication=no user@hostname 'cat >> .ssh/authorized_keys'
If you're not familiar with the linux pipe, I will explain a bit. If you understand the above command, you're done. Enjoy.
The first part before the vertical line {the '|' is called a pipe) dumps all of the text (cat) inside the file (~/.ssh/id_dsa.pub) into STDOUT, or the standard output stream. The pipe forces STDOUT from before the pipe to become STDIN (standard input) for the command after the pipe. Normally, on HostGator you would open an ssh session with ssh -p 2222 user@hostname. But, because there is a conflict in either existing keys on your machine or the authentication of those keys on the server, you'll have to add -o PubkeyAuthentication=no. Finally, the command within single quotes at the end dumps the text in STDIN into a file handle (the '>' causes the dumping of this text to redirect STDIN to an existing filehandle, while two of those characters '>>' redirects to a file, creating the file if it doesn't exist).
Can’t login to MySQL as root :(
I was having issues logging into MySQL as root the other day. It took a while to figure things out. Ultimately, I had to follow the steps on two separate posts: http://rimuhosting.com/howto/mysqlinstall.jsp and http://bugs.mysql.com/bug.php?id=22118.
Here are the steps I took:
- Stop MySQL:
/etc/init.d/mysql stop
- Edit config:
sudo vim /etc/my.cnf
- Add line to section [mysqld]:
skip-grant-tables
- Start MySQL:
/etc/init.d/mysql start
- Reset Root Password:
mysql -e "update user set password = old_password('newpassword') where user = 'root'" mysql - Kill MySQL:
kill `cat /var/run/mysqld/mysqld.pid`
- Create an init-file:
cat ~/mysql-init<<EOF UPDATE mysql.user SET Grant_priv='Y', Super_priv='Y' WHERE User='root'; FLUSH PRIVILEGES; GRANT ALL ON *.* TO 'root'@'localhost'; EOF
- Run MySQL with the init file:
mysqld_safe --init-file=~/mysql-init &
- Remove the mysql-init file:
rm ~/mysql-init
- Restart MySQL:
/etc/init.d/mysql restart
- Login as root!
Part of this was also taken from the MySQL documentation for resetting a password, however, the contents of the file were changed to match one of the previously mentioned posts. If these steps don't work, please visit the official documentation and give it a try again.
**IMPORTANT**
When you're done following the above steps, please remove 'skip-grant-tables' from my.cnf. Thanks, Ian, for bringing this missed step to my attention!
Learning WCF: IIS 7 won’t start service from web project
I'm following along with code in Learning WCF, attempting to quickly become an expert at building WCF Services from scratch. In Chapter 1, there is a project called IISHostedService. After making the quick modifications to the downloaded code, and running the application, IIS 7.0 (Windows 7, 64bit) doesn't serve the services, complaining about adding a MIME type. I thought this was rather fishy, because I've created WCF Services while in school under Windows XP and they ran fine.
It turns out that I didn't have WCF properly setup. To do so, you have to run
C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\servicemodelreg -i
This will provide the following output (which is everything I was missing):
Microsoft(R) Windows Communication Foundation Installation Utility [Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.4926] Copyright (c) Microsoft Corporation. All rights reserved. Installing: Machine.config Section Groups and Handlers (WOW64) Installing: Machine.config Section Groups and Handlers Installing: System.Web Build Provider (WOW64) Installing: System.Web Compilation Assemblies (WOW64) Installing: HTTP Handlers (WOW64) Installing: HTTP Modules (WOW64) Installing: System.Web Build Provider Installing: System.Web Compilation Assemblies Installing: HTTP Handlers Installing: HTTP Modules Installing: Protocol node for protocol net.tcp (WOW64) Installing: TransportConfiguration node for protocol net.tcp (WOW64) Installing: ListenerAdapter node for protocol net.tcp Installing: Protocol node for protocol net.tcp Installing: TransportConfiguration node for protocol net.tcp Installing: Protocol node for protocol net.pipe (WOW64) Installing: TransportConfiguration node for protocol net.pipe (WOW64) Installing: ListenerAdapter node for protocol net.pipe Installing: Protocol node for protocol net.pipe Installing: TransportConfiguration node for protocol net.pipe Installing: Protocol node for protocol net.msmq (WOW64) Installing: TransportConfiguration node for protocol net.msmq (WOW64) Installing: ListenerAdapter node for protocol net.msmq Installing: Protocol node for protocol net.msmq Installing: TransportConfiguration node for protocol net.msmq Installing: Protocol node for protocol msmq.formatname (WOW64) Installing: TransportConfiguration node for protocol msmq.formatname (WOW64) Installing: ListenerAdapter node for protocol msmq.formatname Installing: Protocol node for protocol msmq.formatname Installing: TransportConfiguration node for protocol msmq.formatname Installing: HTTP Modules (WAS) Installing: HTTP Handlers (WAS)
Oracle Exception: Could not load file or assembly ‘Oracle.DataAccess, Version=2.111.7.20…
Last week, I was having performance issues with my workstation. I was told to remove unused files and applications. I had previously installed ODAC 11g for the Oracle Data Providers. After realizing they were not backwards compatible with the Oracle10g providers we're using in production, I removed ODAC 11g using the Oracle Universal Installer. Apparently, that doesn't completely remove references to the 11g client or components.
After removing files and directories, I began receiving the following error when accessing an application locally:
Exception message: Could not load file or assembly 'Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
To see what Oracle libraries are installed in the GAC, I ran the following command from a Visual Studio command prompt:
gacutil /l | find /i "Oracle" > c:\Scripts\oracle.txt
This gave me the following list (note: Oracle 2.111.7.20 libraries are installed by ODAC 11g)
Oracle.DataAccess, Version=2.102.2.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86 Oracle.Management.Omo, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86 Oracle.VsDevTools, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86 Oracle.Web, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86 Policy.2.102.Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86 System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86 Oracle.DataAccess, Version=1.102.2.20, Culture=neutral, PublicKeyToken=89b483f429c47342 Oracle.DataAccess, Version=1.102.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342 Oracle.Management.Omo, Version=1.102.2.20, Culture=neutral, PublicKeyToken=89b483f429c47342 Oracle.VsDevTools, Version=1.102.2.20, Culture=neutral, PublicKeyToken=89b483f429c47342 Policy.1.102.Oracle.DataAccess, Version=1.102.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342 Policy.10.1.Oracle.DataAccess, Version=1.102.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342 Policy.10.2.Oracle.DataAccess, Version=1.102.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342 Policy.9.2.Oracle.DataAccess, Version=1.102.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342 System.Data.OracleClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
I have spent a week trying to figure out why these libraries wouldn't uninstall from the GAC and why I couldn't possibly remove them from the Oracle Universal Installer.
To manually uninstall these libraries, you'll have to run the following commands from a Visual Studio Command Prompt:
gacutil /u "Oracle.Management.Omo, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86" gacutil /u "Oracle.VsDevTools, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86" gacutil /u "Oracle.Web, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86" gacutil /u "Policy.2.102.Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86"
Here's the part that got me: I installed ODT, not just ODAC. This comes with a number of add-ons for Visual Studio (including Health Monitoring and Profiling). So, you have to manually edit the machine.config to get everything completely removed.
So,
Edit C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config and remove all references from the above libraries.
After following these steps, I was finally able to load the application locally using the ODAC/ODP.NET libraries for Oracle 10g.
Fluent NHibernate error: Unable to cast object of type ‘Oracle.DataAccess.Client.OracleConnection’ to type ‘System.Data.Common.DbConnection’.
After developing an application in Fluent NHibernate, I've received the following Error and Stack Trace:
Unable to cast object of type 'Oracle.DataAccess.Client.OracleConnection' to type 'System.Data.Common.DbConnection'. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.InvalidCastException: Unable to cast object of type 'Oracle.DataAccess.Client.OracleConnection' to type 'System.Data.Common.DbConnection'. Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. Stack Trace: [InvalidCastException: Unable to cast object of type 'Oracle.DataAccess.Client.OracleConnection' to type 'System.Data.Common.DbConnection'.] NHibernate.Tool.hbm2ddl.SuppliedConnectionProviderConnectionHelper.Prepare() +43 NHibernate.Tool.hbm2ddl.SchemaMetadataUpdater.GetReservedWords(Dialect dialect, IConnectionHelper connectionHelper) +65 NHibernate.Tool.hbm2ddl.SchemaMetadataUpdater.Update(ISessionFactory sessionFactory) +80 NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners) +598 NHibernate.Cfg.Configuration.BuildSessionFactory() +87 FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() +49 [FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail. ] FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() +69 ETeacherWeb.DataAccess.DataSession.get_SessionFactory() +641 ETeacherWeb.HttpModules.NHibernateSessionModule.<Init>b__0(Object , EventArgs ) +8 System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +68 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
The server is running Oracle 9.2 client, without ODP.NET. In order to fix this, I copied version 9.2 libraries to the server.
The libraries required were:
Oracle.DataAccess.dll (application/bin folder)
OraOps9.dll (oracle/9.2/bin)
The above directories will of course be different for you, but they should help. Also, the Oracle bin folder must be accessible via the %PATH% variable.
If possible, the much easier fix is to install a full Oracle client, including ODP.NET.
ArgumentOutOfRangeException : Index was out of range. Fluent NHibernate commit
I came across the error
ArgumentOutOfRangeException : Index was out of range.
while trying to perform a commit on a single entity with 4 nested entities and 3 properties.
I tracked the problem down to one two entities: Country and "Post" which I will refer to as Location.
The objects looked like:
public class Location
{
...
// public virtual string ContactCountry { get; set; }
...
public virtual Country Country { get; set; }
}
public class Country
{
...
public virtual IList<Location> Locations { get; set; }
}
The problem came from the Fluent NHibernate mapping referring to a property on the COUNTRY_CODE field and specifying a HasMany relationship to Country on the same column.
This is an oddity, for sure. But, the better (object-oriented and proper) way to do it would be to change ContactCountry to a getter and return the Country.Code property (if ContactCountry is used elsewhere). Or, call Location.Country.Code only.
Removing the property and mapping for ContactCountry fixed the problem.
