Friday, September 18, 2009
Maven Compiler Tips and Tricks
Apache’s Maven is a great tool for managing a build environment: it keeps track of all project dependencies and provides a number of configurable build phases which can add depth to the build process. Building a project from the ground-up with Maven is a sure-fire way to keep it well organized and easy to maintain – but what about adding Maven on to an existing project, or worse, merging a non-Maven project into a project that already relies on Maven?
What follows is a look at some of the lessons I’ve learned from tweaking compiler plug-ins and digging through search results to debug various Maven-related issues. Hopefully it will be useful to the next developer who happens to hit similar issues, and if you have tips of your own be sure to leave a comment.
The maven-compiler-plugin <include> property
When overriding the default maven-compiler-plugin, the <include> tag may be used to force the compiler to include extra files into the build. There are a couple of interesting points to note here:
It is a filter. Many things in Maven expect a path to a directory, but not the <include> tag. If you have some extra java classes in src/main/java and you pass that to <include> it will fail silently – what you actually want is src/main/java/**/*.java.
It is for the compile-phase only. By default, in addition to using the maven-compiler-plugin during the compile phase, Maven will also use it during the test-compile phase. Most properties will apply to both, but <include> is not one of them; the test-compile phase requires a separate property, <testIncludes>, for any includables it requires[1].
The generate-sources and generate-resources phases
These phases are great for adding source (.java) and resource (.class) files to the compiler before the compile phase occurs. The snippet below shows how to use mojo's build-helper-plugin to add some obscure .class files to the classpath:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>../obscure/classes</directory>
</resource>
</configuration>
</execution>
</executions>
</plugin>
Now any .class files in ../obscure/classes (or any subdirectories) will be added to the classpath.
The same plug-in is used for adding .java files, simply tweak the generate-resources and add-resource values to generate-sources and add-source, and the <resources> and <resource> properties to <sources> and <source>.
The maven-compiler-plugin <compilerArgument> property
The <complierArgument> tag may be used to pass command-line arguments directly to the java compiler. Two examples:
<classpath> seems like it would let you add resources to the classpath, but near as I can tell, these aren’t actually used. Maven seems to prefer managing its own classpath, though we can still add/remove entries by overriding the default generate-resources phase (as explained above).
<sourcepath> is a great way to specify multiple source directories for compilation. It takes a semicolon-delimited list of top-level directories containing java files to compile. Alternately, an override of the generate-sources phase may be used here as well.
One gotcha with regards to sourcepath: to get this to work, I had to manually set <fork> to true on the maven-compiler-plugin. In fact, this gets even worse: when <fork> is true, Maven will use the %PATH% environment variable to determine which JRE to use, and this will fail with a totally non-descript error if the path to your JRE contains any spaces – very annoying to track down. This is actually a bug in Maven, logged here (http://jira.codehaus.org/browse/MCOMPILER-30).
The <sourceDirectory> property
A minor but important tag when playing around with various sources and resources, the <sourceDirectory> tag may be used to set the base directory for including java source files. It defaults to src/main/java, but I found when playing around with a lot of sources spread around various directories, it was easiest to set it to the current directory as follows:
<build>
<sourceDirectory>.</sourceDirectory>
{...}
</build>
Other useful debugging hints
When running into problems, it’s always good to have a few debug flags around to get a little more information out of Maven, which is generally not great at telling you what might be wrong.
Specifying the -e flag while running Maven will print out any exceptions Maven encounters, with the corresponding stack trace.
The <verbose> tag may be added inside any plug-in’s <configuration> property and when toggled to true (default is false) it will print some extra information, including the sourcepath and classpath being used by Maven’s compiler.
Specifying the -X flag while running Maven will document all kinds of intermediate steps Maven takes during the build – much more than -e and <verbose>.
[1] This makes perfect sense, of course: it’s unlikely that you’ll want the same includables for both the normal compiler and the testing compiler. It’s just counter-intuitive compared to the rest of the <configuration> properties.
Friday, July 17, 2009
Here I am!
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);Now that we have location manager we need to request location updates from it. The location is requested using requestLocationUpdates method, it registers the current activity to be notified periodically by the named provider. In our case provider is GPS. For tracking location changes we are using LocationListener which is for receiving notifications from the LocationManager when the location has changed.
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, new LocationListener() { public void onLocationChanged(Location location) { double lat = location.getLatitude(); double lng = location.getLongitude(); latitude.setText( Double.toString( lat ) ); longitude.setText( Double.toString( lng ) ); } public void onProviderDisabled(String provider){} public void onProviderEnabled(String provider){} public void onStatusChanged(String provider, int status,Bundle extras){} });
Just getting last known location...
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);Good! We got the location. Now we just need to generate the URL and send SMS. Android offers full access to SMS functionality from within your applications with the SMSManager. We are geeting a reference to the SMS Manager using the static method SmsManger.getDefault. For sending SMS message use sendTextMessage, which allows you to send SMS message by specifying text message and receiver's phone number.
final SmsManager sm = SmsManager.getDefault(); String phoneNumber = number.getText().toString(); String URL = "http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q="; URL += latitude.getText() + "," + longitude.getText(); sm.sendTextMessage(phoneNumber, null, URL, null, null);That's it! Just one note - in order to send SMS message and request GPS location application require following two permissions:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.SEND_SMS"/>
Thanks to my friend Aaron Olson from Macadamian for the help in testing this code.
Source
Thursday, June 04, 2009
Using Mate to Dispatch Events with a Callback in ActionScript
I ran into a situation not too long ago where I had to dispatch an event with a callback from a service-like class. Since this wasn't a UI component, there was no corresponding MXML. I needed a pure-ActionScript solution, but still wanted to use Mate. In a matter of minutes, I had no problem dispatching my event*:
public class TestClass
{
public function generateEvent():void
{
var event:TestEvent= new TestEvent();
event.type = TestEvent.TYPE;
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.generator = TestEvent;
dispatcher.dispatchEvent( event );
}
}
This was a good start, but I wanted to specify a method within the same service-like class to be called if the event returned successfully. Mate's dispatcher tag makes this very easy, but without any MXML, it was not an option. All the handler for the event does is generate a result or fault using Mate's ServiceResponseAnnouncer, so I needed a way to specify the callback from my dispatcher: just like the MXML tag allows, but using only ActionScript.
Looking through the docs didn't get me very far. The section on the Dispatcher provides information on using a dispatcher in ActionScript, but without a callback, and there is a section on using callbacks, but specific to the MXML implementation. I checked the ResponseHandler classes as well, and poked around a bit on Google without much luck.
Knowing that these properties exist, I attempted to piece it together myself (and eventually succeeded). In case anyone else ever runs into the same issue, and because I'd rather not go through all that searching/trial-and-error again, here is a working solution:
public class TestClass
{
public function generateEvent():void
{
var event:TestEvent= new TestEvent();
event.type = TestEvent.TYPE;
var handler:ResponseHandler = new ResponseHandler();
handler.type = ResponseEvent.RESULT;
handler.method = myCallback;
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.generator = TestEvent;
dispatcher.responseHandlers = [handler];
dispatcher.dispatchEvent( event );
}
private function myCallback(event:ResponseEvent):void
{
trace( "callback reached!" );
}
}
One of the hardest parts to figure out was what method signature was required for the callback function. I found my answer in a comment in the ResponseHandler class - one more reason why open source frameworks and well commented code are the way to go!
*Aside: if a callback is not necessary, there's no need to use Mate. In fact, Mate's best practices specifically encourage using Flex's built-in dispatchEvent() method. Had I not needed a callback here, I could have called dispatchEvent() on the parent application (or any other DisplayObject within the scope of my service class).
Monday, May 11, 2009
XBAP - Using the Popup Control as a Dialog Box
How many people have experienced the modal pop up in desktop applications? They are commonly used across a wide variety of applications, one could say, too commonly used. While not appropriate for all situations, sometimes you need to use a pop up.
In XBAP applications the ability to open a pop-up is very limited; in many cases you will use navigation and multiple pages instead of separate windows. In most cases this is sufficient, but sometimes you really need to use a pop-up, and when you do a simple work around is to use the Popup control offered by WPF.
First, you define the Popup in the markup, making sure to set its StaysOpen property to true so it will remain open until you close it. (There’s no point in using the PopupAnimation or AllowsTransparency properties, because they won’t have any effect in a web page.) Include suitable buttons, such as OK and Cancel, and set the Placement property to Center so the popup will appear in the middle of the browser window.
Code sample:
<Popup Name="dialogPopUp" StaysOpen="True" Placement="Center" MaxWidth="200">
<Border>
<Border.Background>
<LinearGradientBrush>
<GradientStop Color="AliceBlue" Offset="1"></GradientStop>
<GradientStop Color="LightBlue" Offset="0"></GradientStop>
</LinearGradientBrush>
</Border.Background>
<StackPanel Margin="5" Background="White">
<TextBlock Margin="10" TextWrapping="Wrap">Please enter your name.
</TextBlock>
<TextBox Name="txtName" Margin="10"></TextBox>
<StackPanel Orientation="Horizontal" Margin="10">
<Button Click="dialog_boxOK_Click" Padding="3" Margin="0,0,5,0">OK</Button>
<Button Click="dialog_boxCancel_Click" Padding="3">Cancel</Button>
</StackPanel>
</StackPanel>
</Border>
</Popup>
At the appropriate time (for example, when a button is clicked), disable the rest of your user interface and show the Popup. To disable your user interface, you can set the IsEnabled property of some top-level container, such as a StackPanel or a Grid, to false. (You can also set the Background property of the page to gray, which will draw the user’s attention to Popup.) To show the Popup, simply set its IsVisible property to true.
Here’s an event handler that shows the previously defined Popup:
private void popupTriggerButton_Click(object sender, RoutedEventArgs e)
{DisableMainPage();
}
private void DisableMainPage()
{ mainPage.IsEnabled = false; this.Background = Brushes.LightGray; dialogPopUp.IsOpen = true;}
When the user clicks the OK or Cancel button, close the Popup by setting its IsVisible property to false, and re-enable the rest of the user interface:
private void dialog_boxOK_Click(object sender, RoutedEventArgs e)
{ // Copy name from the Popup into the main page. lblName.Content = "You entered: " + txtName.Text;EnableMainPage();
}
private void dialog_boxCancel_Click(object sender, RoutedEventArgs e)
{EnableMainPage();
}
private void EnableMainPage()
{ mainPage.IsEnabled = true;this.Background = null;
dialogPopUp.IsOpen = false;}
Using the Popup control to create this workaround has one significant limitation. To ensure that the Popup control can’t be used to spoof legitimate system dialog boxes, the Popup window is constrained to the size of the browser window. If you have a large Popup window and a small browser window, this could chop off some of your content. One solution is to wrap the full content of the Popup control in a ScrollViewer with the VerticalScrollBarVisibility property set to Auto.
If a Popup isn’t suitable for you, you can try another more “interesting” approach for showing a dialog box. Using the Windows Form library from .NET 2.0 you can safely create and host any WinForm control in your WPF application. In this case, you can create and show an instance of the System.Windows.Forms.Form class (or any custom form that derives from Form), because it doesn’t require unmanaged code permission. In fact, you can even show the form modelessly, so the page remains responsive. The only drawback is that a security balloon automatically appears superimposed over the form and remains until the user clicks the warning message. You’re also limited in what you can show in the form. Windows Forms controls are acceptable, but WPF content isn’t allowed.
Labels: .NET, c#, code sample, popup, WPF, XBAP
Monday, April 27, 2009
FlexDock
The component which is actually our "box" is called CanvasBox. For expanding the boxes I prefer to use Caurina Tweener, it is also possible to use built-in mx.effects.Resize, but I prefer Caurina Tweener's one:
private var _rollOverTween:Object = {width:200, height:200, time:0.45, transition:"easeOutBack", onComplete:onRollOver};
private var _rollOutTween:Object = {width:90, height:90, time:0.2, transition:"linear", onComplete:onRollOut};
When the user clicks on the button the Tweener.addTween( this, _rollOverTween); method is called, it is possible to change the content of the box in the click handler, but if you want your UI not to be broken it is better to do those changes in the onComplete handler of the tween.
Besides the CanvasBox component we also need to have a component which will hold the boxes. It is called BoxHolder and it is template component. It has _content field which is storing the boxes, pay attention at [ArrayElementType("CanvasBox")]:
// An array which stores the UI components
// of our content
[ArrayElementType("CanvasBox")]
private var _content:Array;
Every time you click on a box, the closeOthers method is called which is shrinking previously expanded box.
private function closeOthers(event:MouseEvent):void
{
for each(var component:CanvasBox in _content)
{
if(component != event.currentTarget)
{
component.roolOut();
}
}
}
DEMO | SOURCE
Tuesday, March 31, 2009
HTML4 and XHTML
More seriously, when dealing with HTML, remember that each version of the specification has specific characteristics. And the application you are using (in my case Atlassian's Confluence), is validating against some version of the specification. Somehow I known this for years, having spent countless hours in the SOAP and WSDL specifications back in my Cognos days. Yet somehow I forgot, its easy to overlook these sorts of things sometimes.
Now the problem I encountered was around the closing tags. In XHTML you can do things like this but not in HTML4:
<iframe src=.../>
So the morale of the story, read the manual and remember the specification! :)
Labels: specification
Monday, March 09, 2009
Single Instance Applications in WPF
In some design scenarios launching multiple copies of the same WPF application is a problem, especially for document-based applications or server applications.
WPF does not provide a native solution for single instance applications; however there are several workarounds for this issue.
The most commonly used solution is to check whether another instance of the application is already running when the Application.Startup event fires. This is easily done using a system wide mutex (provided by the operating system to allow interprocess communication). While this is easily done, it limits the developer’s options by not providing a way for the new instance to communicate with the already running instance. Mainly this will provide only a simple way of limiting the number of running instances to one, while a separate system will be required to handle the new calls (usually through remoting or Windows Communication Foundation).
The recommended and more useful approach is to use the built-in support that’s provided in Windows Forms and originally intended for Visual Basic applications. This approach handles the messy plumbing behind the scenes. This means using an old style application class as wrapper for the WPF application. The wrapper will handle the instance management and will communicate the request to the already running instance of the WPF application.
Solution steps:
1) Add a reference to the Microsoft.VisualBasic.dll assembly.
2) Add a new custom class derived from the Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase class.
3) The IsSingleInstance must be set to true in the constructor. This enables a single instance application.
4) Override the OnStartup() method to create the WPF application object. (Note: The OnStartup() method is triggered when the application starts)
5) Overide the OnStartupNextInstance() method to handle future instances. (Note: The OnStartupNextInstance() method is triggered in when another instance of the application starts up)
6) Define a Main entry point for the application and create the wrapper object
7) Create the WPF application class
Sample of the application wrapper:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Microsoft.VisualBasic.ApplicationServices;using System.Windows;namespace SingleInstanceApplication{ //The Main entry point classpublic class Startup
{[STAThread]
public static void Main(string[] args)
{ SingleInstanceAppWrapper wrapper = new SingleInstanceAppWrapper();wrapper.Run(args);
}
}
//The old-style application wrapperpublic class SingleInstanceAppWrapper : WindowsFormsApplicationBase
{ public SingleInstanceAppWrapper() { // Enable single-instance mode.this.IsSingleInstance = true;
}
// Create the WPF application class. private WPFApplication _app; //Override OnStartup() method to create the WPF application objectprotected override bool OnStartup(
Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{ _app = new WPFApplication();_app.Run();
return false;
}
// Override OnStartupNextInstance() to handle multiple application instances.protected override void OnStartupNextInstance(
Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs e)
{ //In case of command line arguments, send them to the WPF application object if (e.CommandLine.Count > 0) {_app.HandleCommandLine(e.CommandLine);
}
}
}
}
As you can see, the sample above contains the Main entry point for the application. This is required because the wrapper must be created first.
If Visual Studio is used, by default the App.xaml application definition style is used. This will not work with the wrapper because the App.xaml approach already has a Main entry point.
Remove App.xaml and App.xaml.cs from the project and create a new class for the entry point.
The only thing left to do is to create the WPF application definition:
public class WPFApplication : System.Windows.Application
{ //Override the OnStartup() methodprotected override void OnStartup(System.Windows.StartupEventArgs e)
{ base.OnStartup(e); //Load the main window Window _MainWindow = new Window();_MainWindow.Show();
//Set the MainWindow property for the WPF application object this.MainWindow = _MainWindow;}
//Method used to handle command line argumentspublic void HandleCommandLine (System.Collections.ObjectModel.ReadOnlyCollection<string> e)
{ //Code to handle command line arguments from other instances goes here}
}
Because the wrapper approach does not contain a XAML application definition (App.xaml), if you need to load application level resources, the following code can be placed the OnStartup() of the WPF application definition to load the resources from a resource dictionary:
Application.Current.Resources.MergedDictionaries.Add(
Application.LoadComponent(
new Uri("AssemblyName;component/ApplicationResourceDictionary.xaml",
UriKind.Relative)) as ResourceDictionary);The above code will work for dynamic resource definitions. The static resource lookup process will fail because the source for the application resources dictionary need to be specified. In that case the code to load the resources will be replaced with the following:
Application.Current.Resources.Source =
new Uri("/AssemblyName;component/ApplicationResourceDictionary.xaml", UriKind.Relative);
Note: AssemblyName is a placeholder for the actual assembly name. The Uri for the resource dictionary location can be changed as required.
Labels: .NET, c#, embedded, Visual Basic, Win32, WPF