text:
Former SeaWolves Perez, Suarez future Tigers double-play combination
For more than two months during the 2013 season, Erie baseball fans got a glimpse of the possible future middle-infield combination of the Detroit Tigers.
Hernan Perez began the 2013 season with the SeaWolves and Eugenio Suarez was called up to Erie one month into the season. After fans and prospect experts salivated over what could be a terrific combination a few years down the line, the two are closing in on making it a reality in the near future.
"I feel very good playing with him and we are a great combination," said Perez, who is currently with Triple-A Toledo, about Suarez. "It wasn't hard for me to move to second base because I've played there before. I'm just playing hard and doing my best."
Perez, 23, and Suarez, 22, grew up in Venezuela as defensive stars at the shortstop position. Perez was the first to get some major-league experience two seasons ago when he was called up for two games. In 2013, Perez spent 34 games with the Tigers, hitting .197 with five RBIs and 13 runs scored, and he made several highlight-reel defensive plays as well.
Going into Friday, Perez was hitting .261 with 20 RBIs and nine stolen bases in 57 games with the Mud Hens. He was the everyday shortstop for Toledo until Suarez was recently called up. Perez was forced to move to second base to make room in the lineup for his good friend.
"I'm sure the move probably bothered him a little bit at first," said Toledo manager Larry Parrish on Tuesday, one night before Suarez was promoted to Detroit. "Hernan was told he'd be playing a lot of shortstop this year and he's played the position well. He has also played well at second base and is a good, solid ballplayer."
Suarez spent most of spring training in camp with the Tigers before being assigned to the SeaWolves to start the season. He hit .284 with six home runs, 29 RBIs and seven stolen bases in 42 games before getting the call to Toledo. The promotion was short lived as he played 12 games with the Mud Hens before the Tigers called him up on Wednesday afternoon.
"I feel very good about getting called up to Toledo, and it's a big chance for me," said Suarez just hours before he was called up to Detroit. "It's important for my career right now to keep playing every day and seeing good pitching. I want to keep playing hard and help my team win."
Suarez had an inauspicious start to his Tigers career as he injured his left knee sliding into second base on Wednesday night. He missed Thursday's game, which he was supposed to make his first major-league start, and was not in the lineup on Friday.
"Eugenio was red-hot when he first came up here and he's cooled off a little bit," Parrish said. "He's holding his own very well for a first-year guy at this level. He's got some late life in his bat and when he hits it, he can make it jump."
While the young Venezuelans still have some ground to make up with standout shortstop Jose Iglesias and veteran second baseman Ian Kinsler in front of them, the future appears to be bright in Detroit. Suarez and Perez are both young, have big-league experience and continue to produce.
Tigers general manager Dave Dombrowski hasn't been afraid to trade prospects for proven veterans, making it possible that Suarez or Perez could be trade bait if both keep producing.
"He was in big league camp during spring training," said then-Erie manager Chris Cron about Suarez last May. "He was another one of those kids that opened some eyes in a positive manner to the big-league staff."
Suarez is listed as the No. 6 prospect in the Tigers' organization according to MLB.com, while Perez is No. 9. With both continuing to produce at each level, the two could be an impressive middle infield combination in Detroit for years to come.
TOM REISENWEBER can be reached at 870-1707 or by e-mail. Follow him on Twitter at twitter.com/ETNreisenweber. Read the Extra Innings blog at www.GoErieBlogs.com/extra-innings.


text:
Jesse Gallagher
In my last post, I ended up recommending that Domino developers and administrators take some time, if at all possible, to dive into new tools. In some cases, that may be in order to stay indefinitely, but, even otherwise, learning a new environment would have tremendous benefit to your existing Domino work.
Since I'm not a full-time administrator myself, my advice is admittedly a bit thin. It mostly involves my oft-repeated suggestion to try out a reverse-proxy setup for HTTP. That could parlay into use with mail as well, but even just becoming more familiar with a multi-tiered setup and the essentially-standard OpenSSL tools for certificate manipulation would pay dividends.
For developers, there are a great many potential paths to walk, and I think it's extremely useful to at least take one step down each. The use of that reminds me of the "Programming Languages" course I took in college. It involved rapid-fire coverage of C, C++, Scheme, and Prolog - four distinct languages with pretty distinct programming styles (the latter two moreso than the former two), meant to introduce students to the different notions of programming. I don't use Lisp or (lord knows) Prolog in my day-to-day programming life, but having learned a little bit about functional and logic programming at the time has paid dividends over the years.
There are a couple broad topics I can think of that are worth investigating, including ones that we as a community have already been working on.
For the most part, the importance of source control has basically sunk in as a "we should do this" sort of thing in the Domino community. However, the inconvenience associated with maintaining an on-disk project means we're not all the best at doing this religiously. And, indeed, we're often hampered by both old habits and Domino's licensing terms that prevent us from doing this properly: there's a strong strain of "multiple people working on the same NSF" in Domino's history, and that doesn't mix well with source control (or XPages, for that matter).
So I recommend not just knowing about source control, but also trying (as much as licensing allows) to use this as an opportunity to switch to a more "traditional" model for app development. I like to think of this type of development as equivalent to working on a desktop app: it would be madness to have multiple people working in the same Xcode/VS/etc. workspace on the same binary build, and then particularly trying to have an end user also use that resultant binary. Instead, it's better to have each developer work separately on distinct non-replica NSFs, ideally on local dev servers, and then deploy the changes as an NTF.
Java EE in general is a very worthwhile target for interest, especially because it encompasses so many other possibilities. But I'd like to call attention in particular to the WAR file model, which is roughly equivalent to an NSF for app deployment.
When I first learned web programming, with PHP, it followed the "just toss a bunch of files on disk and visit their paths in a web browser" model, which basically worked, but taught some very bad habits. Domino improves on this a bit, with everything in its place in an NSF, but still suffers from a bit of the same malady: the "filesystem" of design elements is what is exposed to the browser directly, URL-wise. In a more fully-app-based system, though, there's a lot more flexibility about how the incoming URLs map to the underlying code and resources, and Java EE's encapsulated nature plays on this well.
With a WAR file, you have the "app container" advantage of an NSF but also gain the "everything after the app name is mine" benefit of a controlled URL router, and that shift helps conceptualize apps as something of a "mount point" onto an app server. So you may have a blog app that you load up as "/blog" on your server, and then that app can control the traffic beneath it, but is similarly a bit walled off from everything above it. It's the sort of "feel" that settle in with time, and then it feels weird to lack that flexibility.
This model also fits particularly well into app platforms like BlueMix or Heroku.
This one's difficult for Domino developers! No matter the tooling used for an NSF, being able to dive into automated testing is difficult. You can coax Maven into running some tests, though that will lack an XPages environment. You can test on the XPages side with JUnit4Xpages, though that won't be part of an automated build without more hoops. There's no real equivalent to the type of fully-fleshed-out testing tools available for other platforms now.
So that's lead to unit/integration/whatever testing not even being on the horizon for most Domino developers. That's particularly a shame because it's already something of a chore to get into the testing habit even when the tools do everything they can to help you. It's essentially like brushing your teeth when you're a kid: you do it because you're told to, but it's not something you'd ever do of your own accord.
It's worth it, though! It will probably require working on a fully non-Domino project, but going through the steps of building a fleshed-out system with automated tests along the way is a valuable experience. The goal is to get to the point where it feels weird to not have tests, much in the same way as lacking source control - an untested change should feel like it doesn't "count". It's a big world, too: beyond just small unit tests, there's tooling to run a web app in a test environment and run user interactions, or do the same on mobile-device simulators.
This dovetails with testing, in that one of the primary benefits of having a build server like Jenkins or Bamboo is that they can act as a neutral, clean environment to build the whole app and run the tests, informing you of any errors or failures. This is another thing that's made much more difficult by Domino, though it's possible.
Beyond testing, having a build server reaps benefits with project organization and delivery pipelines. Jenkins's recent updates have focused on that sort of thing, where the tool will help you manage pulling down the latest code from SCM, building it, and then deploying the results to dev or live servers, as desired. Build servers won't necessarily change the way you develop, but they will prove to be a faithful companion, with more uses the more you get comfortable with them.
Get comfortable with the command line. Other than Microsoft's tooling, which has a very schizophrenic relationship with the CLI, basically all modern development environments swim in the Unix world. Not everything has to be done via CLI - certainly, it's much more comfortable to use SourceTree than to do all git commands manually - but it's hard to find a tutorial that doesn't have at least a few tossed-off terminal commands. Mac- and Linux-based developers are at a distinct advantage with this, but Windows has Cygwin and the ported Linux userland in the next Windows 10 release.
Along this line, it's tremendously useful to have a bit of Linux server admin knowledge. I recommend either spinning up a Linux VM locally (Ubuntu has served me well) or using Linode. Linode in particular is so cheap and convenient that it's very much worth tossing them a couple bucks to run a server for a little while with full confidence that you can melt it into the ground without consequence. The delightful iOS-focused podcast Under the Radar had an episode on this topic a while back that's worth a listen.
You should probably also learn a little about vi.
Back in the realm of pure programming knowledge, it's extremely valuable to learn about MVC and related concepts. XPages sort of brought this to the Domino world, but it suffered from lack of wholehearted adoption and its legacy baggage made it very difficult to really go full MVC even if you wanted to.
The good news is that essentially every other active framework encourages or enforces this approach. When diving into one, it can be a bit jarring at first - there's a lot of "ugh, can't I just put the code here?" going on - but it falls into place very quickly.
Picking a place to start is a daunting prospect, given the ever-shifting sands of the modern development world.
One of my favorite tutorials for a web framework is Michael Hartl's Rails tutorial, which is kindly available for free online (with options to purchase other forms). It not only provides an up-to-date introduction to Rails development, but also covers a lot of the other ground mentioned above: the command line, Heroku, Git, and test-driven development.
In another direction, I recommend taking a look at Meteor, which is something of an all-in approach to JavaScript-based development. It does an interesting job blurring the lines between client and server and makes a very compelling case for "JavaScript everywhere".
Beyond that, really just learning any development toolchain will help. There's not too much need to sweat picking "the right one" at each step - any knowledge gained in one will help in others, either directly or by giving you some additional perspective. The most important thing, especially now, is learning something.
It's pretty easy to see that change is in the air for Domino types. It's been taking a number of forms for a while now - the long delay since the release of 9.0.1 and associated aging of the tools and infrastructure have led to a series of forced adaptations for developers and administrators. Developers, for example, have had to keep light on their feet to adapt to new browsers and devices that the framework doesn't automatically support, as well as a shift toward manually including jQuery and other tools that have a bit more wind at their back than Dojo. Administrators, for their part, have had a series of heart attacks related to SSL and other security matters, usually involving a a lot of noise followed by (unfortunately, I feel) a good-enough patch from IBM.
That sort of thing isn't likely to get any smoother. In large part, that's entirely distinct from anything IBM does: the genie's out of the bottle when it comes to fast-moving platforms, and the best we can hope for is a sort of still-moving linga franca that can be sort-of-stable on the majority of targets. But then part of that is Domino: for all its virtues, it hasn't adapted for the modern world, no matter how much some of us would have liked it to. And that's had some negative side effects on us as a customer base, side effects that manifest as a gut-reaction rejection of the modern ways of doing things.
Take the SSL thing, one of my soap boxes: though the immediate problem could be summarized as "IBM should update their SSL stack", the larger issue it exposed was that our beloved monolith is mortally vulnerable to a single component falling behind. And, in fact, it made clear that we're spoiled by the approach: many of the reactions were basically that we shouldn't have to worry about things like reverse proxies or the general notion of distinct systems for web front-ends and the app server. And that initial rejection of the hassle has implications, limiting the average Domino installation's capacity to scale for load balancing or failover in a smooth way, things that come almost "for free" with a reverse-proxied setup common among almost all other app servers.
Developers have it worse: the "power user turned developer" history of Notes and the particular peculiarities of the platform* have left us desperately behind the baseline for modern development. The tooling has coddled us into preferring inline scripts and procedural programming to structured code organization, into viewing a thoroughly-staid language like Java as something outrageously complex, of only begrudgingly adopting SCM due to the platform-induced hassle, and of almost entirely ignoring automated testing. And similarly to the SSL discussion, the historic "one tool for every job" nature of Domino leads to natural pushback when faced with other platforms.
And I get why! And I feel it too. It's a real PITA to now always have to be on the lookout for some new point release of iOS or Android to break drop-down boxes or something, as opposed to years of deploying Notes apps that looked and worked identially across every version forever (pretty much). It's also a drag to run into situations where the problem is "easy" on Domino but more cumbersome elsewhere, like platforms that farm out their FT indexes to distinct servers, or don't include document/record-based security. That makes it very easy to become blinded to the tradeoffs, though. It may be nice that Domino is a one-stop-shop for so much, but it's a shop that requires Designer, that makes it very difficult to use third-party-dependency systems like Maven (even within Maven projects), that lags in DB features found elsewhere, that is only awkwardly accessible from other app-dev frameworks, that has an API that's a bit older than Windows Me, and that essentially never showed up for the modern development conversation†.
Domino has always had a lot to recommend it, and XPages has carried us very far. And hey, this is enterprise software - even if there's never a major new version, there'll be paying work forever. It just may not be the kind of work you want to do, and it is almost definitely not truly healthy for the companies paying for it. So what I recommend is that you have a plan. The good news is that there are a great many next steps that build smoothly on existing Domino knowledge and, potentially, infrastructure. Certainly, I'm thoroughly biased in the direction of Darwino, but that's one of many. You could also do worse than learning a mature platform like Ruby on Rails (heck, you could run that on JRuby on Tomcat or WebSphere). Take some time to learn about reverse proxies and modern web-server setups. Basically: something. Just do it with an open mind, and don't balk at the first thing that's more complicated than the Domino equivalent. I think a bit of that will serve you very well.
* And, to be fair, of the overly-conservative nature of enterprise programming.
† Other than, of course, being one of the progenitor NoSQL databases.
Lately, I've been musing a lot on the topic of code "correctness" - that is, beyond the normal case of wanting code to do what I intended, and further into the realm of sweating even extremely-miniscule details. A lot of this is due to my continued watching of the evolution of Apple's Swift language (I highly recommend following Erica Sadun's blog for this). Swift is very much in the camp of "make sure all your 'i's are dotted and 't's crossed" languages, as opposed to more fast-and-loose languages like JavaScript or Ruby.
I've gone back and forth on the overarching concepts from time to time. I've long been a big Ruby fan, and a lot of that is because of a general feeling that, if you let go of a lot of the "strict old aunt of a compiler" restrictions, you gain a tremendous amount of expressiveness and productivity with few real-world problems. On the other hand, being immersed in Java all the time has shifted my brain to appreciating the benefits of stronger compile-time checks (at least on paper). Overall, I'm more on the latter side than the former now, double-edged sword though it is. This is why I've been diving into things like aggressive null analysis in my code. Even when it seems like it's being a pedant, there are certain classes of bugs that it finds that I wouldn't even normally think of on the fly. For example, the null checker flags this as being a potential NPE:
if(this.foo != null) {
My first reaction upon seeing that was along the lines of "you're full of crap, Eclipse", but then I noticed the small path a bug could take to creep in: multithreading. If I'm in a situation where the object containing foo is used across threads, there's a possibility where Thread A would evaluate this.foo != null to true and start to step in to the block. Then, Thread B would get its turn on the processor and evaluate this.foo = null in another method. Thread A would then pick up and try to call doSomething() on the newly-minted null. So I've swallowed my pride and started writing safer code like:
this.foo != null
this.foo = null
SomeObject localFoo = this.foo;
if(localFoo != null) {
What I've always admired about Swift is that it takes these sorts of lessons to heart and adapts the syntax to suit. My interest in code-correctness pedantry in Java has led me to write out verbose abominations like this:
private final @NotNull String foo;
Three of the conceptual tokens there are purely to say things that are best practices to start with: I don't want this property accessible outside the class, I want to make sure it's assigned during construction and not change thereafter, and I want to ensure it's not null. The Swift variant is:
let foo: String
Same thing, half the typing. And, as a bonus, since nullability checking is built in to the language and not a by-convention thing like the null annotations in Java, I can be sure that the rules will be applied. That sort of thing is the dream! But, since Java is the best language for the work I'm doing for now, the important thing is that it at least suits, verbose or not. In a lot of languages, it gets much more difficult to have this sort of assurance.
So, hassle as it is, I suggest that other Domino developers, on their paths through Java, consider picking up the same habits. For every time you run into something like Java complaining that it can't convert a List<String> into a List<Object>, diving fully into null checks and immutability will save you a late-night crash report and angry user. As you develop more in Java, give it a try.
I've talked a bit so far about how Darwino related to Domino from a development perspective, but I think it'd also be useful to delve into specifically which concerns the two platforms address, to see where they overlap and where they don't.
There are two main categories to cover, since Darwino inherits Domino's unusual trait of pouring over from "database" to "app-dev platform".
As I covered a few posts ago, the two are similar at a conceptual level, both being replicating document databases with document-level access control. Aside from the difference between an NSF note's format and a JSON document, the main distinction is that Darwino doesn't cover the actual physical storage of data. Instead, it is based on top of existing SQL servers of various stripes (PostgreSQL and SQLite being the most common). A Darwino application creates a series of tables and uses them as the backing store for the conceptual document database.
This has a number of implications. The main one is that there isn't a "Darwino server" as such - instead, there are SQL databases and Darwino applications acting in tandem. In developing an application, this isn't generally a concern: the Darwino APIs are the same across each database, in the same sort of way that a Domino application doesn't care about the ODS version. However, being backed by a SQL server has some distinct advantages: the server can be administered and optimized using the same knowledge you would use for a "normal" SQL-backed app, and the ability of modern DBs to index JSON data opens up a world of possibilities (think NSFDB2, except good).
The flip side of this bleeds into the second category, as it means that a Darwino application consists of at least two parts: the SQL database and the application, which veers from Domino's "everything in one package" promise slightly.
Things diverge most significantly (though at least as promisingly) when it comes to the application level. Domino has a few "official" ways to develop applications (Notes, legacy web, and XPages) and then hooks to sort of act like a Java EE server, albeit with some notable limitations. Darwino, on the other hand, exists as a sort of "glue layer" in between the database and the application: lower-level than XPages but higher-level than just a database driver.
Darwino provides a common platform for writing Java-based applications, with various services for managed beans, user directories, and so forth, written to work consistently across all of the platforms it targets. Again, this starts out similar to Domino, but diverges in the areas where Darwino takes advantage of other technologies.
At the low level, since Darwino's main requirement is "a Java runtime", it is able to run smoothly on various Java EE servers, on Android, on iOS, and on pretty much anything that provides a capable-enough Java environment (such as, say, Domino). It also, incidentally, means that it works great on Java 8.
At the high level, Darwino doesn't prescribe a specific UI framework, so the field is open to use any of the tremendous array of rapidly-developing Java frameworks on the web side and, as desired, native UI toolkits on mobile. There's a bit of an inherent bias towards REST+client JS applications, since then the same code entirely can be used on both web and mobile (as not every Java web tooklit works on the mobile mini web server as it is now), but that's not obligatory.
So the overall idea is that Darwino doesn't solve every problem that Domino does, but the problems it chooses to farm out are in the areas where that brings tremendous benefit. In each area where Darwino uses third-party support, it benefits from the tremendous advancements made in recent years, without requiring jumping through weird hoops to get modern techniques to work.
By virtue of one of the original speakers having to cancel, I will be presenting at Social Connections in Toronto next week! Specifically, it will be on the 7th at 2:30, and the topic will be OpenNTF's new tooling and initiatives:
OpenNTF has long been a central hub for community and open-source development in the Notes/Domino world. In the past year, however, it has also expanded its capabilities with new tooling and a broadening scope to the larger IBM portfolio. This presentation will discuss OpenNTF's history and its plans for the future, including a look at its newly-launched suite of source control, issue tracking, and continuous-delivery tools.
So, if you're attending Social Connections, drop on by the Toronto Room on Tuesday afternoon.
Years back, I took a small whack at an idea that had been percolating in my head: a "app manager" application that would assist with the XPage-specific portions of running a Domino server. It would cover a lot of ground that Administrator really doesn't touch, such as inspecting NSFs to see which contain XPage artifacts, highlighting potential problems with them, and assisting with app-design backup and deployment.
It never really got too far, since there are always a hundred other things to work on, but I always liked the idea. I decided to toss what code I had laid down up on GitHub:
I don't imagine I'll really have time to build on that unless I'm suddenly really struck with inspiration. But either way, the code is there for anyone interested in taking a look.
Though most of my work lately has been on sprawling, platform-level stuff or other large existing codebases, part of it has involved a new small app. I decided to take this opportunity to dive more aggressively than previously into automated null analysis and other potential-bugs tools.
What I mean by "null analysis" is letting the IDE or compiler try to help you avoid NullPointerExceptions. Though there are plenty of other programming mistakes you could still make, these are among the most common, and so a little extra work up front to avoid them should pay dividends. Eclipse has some handy options in its Java → Compiler → Errors/Warnings preferences to assist with this:
The first option will pick up on some pretty basic instances, such as:
Object foo = null;
Since this is clearly going to always cause an NPE, Eclipse is able to point this out as an error. The next level gets a little more nebulous: "potential" null pointer access. This crops up when Eclipse can't reliably determine whether a value will be null, either because there is no way to know at compile time (say, database access) or because the compiler's tooling is too limited. Here's a contrived example:
Object foo = Math.random() > 0.5 ? new Object() : null;
This situation is clearly untenable, but there are other situations where you as a programmer can be very confident that the value will not be null (say, if you swap out the > 0.5 for >= 0.0), but the compiler doesn't know that. That's why it often makes sense to leave that as a warning instead of an error.
> 0.5
>= 0.0
That's all stuff I've done before, but now I've decided to dive into annotation-based null analysis as well. Unfortunately, in stock Java, this is something of a hot mess (that list even leaves out Eclipse's home-grown version). Since Java didn't grow up with this sort of capability, it's been shoehorned in by various parties over the years. There are other tools to assist you in Java 8, but, unfortunately, I can only target 7 as the highest. For now, I've settled on the "sort-of standard" javax.validation.constraints package. It wasn't really intended for this specific purpose, but it's flexible enough to suit and can be used in Eclipse and FindBugs (though I have my reservations about the choice).
In Eclipse, this type of analysis can be enabled by checking "Enable annotation-based null analysis" below the other options and, unless you're using Eclipse's known annotations, adjusting the "Configure" options next to "Use default annotations for null specifications":
In any event, regardless of the choice of tooling, the "this shouldn't be null" annotations work the same way: you use them to decorate things that you either require not be null when provided to you (method parameters) or you promise to not be null when providing to others (method return values). For example:
public @NotNull Object doSomething(@NotNull Object otherObject) {
return otherObject.toString();
This highlights three things, two good and one bad:
That last one is a common problem when adopting annotation-based null analysis, at least in Eclipse (I hear it may be better in IntelliJ): its logic doesn't go very deep. If everything is gussied up with these annotations, you're clear - but as soon as you step outside of the project you're working on, you have to add in likely-unnecessary checks. Fortunately, these checks don't realistically hurt (a null check at runtime in a normal app is negligible performance-wise), but they can grate to have to add in.
Glutton for punishment that I am, I decided to go a step further and enable FindBugs processing as an integral step of my build. Though FindBugs can be very picky about the types of things it complains about, it is blessedly more thorough in its analysis than Eclipse, so you generally end up conceding that it is correct when it yells at you. Since the project is Maven-based, I added the check in the project's pom file:
For most uses, that's all that's required. Now, when the project is compiled, FindBugs will give it a once-over and halt the build if it finds anything it doesn't like. This can be tweaked a great deal - for example, changing the checks to run or the severity of the problem needed to fail the build - but the defaults will likely suit.
Adding these extra checks involves a lot of plusses and minuses. The big minus is that you may end up spending a lot of time "fixing" bugs that don't really exist, time that you could instead spend actually writing your application (and writing new bugs that the tools won't find anyway). There's really nothing to be gained by carefully explaining to Eclipse for the hundredth time that toString always returns non-null.
Still, particularly when tested out in a small, low-surface-area app, this can be a good practice to learn and refine. Eventually, a move to Java 8 will help this more, and it certainly doesn't hurt to add in nullability annotations in the mean time. Overall, I think having the tooling help you avoid a whole suite of common "brain fart" bugs like this is worthwhile.
Granted, this is short notice, but for anyone in the southeast-PA area, there's a meetup at IBM's offices this Thursday (the 19th) from 11 to 12:30. I'll be there, giving a presentation about OpenNTF and some of the ways that I've used the projects we work on there on my customer projects. Better still, there's lunch! The signup form is over on Greenhouse here:
If you're able to make it, great! Otherwise, I imagine there should be more of this sort of thing in the future.
In my last post, I mentioned that a big part of the job of the Darwino-Domino replicator is converting the data one way or another to better suit the likely programming model Darwino-side or to clean up old data. The way this is done is via a configuration database on the Domino side (an XPages application), which allows you to specify Database Adapters that configure the translation. While it is possible to write these in Java, the primary way is to use a Groovy-based DSL script.
The simplest form of this script may be one line just defining where the NSF is:
nsfName "foo.nsf"
With that, the replicator will open foo.nsf and attempt to replicate all documents with "best fit" translations of each field it comes across. Things can get a little more complex, though:
form("SomeForm") {
excludeField "foo"
excludeFields "IgnoreMe"
field "foo_(.*)", nameRegex: true
arrayField "bar_(.*)", delimiter: "\$", zeroBased: true, initialIndexed: false, prefix: false, compact: true,
userDataFormatName: "ODAChunk", nameRegex: true
field ~"impliedfoo_(.*)"
form("ArrayTest") {
arrayField "FirstName", type:TEXT, delimiter: "_"
arrayField "LastName", type:TEXT, delimiter: "\$", zeroBased: true, initialIndexed: false, prefix: true, compact: true
// Similar to the ODA style
arrayField "UserData", type:USERDATA, delimiter: "\$", zeroBased: true, initialIndexed: false, prefix: false, compact: true,
userDataFormatName: "ODAChunk",
toDarwino: { value ->
// The value will be an array of byte arrays, which should be strings
println "testrep: called toDarwino!"
value.collect { bytes ->
new String((byte[])bytes, "UTF-8");
toDomino: { value ->
// We should provide an array of byte arrays
println "testrep: called toDomino!"
println "value is ${value}"
def result = value.collect { string ->
println "result is ${result}"
return result
form("RestrictedFields") {
restrictToDefinedFields true
field "KnownField"
field "KnownField2"
The specifics of what's going on in this example (pulled from unit test data) aren't too important, but it demonstrates the customizability that an in-language DSL brings. Since the code is executed in Groovy, it has access to the full Java runtime (including, if you deliver it in a plugin, your own custom classes and dependencies), as well as Groovy's nice abilities like closures. In fact, a great many properties, like the converters above, can be specified as closures and executed in the context of each document as it's replicating, allowing for pretty fine-grained translation.
And personally, adapting Groovy into the process was an interesting exercise. Since Groovy was designed explicitly as a "scripting" variant of Java, the process of working it in to an existing Java code base is very smooth, and there aren't too many gotchas. I wrote some Java classes that provide the context for the root and individual "form" blocks, wired up the interpreter, and then they call each other seamlessly. Other languages could probably suit the job well too - JRuby, Rhino, etc. - but Groovy is mature, purpose-built, and largely syntax-compatible with Java itself, making it a very comfortable fit.
One of the key points of interest in Darwino for Domino developers is its two-way replication. Darwino's replication system was built in such a way that, in addition to its own internal needs, you can also write a replicator to connect to an entirely-unrelated system, as long as that replicator translates the foreign data to and from JSON documents. Domino is a perfect case for this, since the data model is already very similar, and its replicator ships with Darwino and has been a focus of my attention for a while.
Behind the scenes, this replication takes advantage of a lot of the same kinds of things that Domino's replication always has: UNIDs, sequence IDs, original-vs.-in-file modification/creation, and deletion stubs. These details are transparent to the developer: the Darwino adapter knows how to fetch the appropriate data from the NSF and to convince Domino that the Darwino DB is (almost) like a remote Domino server, at least as far as the stored data is concerned.
The primary differences show up in the way data is formatted for storage. Darwino uses JSON for its document format, which has a couple key advantages and disadvantages compared to NSF's "bag of items" approach. The best approach is probably to provide an example and highlight the pertinent differences. Say you have a Domino document that (conceptually) looks like this:
Type: TEXT
Value: Foo
Type: TEXT
Value: Fooson
Type: TEXT
Flags: NAMES READWRITERS
Value: CN=Joe Schmoe/O=SomeOrg
Type: TIME
Value: 1970/2/1
Type: TIME_RANGE
Value: 2016/1/1-2016/1/5, 2016/3/3-2016/3/5
Type: TEXT
Value: Y
On the Darwino side, that would potentially look like this:
"_writers": {
"username": ["cn=Joe Schmoe,o=SomeOrg"]
"firstname": "Foo",
"lastname": "Fooson",
"birthday": "1970-02-01",
"vacations": [
"admin": true
There are certainly a few things to take note of here. First and foremost is the structure of the authors field. Because JSON doesn't have field metadata, the way Darwino does its readers/writers security is by using specially-named and -structured properties within the JSON, and so the converter moves all readers and writers fields into that. This has internal-implementation reasons, but I think it's also conceptually preferable to, say, having a multi-level object within each field to declare its flags separate from the value. The name also happens to be stored in LDAP style, because Darwino is more at home with standard LDAP conventions for that sort of thing.
Another thing to note is the format of the date fields. Since JSON doesn't have a real date/time type of its own, these values are converted according to ISO 8601 and stored as strings. That means that your Darwino application will need to know that those string values represent dates, but they're reasonable to deal with.
The multi-value date field leads to another important aspect: arrays. In Domino, most items are conceptually presented as arrays, regardless of whether they contain single or multiple values, leading to code that requires either explicitly asking for the first element or jumping through hoops to deal with single or multiple values. Since that's a drag to worry about with JSON, the default behavior for single-value items transferred to Darwino is to store them as "bare" values. When configuring the translation (which will be fodder for a future post), you are able to specify that you want a field to be always stored as an array, which will allow the Darwino-side code to be simpler.
The last field shows off an outright advantage of the JSON format: boolean storage. When defining the conversion, you can specify a field as boolean and provide what the true/false values will be, and they will be sent over to JSON as true and false explicitly. That's not a night-and-day change, but it is a nice help.
Finally, there's the matter of rich text, which is unsurprisingly a nontrivial problem. This is handled in an XPage-alike way: MIME rich text is transferred with only minor adjustments, while Composite Data is converted to HTML and cleaned up a bit before transfer. Darwino supports the concept of attachments natively, and so Domino attachments are brought over with a naming prefix to match the field they're attached to, plus a delimiter to indicate whether they're normal attachments or embedded images. The way it is presented on the user end is dependent on the application, but Darwino has some routines to translate storage-safe inline image refs to app-relative URLs.
Later, I will go into the process of how the Domino-Darwino adapters are set up. The short of it is that you create scripts that can run the gamut from just telling the server where to find the NSF to customizing the translation of each field encountered. This allows you to either transfer the data back and forth in the default "best approximation" approach or use the opportunity to enforce a bit of a schema on old data.
So, Darwino! I've mentioned it quite a few times on Twitter and, particularly, in person, but I think it's high time I write some proper blog posts about it.
To start with, I'll cover what Darwino is. The short version is it's a Java-based development framework with a replicating document database. The interesting aspects go beyond that, though:
How does this relate to Domino/XPages development? That depends on your desires, really.
In some ways, it doesn't. Darwino is its own platform, running on Java web servers like WebSphere and Tomcat, using independent SQL servers like DB2 and PostgreSQL. Darwino's replication between the server and mobile devices is similar to Domino's, but is its own thing. Similarly, the document model, though conceptually similar to Domino (including enhanced reader and author fields), is not NSF.
However, there are a number of reasons why it's of interest to a Domino developer, and the most immediate of those is its ability to do two-way replication with Domino databases. I'm a little biased on this point because of how much time I've spent working on it, but this replication is capable of some nifty tricks to make it capable and adaptable, including transformation of the data, two-way maintenance of document time stamps, and so forth. With this syncing, it makes it very practical to extend your existing Domino app - be it a classic-style Notes/web app or an XPages one - with a Darwino-side UI that uses the same data, synced down to mobile devices for offline access. And this doesn't require migration; since the changes replicate back, the app can remain chugging away unchanged on the Domino side if desired. This also can be tremendously useful for reporting, by syncing the data over to a full SQL database that can be viewed and queried by normal tools.
And, really, it's also of interest to Domino developers personally by virtue of being a platform that has learned a lot of valuable lessons from Domino and extended them in new ways. Those years of accumulated document-database knowledge will carry over nicely, with some extra benefits if you're SQL-familiar too. Any Java knowledge will come in handy immediately, as Darwino is thoroughly Java-based on all target platforms. And, thanks to its pedigree, a lot of the platform support concepts are similar to aspects of XPages (the good parts). In general, the more XPages development you've done, the more it will benefit you (especially if you want to use JSF for the UI!). You could also, with some servlet-implementation limitations, run Darwino apps on Domino via OSGi, and I've been putting some side work into accessing Darwino databases from XPages directly - Darwino could make a solid basis for Domino-run apps.
So this turned into a bit of a sales pitch, but there's no getting around it - I find this thoroughly compelling and exciting. As I have time, I plan to expand on Darwino's various capabilities (along with the other various blog series I still plan to get to). For now, you can register for and download the Community Edition, read the documentation there, and/or track me down with any questions.
Yesterday, I decided to toss the source of my first real XPages app up on GitHub:
It's my WoW guild's web site, which had some forums as well as a raid-management tool and loot tracker. I'm guessing that those tools won't be particularly useful for your average XPages app, but they were interesting things to build, and were a great exercise in figuring out the platform. Since it is quite old, there are also plenty of terrible decisions in there, such as my mass recycler from before I knew that Domino objects are already all recycled at the end of the request, but hey, that's growth.
In any event, it's there for the curious, or in case any of the code ends up being useful for future Googlers.
This post isn't really in my ongoing Java thread, though it's related in that this is the sort of thing that may come up in fairly-advanced cases. This post will assume a functional knowledge of Maven, Tycho, and JUnit.
For Darwino, I ran into the need to run unit tests on Domino-adapter code during the Maven build process. Since the Domino project tree uses Tycho, this ended up differing slightly from standard Maven testing. Rather than using the src/test/java directory in the same project to house the associated tests, Tycho prefers the very-OSGi-native method of having a separate project, but declaring it a "fragment" plugin attached to the primary one. In OSGi terms, a fragment is a special type of plugin that, when loaded by the runtime, gets glommed on to a specified host plugin and runs in its same classpath. In other cases, this may be used to provide platform-specific additions, add locale resources, or other uses.
So I created a new fragment project, which is structurally much like a normal plugin, but with an extra line in the MANIFEST.MF:
Fragment-Host: com.example.some.parent.plugin
This line tips off the OSGi environment to its nature. In the pom.xml, there are a number of important differences related both to how Tycho handles test fragments and the necessity of loading the Notes native libraries:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
By default, Tycho doesn't include the other fragment plugins when running the test.
So here, we manually include the appropriate features.
The preamble is the same as usual for Maven, but the packaging is slightly different. Instead of eclipse-plugin, this should be packaged as eclipse-test-plugin. Tycho's packaging doesn't particularly care about whether or not it's a fragment, but it does care about its test nature.
Things get a little interesting in the target-platform-configuration block. These two entries have similar purposes: to cause Tycho to load up other, native-artifact fragments required to run the tests. The first one showed up in the Java series: it contains Notes.jar, but, because it is itself a fragment (and can't be directly depended upon by the test project), Tycho won't automatically load it unless directed to. The second one serves a similar purpose, but loads a feature instead. This feature contains references to a number of distinct platform-dependent native-artifact fragments, and specifying this dependency causes Tycho to consider each one without having to specifically enumerate them in the POM.
The final block is a little simpler, and it just tells Tycho where to start when it goes to run the fragment as a test suite. The AllTests class is a test suite in the JUnit 4 convention, with @RunWith and @Suite.SuiteClasses annotations.
There's another catch to this, though: Notes has some specific demands on its environment, and in particular must be run with knowledge of a Notes program directory, a data directory, a notes.ini, and an ID file (unless you're doing DIIOP (which you probably shouldn't)). The specifics of what the libraries expect in their runtime environment and how they should be loaded in their API calls vary a little from platform to platform, and I ended up with a pile of "just keep trying stuff until it works" code. The result, though, is that I have automated tests running on Windows, Linux, and OS X. First, there's the large platform-specific section of my root POM, which defines platform-activated profiles that set up environment variables:
<!-- These profiles add support for specific platforms for tests -->
<argLine>-Dfile.encoding=UTF-8 -Djava.library.path="${notes-program}"</argLine>
<argLine>-Dfile.encoding=UTF-8 -Djava.library.path="${notes-program}"</argLine>
<argLine>-Dfile.encoding=UTF-8 -Djava.library.path="${notes-program}"</argLine>
<!-- The res/C path entry is important for loading formula language properly -->
<!-- Notes-standard environment variable to specify the program directory -->
<!-- Linux generally requires that the notes.ini path be specified manually, since it's difficult to determine automatically -->
<!-- This variable is a convention used in the test classes, not Notes-standard -->
Each block is kicked off both by a specific OS combination, using Maven's OS names (you can also target specific architectures within them), as well as the presence of a notes-program property. This is a convention I've adopted to go alongside the notes-program property that points to the XSP plugins; this one instead points to the root Notes or Domino install to use for execution.
Windows is the easiest since Notes still feels most at home on there. There, it's just a matter of adding the Notes program root to the Java library path and the environment's PATH. From there, the Notes libraries automatically picked up the data directory and notes.ini, presumably from the registry.
The Mac is mildly more complex: in addition to the two settings from Windows, I also ended up adding the program path to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH. I'm not entirely sure both are needed, but hey, it works this way. In addition, I had to specify Notes_ExecDirectory. After that, the tests found the location of the data dir and Notes Preferences, presumably due to Mac OS conventions.
Notes Preferences
Linux needed the most hand-holding, which shouldn't be too surprising for those who have installed Domino on Linux - it doesn't seem to respect any platform conventions there. In addition to specifying the notes-program property and using it in the same places as on the Mac, I also added two more properties to my Maven config: notes-data, to point to the data directory, and notes-ini, to point to notes.ini. I used the notes-data property to specify the Directory environment variable that the Notes libraries look for, and then I also specified NotesINI. That's not something that the Notes libs look for, but instead it's a way to shuttle the configuration to the Java code that actually executes the tests.
That leads to the final hurdle: initializing the Notes environment in the JUnit test classes. To do that, I specified a @BeforeClass method that checks for the presence of the Notes_ExecDirectory and NotesINI environment variables. If they're present (i.e. it's Linux), it calls NotesInitExtended with the value of Notes_ExecDirectory as the first argument and = plus the value of NotesINI as the second. Afterwards, whether or not that was called, it calls NotesThread.sinitThread(), and from then on NotesFactory.createSession() will generate proper native sessions.
There's also an @AfterClass method that is the mirror of that: it calls NotesThread.stermThread() and then, on Linux, NotesTerm.
So yeah, there are a lot of hoops to hop through! Hopefully, this post will be helpful for someone attempting to do the same thing I did, and it'll cut down on a lot of searching around and trying to piece together a working environment.
So, after the last post's large task of converting to Maven, this step is mostly about picking up the pieces and expanding on some of the concepts. We'll start with M2Eclipse, usually rendered as just "m2e".
m2e is the set of plugins that acts as Eclipse's interface to Maven. It more-or-less replaces the earlier maven-eclipse-plugin, though you will likely still see references to that around. Eclipse doesn't have any inherent knowledge of how Maven works, m2e has the complicated task of reading your projects' pom.xml files and adapting them to Eclipse's internal configuration. So, for example, in our projects it saw the presence of Tycho and determined that they should be imported as OSGi projects. In other cases, m2e may pick up the presence of things like Android plugins to trigger the use of the Android development tools.
Though it tries mightily, m2e is the source of a lot of the consternation that can come with a switch to Maven-based development. Because most Maven plugins don't have any inherent allowances for working in an Eclipse environment, adapters have to be written for each one in order for them to work with m2e - this is what the dialog yesterday installing the Tycho adapters was about. In some cases, these don't exist and you have to tell m2e to ignore the plugin; in other cases, the adapters DO exist, but are flawed in some way. Most of the time, things go alright, but there are enough edge cases that it can be irritating.
For this kind of task, m2e is pretty unobtrusive, but it's important to know it's there.
One side effect of m2e's behavior is that it's not a good idea to remove Eclipse's project configuration files from the Git repository. This is not required, but it can avoid a number of annoying problems when dealing with multi-person Maven projects. To start with, open the .gitignore file from the root of your local Git repository (you can get to this easily using Eclipse's Git Repositories view, in the "Working Directory" part of the repo). Add some lines at the end to ignore .project and .classpath, so your whole file should now look like:
# Mobile Tools for Java (J2ME)
# Package Files #
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
# Eclipse project files
Depending on how your (hypothetical) team wants to work, it may also make sense to ignore the .settings/ directory, which stores some additional Eclipse project information. However, some of that information may be useful to share - for example, on-save code-cleaning behavior that isn't readily expressed in Maven.
Due to the way Git works, just adding the files to the .gitignore won't remove them from the repository: instead, they'll just no longer show up in the list for new changes. In order to also remove them from the repository without deleting them from the filesystem, go to the "Navigator" pane in Eclipse (if it doesn't show up currently, you can add it via Window → Show View → Navigator), find each .project and .classpath file in the four projects (some will only have the former), right-click, and choose Team → Advanced → Untrack:
Now, commit the changes - though the files remain on the filesystem, they should show up as deleted in the commit dialog:
This one is one we've already prepped a bit for. Whereas most Eclipse projects store their binary output (Java class files, Jars, etc.) in the bin folder or elsewhere, the standard Maven behavior is to use target. For most of the projects, this doesn't matter - we had already configured the plugin to use a subfolder here for its classes, and the temporary files for other aspects don't matter. However, it's still important to know about this; when you're looking for the compiled or packaged output of a Maven project, this is the place to look, and we'll run into this when building the update site.
There's an important changed involved now with how the update site is built: it does not involve opening the site.xml and clicking "Build All" anymore. Instead, it involves right-clicking the root project ("parent-xsp") and choosing Run As → Maven Install:
There are two logical followup questions when seeing this change: "what?" and "why?". They're both bound together to what the nature of a Maven project is, and, significantly, the way Eclipse interacts with them. Maven is primarily a command-line tool - granted, it's a set of Java classes, but the primary way to interact with it is via the command line. m2e does a lot of work to interpret the projects in the same way as the `mvn` command-line tool, but it's just a secondary interpretation due to the way Maven and Eclipse work.
The way to fully build a Maven-ized project in a way that fully uses the configuration is to run the command-line tool. Fortunately, m2e comes with its own embedded version and doesn't require you to use a terminal, but the abstraction is very leaky - and this is why you use "Run As" instead of any of the normal "Build"-related commands. The "Run As" commands construct a CLI-type environment and execute the embedded Maven, which is what then does the real work.
Since "parent-xsp" is the root of our projects, it's the starting point to execute a Maven build. When you run this, you'll see a lot of chatter in Eclipse's Console view, particularly the first run: Maven will seek out the plugins needed to build the projects and install them to the local Maven repository (stored in ".m2/repository" in your home folder). After that, it will build and package each of your projects. There's a whole phase system going on here (similar in concept to the XPages lifecycle), as well as many configuration options, but the important part here is that the "install" command (called a "goal" in Maven parlance) is the last phase that we will worry about, and it will cover everything we need here.
Upon completion, the Console text should end with something like this (incidentally, "Reactor" is Maven's term for the entire blob of modules being processed):
[INFO] Reactor Summary:
[INFO] parent-xsp ......................................... SUCCESS [ 0.617 s]
[INFO] com.example.xsp.plugin ............................. SUCCESS [ 1.647 s]
[INFO] com.example.xsp.feature ............................ SUCCESS [ 0.411 s]
[INFO] com.example.xsp.update ............................. SUCCESS [ 4.143 s]
[INFO] Total time: 30.310 s
[INFO] Finished at: 2016-02-23T13:55:20-05:00
[INFO] Final Memory: 80M/191M
Part of this process is the cration of the update site, which, due to how we configured it, will be represented twice in the "target" folder in "com.example.xsp.plugins": as a tree of files inside the "site" folder and also zipped up into the "site_assembly.zip" file. There's also a file named "site.zip", but that contains just the site.xml, which is not important. It's these files that you should now target with Designer and the NSF Update Site when updating the plugin. In fact, it'd be a good idea to delete the "features" and "plugins" folders from outside the "target" folder now - they won't be used any more.
As for the "Build All" button in site.xml, it's best to pretend it doesn't exist. It will still work, but it will break your Maven build, because it overwrites the "qualifier" in the version numbers. This is, admittedly, a drag: it's convenient having a clear, logical button to build the site, and it's very inconvenient that Eclipse doesn't tell you not to use it any more. However, the Maven process, besides being now required, has a nice advantage: now building the update site will no longer cause Git to want to check in the change. That's something that can get annoying very quickly when working with another developer on a non-Mavenized OSGi project.
We'll finish the day on an easy one: adding back in the source plugin. Unlike the original setup, which used a separate feature to house the source plugin, we'll now include it in the same feature. You could also continue to have a separate source feature, which would be useful for very large projects where it would actually be a big burden to deploy the source to servers, but, for XPages libraries, it's generally not worth the cognitive hassle.
Since we already configured the Tycho source plugin earlier, this is just a matter of adding a reference to the (implied) source plugin to the feature.xml:
<?xml version="1.0" encoding="UTF-8"?>
label="Example XSP Library Feature"
<description url="http://www.example.com/description">
[Enter Feature Description here.]
<copyright url="http://www.example.com/copyright">
[Enter Copyright Description here.]
<license url="http://www.example.com/license">
[Enter License Description here.]
Now, the source will be included in the output and bundled with the main feature when it's installed. Commit this change:
At this point, we're basically back to where we were previously, OSGi-wise, but in a much better position to scale the project further and take advantage of supporting systems. The next couple posts will cover some of those potential systems, as well as remaining large conceptual topics. There's a great deal to know when it comes to Maven, but it's all helpful.
Prelude: there was a typo in the previous entry. Originally, the file URL read "file://C:/IBM/UpdateSite", but, on Windows, there should be another slash in there: "file:///C:/IBM/UpdateSite". I've corrected the original post now, but you should make sure to fix your own settings.xml file if needed. Otherwise, Maven will complain down the line about the URI having "an authority component".
The time has come to do the dirty work of converting our existing plugin projects to Maven. There will be some filesystem-side reorganizing and not every project will make it (looking at you, source project), but overall it's mostly a job of pasting a bunch of XML into new files.
For the first leg of this, I recommend removing the projects from your Eclipse workspace by selecting them, right-clicking, and choosing Delete:
On the confirmation dialog, do not select "Delete project contents on disk" - we don't actually want to get rid of the files.
Next, find the projects on your filesystem, create a new folder alongside them named "com.example.xsp", and move the projects inside it. In Maven parlance, we're creating a "multi-module project", and this new folder is the top level in our module hierarchy. This can contain arbitrary levels and can be very helpful in project organization, but this will be a pretty simple parent-and-children case. Next, dive into the folder and delete the "com.example.xsp.source.feature" - we'll be able to generate this through Maven now, and so we can trim down our project count slightly.
Now, create a file named pom.xml in the "com.example.xsp" folder alongside the subfolders, and fill its contents with this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
Maven compiler options
Tycho plugins
<!-- work around Equinox bug 348045 -->
<removeAll />
So... yeah, there's a lot going on here. This is the biggest of the "XML dumps" we're going to have and contains by far the greatest number of bizarre "you just have to know about it" parts. "POM" stands for "Project Object Model" - it's the language Maven uses to describe the project. Let's tackle the file from near the top (ignoring the XML header):
These elements are effectively just boilerplate: the project element is the root of our project descriptor and it contains some definitions to let XML editors parse the file format. In turn, the modelVersion describes to Maven the specific version we're working with, which has been "4.0.0" for as long as I've been doing this.
These elements are obligatory in one form or another in every project, but are less copy-and-paste-able: they define the name and version of your project. These are Maven's equivalents to OSGi's Bundle-SymbolicName and Bundle-Version, though Maven makes an explicit distinction between the overall grouping of the plugin and its specific name. These are essentially arbitrary, but the convention is to use the standard reverse-DNS version of your domain name for the group ID, and then keep this group ID consistent across different projects (...mostly). The artifact ID is less consistent, but it's good to pick a pattern like "projectPrefix-submodule". Here, we actually reverse that a bit to call it "parent-xsp" in order to emphasize that this project's purpose is entirely to be a parent to the submodules and not an interesting artifact to consume itself. We'll break this convention again for the submodules due to our use of Tycho/OSGi.
A project's packaging describes the sort of output. By default, if this is left un-specified, it's jar - a normal, run-of-the-mill Jar file. There are a few other common ones you may run into - such as war for J2EE web apps or bundle for non-Tycho OSGi bundles - and the one we're using here is pom. This is actually kind of the "none of the above" option: the "pom" is just the file we're editing now, and is included with every project type. Having a packaging type of pom generally means that either the project has no real outputs of its own (as is the case here) or it's an "ad hoc" project that doesn't fit an existing type.
This block is the hallmark of a parent project: it lists the relative folder paths that contain the submodules. In this case, the names line up with the names we'll use for the submodules, but this could potentially vary depending on the folder names and locations. Parent-child module relationships don't have to be physically hierarchical on the filesystem, but it's a good convention when you don't have a specific reason to break it.
This block is the project-level equivalent to the user-level property we defined in .m2/settings.xml. There are two types of properties that can go here, with no obvious distinction between them: known configuration properties used by Maven itself and arbitrary named variables used by the person writing the pom.
The first property - project.build.sourceEncoding - is an example of the former. During execution, Maven will reference this property defined in the project (or one of its parents) when determining the text file encoding to use. This could be set to something else if you're working with non-Unicode files, but it's important to set it here so that file interpretation will not be platform-dependent. These properties can be read like an equivalent of EL for the project XML: it sets a property of sourceEncoding within the build node in project, but more consisely (more or less).
The other two are variables for use later. The names of these have only very loose conventions, but there seem to be a couple common types: ALL_CAPS, camelCase, and hyphen-delimited. You can also specify variables as dot.delimited and they will work the same way, but that makes them more difficult to distinguish from the system-level properties.
The repositories block is the start of our OSGi-related weirdness. The block itself isn't OSGi-specific - it has its role in other projects that want to make use of dependencies outside of the core public Maven repositories - but the contents is. We're setting two repositories here: one to point to the main Eclipse repository (the Luna version here, but that could just as well be Mars or Kepler) and one to point to the XPages Update Site. This is where the property we set before comes into play, allowing different developers to keep the update site in different locations without changing the project's config.
The build section is often the largest part of a POM file - it contains definitions and configuration for various additional Maven plugins used during compilation. We have two tasks to accomplish here: ensure that we use Java 6 for compilation at the root level (to ensure the build doesn't execute as Java 7 or 8 and be incompatible with Domino) and enable a whole slew of Tycho plugins.
The maven-compiler-plugin block specifies the version of the Java compiler plugin to use (3.1, which is actually kind of old, but the differences aren't important) and then provides it with some configuration to set the Java version level and to not choke on forbidden references. Like the Java version, the latter is a nod to Domino: depending on your JVM configuration, you may run into forbidden-reference errors relating to the lotus.domino classes.
The next slew of blocks all relate to loading up various Tycho components. Tycho's job is esentially to construct an entire OSGi environment during the Maven build, and it consists of a number of moving parts, many of which are basically the Tycho version of normal Maven facilities. The tycho-maven-plugin is the core, and its extensions rule is what allows it to worm itself into various phases of the build process. The tycho-packaging-plugin controls the process of bundling the projects as their various types: the plugin, the feature, and the update site (in our case). The tycho-compiler-plugin is the Tycho variant of the Maven one we configured earlier. The tycho-source-plugin is what allowed us to kick the standalone source feature to the curb - it's the equivalent of the Eclipse-specific feature we had been hooking into before.
The tycho-platform-configuration is the scariest of the bunch. This plugin's job is to establish the OSGi Target Platform we're working with, in conjunction with the repository specified above. Not all of this configuration is necessary for our immediate needs, but may come in handy later. The pomDependencies rule is useful when using mixed-type dependencies in more-complicated projects, while the extraRequirements block forces the inclusion of the plugin fragment that contains Notes.jar. The optionalDependencies rule comes in handy from time to time with XPages projects: there are sometimes cases where there's a dependency that Eclipse has and which the server will have, but which will be awkward to get to in Maven, usually relating to dependencies-of-dependencies not related to compilation. The filters block is... I don't know; just keep it in there. The environments block is a way to describe the platforms on which your code can execute - I believe this is primarily used when testing. The resolver is like filters in that it's a "I just copy it around" thing; presumably, it refers to a specific code path for resolving plugin dependencies.
Okay, so... that's the first one down! For the most part, you can carry around the whole bottom section pretty much as-is for your XPages Maven projects (as I do), and then gradually become comfortable with the specifics over time. Now, there's some good news and some bad news:
In recent versions of Tycho, they've added the ability to reduce the number of POMs involved, but there are limits to that, particularly to do with Jenkins, so we'll stick to the traditional way for now.
Go into the "com.example.xsp.plugin" folder and create a new pom.xml containing this:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
Like I promised: much simpler. Because the parent POM already brought in all the Tycho plugins and configuration, all we need to do here is the basics. One slightly-unusual aspect here is the packaging type. eclipse-plugin isn't a packaging type known to Maven inherently; instead, it's provided by Tycho, but can be used in the same way.
The artifact ID here is a concession to Tycho: Maven artifact IDs don't usually follow the same full-reverse-DNS conversion as OSGi, but Tycho wants the artifact ID to match the OSGi bundle name.
Next up is the pom.xml file in the "com.example.xsp.feature" folder:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
This is very similar to the last, with the only real differences being the artifact ID and the packaging type.
Now, the pom.xml in "com.example.xsp.update":
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
This one's slightly longer, but not by too much. Beyond the different artifact ID and packaging, we also provide some additional configuration to the tycho-packaging-plugin. This is among the plugins that were established in the root POM, but it's re-defined here in order to enable the archiveSite configuration option. This will give us a nice ZIP file of the Update Site at the end.
There's one other thing to note here: Tycho considers the eclipse-update-site packaging type to be deprecated, and it may be removed in the future. In most examples you'll see outside of Domino, people use eclipse-repository instead. This gets back to the difference between the old-style ("site.xml") Eclipse Update Sites and the new-style ("category.xml", named P2) Update Sites. For now, we use the old-style variant because it works better with Notes and Domino.
In addition to this POM file, we also have two changes to make in the site.xml: remove the source-feature reference (we'll add this back elsewhere later) and clean up the versions:
<?xml version="1.0" encoding="UTF-8"?>
<feature url="features/com.example.xsp.feature_1.0.0.qualifier.jar" id="com.example.xsp.feature" version="1.0.0.qualifier">
<category name="Example"/>
<category-def name="Example" label="Example"/>
The version distinction is to change the Eclipse-generated timestamps at the end of the versions to "qualifier". The reason for this is that, for Tycho, the site.xml acts as a pure configuration file, and will no longer be the site index itself. So Tycho wants the qualifier to be generic, and then will fill it in during compilation. Like the source feature, this will be covered more later.
With our POM files defined, the last step for now is to import the projects back into Eclipse. In Eclipse, go to File → Import, expand the "Maven" category, and choose "Existing Maven Projects":
On the next screen, browse to the "com.example.xsp" directory created earlier. If all goes well, this should find the four projects in their hierarchy:
Everything on this can be left as the defaults, though you may want to specify a more-descriptive working set name - that doesn't affect the project behavior.
When you click "Finish", Eclipse with churn for a bit and then, if you're running Mars and haven't done this before, it will present a dialog about "Maven plugin connectors":
The specifics of what is going on here are a large topic of their own, but the short of it is that Eclipse needs specialized plugins to deal with each Maven plugin, and in this case it's looked for (and found) connectors for Tycho. Click "Finish", "Next", and "OK", accept the license terms, and restart Eclipse as it tells you to.
When Eclipse restarts, it should go through some churning while it updates the Maven projects and should finally settle on no remaining errors.
There will be some things to discuss with the fallout from this conversion, but this will do it for today. Commit your changes, stand up and stretch, and grab a cup of relaxing tea:
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License and code samples are licensed under the Apache 2.0 License.

subset: commoncrawl


text:
Paul Crisman Overview
Paul Crisman has been associated with one company, according to public records. The company was incorporated in California twenty-seven years ago and is no longer active.
Background + Contact Information Available for Paul Crisman
Contact + Background Information
- Phone, Address & Email
- Criminal & Civil Court Records
- Bankruptcies, Liens, & Judgments
- Properties, Businesses, Licenses, & More
Sponsored by PeopleSmartNo Thanks
Companies for Paul Crisman
Known Addresses for Paul Crisman
California Secretary of State
Data last refreshed on Monday, July 25, 2016
Data last refreshed on Monday, July 25, 2016


text:
Video Industry News Video Company News Technology Industry News Technology Company News Novelty Industry News Novelty Company News Gay Industry News Gay Company News Legal Industry News All Company News
Released: Jan 22nd, 2014
Running Time: 139 Min.
Director: David Perry
Company: David Perry Productions
Distribution Companies: Evil Angel
DVD Extras: Behind the Scenes, Cumshot Recap, Still Gallery(ies), Trailer(s)
Cast: Veronika (I), Maggie, David Perry, Rye, David (I), Bella Karina, Katarina (I)
Critical Rating: AAAA
Genre: Big Bust, Foreign All-Sex
Veteran French director David Perry's "Big & Real 7" is his latest showcase of huge, hypnotic, all-natural sweater meat. Five lovely European ladies here have various body types, but two extremely prominent characteristics in common! The director and a couple of well-hung pals can't keep their hands off the massive melons on display. Hand-crafted by a true breast man for the big tit connoisseur, "Big & Real 7" remains the natural choice.
Natural is the key word here as these big and real European performers bounce their way into your heart. Occasionally a few words in English are strategically released; otherwise this is relegated to moans and groans emitted during passion by these hot, heavenly and huge-hootered babes.
Even though the cover photo is shot to exaggerate their breast size, it doesn't matter; the girls are all pretty large on top. Occasionally, POV combines as a good mix with straightforward screwing. Some, like Rye, limit their actions to titty-fucking; others, like BBW Maggie, just do it.


text:
I have been trying to use this product with pagelines dms and it breaks the site. This is what the developers were saying with regards to the plugin.
"Some awesome plugin you have installed is using add_option() wrong. It was changed in WordPress 2.3 which was released on September 24, 2007"


text:
I have created a 3D object in opengl for one of my application. The object is something like a human body and can be rotated on touch. How can I detect the position of touch on this 3D object. Means if the user touches the head, I have to detect that it is the head. If touch is on the hand, then that has to be identified. It should work even if the object is rotated to some other direction. I think the coordinates of touch on the 3D object is required.
This is the method where I am getting the position of touch on the view.
- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: self];
m_applicationEngine->OnFingerDown(ivec2(location.x, location.y));
Can anyone help? Thanks in advance!


text:
The Farewell Circuit: We captured some serious magic
Matt O'Brien, Alex Young, Danny O'Brien, DJ House
Photo by Jess Ekstrand
On one of the last snowy days in the spring of 2013, Minneapolis band the Farewell Circuit is gathered in their practice space for rehearsal and some beers. The camaraderie in the room is palpable as they open drinks and get settled in; it's hard to get a word in between the four members as they toss around jokes and share their weekend happenings. Lead singer Danny O'Brien passes his phone to his bandmates, sharing photos from a friend's wedding in Milwaukee where he was doing duties as a photographer. "Did you take all of their photos on your phone, Danny?" someone asks him. He quips, "Yeah, when people ask me where my gear is, I pull out my phone and say, 'Here it is.'"
Since the release of In Our Bones in late 2011, the band has gone through a lineup change with the addition of drummer Alex Young and bassist Matt O'Brien -- no relation to Danny -- to the already established members, guitarist DJ House and Danny. It was an easy transition, for they all ran in the same circles already, but the dynamic is noticeable on the new record, We Were Wolves. Recorded live, the album feels more raw, yet still draws from the delicate vulnerability that Danny exposed on In Our Bones.
Gimme Noise sat down and spoke with the four members before their release show at Icehouse on Friday to get their views on the new album and their favorite producer.
In his deep, booming voice, Alex Young -- who also plays in many other bands outside of the Farewell Circuit such as And the Professors, Bella Ruse, and others -- shares his thoughts on the collaborative feel of this band, something he hadn't really encountered until now. "The thing I thought was interesting about how this band writes is that there's definite sections that are completely detached from anything else," he says. "Danny writes the initial pieces, then we come in and we try to figure out how to bridge the gap between all of these sections. That's the communal writing, and two weeks later, it's a completely different thing."
The band had three days in the studio with producer Brett Bullion, more so because, "That's all we could afford," jokes DJ. Due to the time restriction, the band wasn't able to build tracks, so they recorded all five songs live -- even writing the arrangement for their last track, "Admission," the night before it was to be recorded. DJ continues, "We captured some serious magic doing it live; some things crept their way into the final takes that we couldn't have planned. It was clear that we wrote the arrangement for 'Admission' the night before. When we were in the studio, Brett was doing things that we didn't know he was doing. It was so quick, and we didn't have a feel for the song. It just kind of was. That was a universal moment where we all knew it felt right."
Photo by Jess Ekstrand
Bullion also had producing credits on the last album, and when asked why the band liked working with him so much, they laughingly joke, "He's a dick; he's the worst, and we couldn't afford Steve Lillywhite." Danny explains, "At this point, I consider him a friend. I want to play music with my friends; I want to create with my friends. That's why this is great. Whenever I work with him or we get together, we always have great conversations, and that carries over into whatever we're doing creatively. He's also ridiculously reaffirming. Like every musician, we all have moments where we think we're not good enough. Brett's constantly like, 'You guys are monsters. You can play this!' He creates this really great environment for us."
The producer helped shape We Were Wolves, an album that Danny shares is a clean break from In Our Bones. "It's not that the whole story changes, but it definitely moves to a different setting. I don't think we broke any genre boundaries, but I do feel it's a new chapter; it has a different vibe. Even though I enjoyed playing with the guys in the band on the last album, I love where it's at right now." DJ concedes to being scared shitless going into the studio with this album, because of lack of preparedness. But as soon as they were done, he got into music mode again and wanted to write, because he was so proud of the songs.
Explaining the meaning behind the name of the new album, Danny becomes serious and shares his background growing up in a Christian home with a limited view on the world. He says, "It was this moment of recognizing -- we go on living our lives thinking we're doing the right thing and we're good people. Especially when I was a teenager, I thought I was literally saving people, and then having this realization the whole time I thought I was a good guy when in hindsight it wasn't so. I would view what I was doing as a wolf in sheep's clothing. It seems so deceptive. I use some pretty harsh imagery -- eating children, preying on the weakest ones. I feel those lyrics drive home the point of what happens in Christian circles -- people feel they need something, and then I felt I had to answer to that. I still believe in something, but I consider myself an agnostic humanist."
Another part of what Danny was experiencing during the writing of the album had to do with his younger sister, Anna. When she was 16, Anna was a promising young student with college recruits scouting her for basketball, but all of that changed when she was diagnosed with schizophrenia and dissociative identity disorder, causing her to see hallucinations and withdraw within herself. In the two years since the diagnosis, she has been on medications to control the disease, but Danny parallels how a lot of his youth was stolen because of his years steeped in Christianity are similar to Anna's teenage years. "Looking at my sister, the years of her youth were also stolen from her by something she didn't deserve. No one deserves that."
As does any artist, the band had fears about trying to live up to their prior album. Danny says, "I loved the last album, but I love We Were Wolves just as much, if not more. You attach memories to specific times. I just really have good memories associated with making We Were Wolves." Alex compares this transition between albums by bringing up John Mayer, with the rest of the band scoffing and groaning at the mention of Mayer's name.
"A lot of people loved John Mayer's Continuum, so when he came out with Battle Studies, his fans and critics were like, 'Boo. Two thumbs down.' Everyone wanted a second Continuum, but to put out two records that are totally the same is totally BS. It's not honest at all -- musically and personally. A true artist is going to grow from year to year. There was three to four years between those two albums of Mayer's. I would be really let down if We Were Wolves sounded like a second In Our Bones. There's a lot of change and growth, so if you don't grow, you're shutting yourself off from the rest of humanity. There's so much out there to be inspired by and to write about."
The Farewell Circuit will have their release show for We Were Wolves at Icehouse on Friday, June 7, 2013 with the Dear Data.
21+, $7, 10 pm
City Pages on Facebook | Gimme Noise on Facebook | Twitter | e-mail us
Get the Music Newsletter
Keep your thumb on the local music scene each week with music news, trends, artist interviews and concert listings. We'll also send you special ticket offers and music deals.
In Case You Missed It
Popular Stories
Sponsor Content


text:
Blog TV Competitions Lookbook Buying guides Stores Teams
0 Items
View All Mens Clothing
View All Footwear
View All Accessories
View All Skate
View All Route One
View All Scooter
View All Sale
View All Brands
10% Student Discount >
Price Match Guarantee
Free Delivery over £50
This product is currently out of stock
Fremont Mid constructed with a suede and canvas upper, vulcanised rubber sole unit, metal eyelets with leather rawhide laces. Frogskin camo print on canvas with woven TS Palm label on tongue.
More Trainerspotter
More Boots
UK Next Working Day (Order by 5pm Mon-Thur)£5.99 or FREE on orders over £70
UK Standard Delivery (Up to 5 working days)£3.99 or FREE on orders over £50
For more delivery information including international options click here
If you are not completely satisfied with your purchase, simply return the items to us in their original condition and packaging within 100 days of receipt of your order for either an exchange of product or a refund. Simply follow the instructions detailed on the Returns form which you will find on the reverse of your delivery note/invoice. Please ensure all product is wrapped properly for posting and no postage labels are stuck to the product or its packaging.You don't need to call us prior to your return.
Click here to see our full returns information
Terms & Conditions
Please wait...


text:
Definition of mainstay in English:
1A stay which extends from the maintop to the foot of the foremast of a sailing ship.
1.1Someone or something on which something else is based or relies: whitefish are the mainstay of the local industry
More example sentences
- The gun run, loosely based on the exploits of Naval squads in the Boer War, was a mainstay of the Royal Tournament.
- The first pick of Fox's second draft was Jordan Gross, who has become a mainstay at right tackle.
- Since I have so much yew foliage, this is the mainstay of the ropes and swags that I will be creating.
central component, centrepiece, prop, linchpin, cornerstone, pillar, bulwark, buttress, chief support, backbone, anchor, foundation, base, bastion
tower of strength, key player, sinew, right-hand man/woman, right arm, Atlas
For editors and proofreaders
Line breaks: main|stay
Definition of mainstay in:
What do you find interesting about this word or phrase?
Comments that don't adhere to our Community Guidelines may be moderated or removed.
= trending


text:
The park's high school programs use park resources to enhance classroom learning by giving students an opportunity to make real-world connections with the environment. Rangers will work with you to plan a program that meets your curriculum needs. Please e-mail the education staff or call (865) 436-1258 for more information or to discuss program options.
Tennessee High School


text:
Video Industry News Video Company News Technology Industry News Technology Company News Novelty Industry News Novelty Company News Gay Industry News Gay Company News Legal Industry News All Company News
Released: Nov 01st, 2001
Running Time: 83
Company: Heatwave Entertainment
Cast: Santita, Caramel, Antonio Duran, Al Dogg, Vanessa Ventura, Ana (I), Mistyque
Critical Rating: AAA
Genre: All-Sex
Filler for your ethnic section.
Latinas in nurse getups throw down with mucho macho studs. The sex isn't particularly enthused or well captured, but the ladies featured here are all genuine Latinas (with one Spanish-speaking soul sista tossed in for good measure) and so will please those seeking real-deal Latin-themed fare.


text:
Wild Bill McKubby joins us every afternoon from 3-6pm. Wild Bill has lots of interviews with celebrities, country artists and movers and shakers. Wild Bill has worked at WBYZ about 10 years ago and is glad to be back in Southeast Georgia close to family and friends. He's married to his lovely wife Marilyn has a 6 year old Girl named Emma and a baby boy on the way named William.
Wild Bill Blog
Arrest Made in Ohio College Student's Disappearance
Investigators looking into the disappearance of an Ohio college student whose bicycle was found in a cornfield this week have arrested a man on an abduction charge
How Sympathetic Whites Are Helping to Fuel Racial Change
After sitting in silence, some whites say they're being spurred to action by recent shootings of black men
Weary of Protest, Baltimore Activists Seek Change Elsewhere
After sluggish and unsuccessful prosecution of six officers charged in the death of a young black man, Baltimore activists seek strategies other than protest to promote change
Los Angeles-Area Wildfire Prompts Evacuations
California is bearing down against continuing heat and wildfires that have forced the evacuations of hundreds of homes as red-flag warnings of extreme fire danger predicted gusty winds and scorching, dry air
Solar Project Can't Save the Forest for the Trees?
A green energy project has some environmentalists seeing red
AP Poll: Support Grows Among Americans for Stricter Gun Laws
A new AP-GfK poll shows that Americans are increasingly in favor of stricter gun laws
300 Firefighters Battle 3,327 Acre Brush Fire in L.A. County
Three hundred firefighters are battling a 3,327-acre brush fire in Santa Clarita, California, that has forced the mandatory evacuation of 200-300 homes, the Los Angeles County Fire Department said early Saturday morning. No serious damage to people
AP PHOTOS: A Selection of Pictures From the Past Week
PHOTO GALLERY: A man exercises his open carry rights in Cleveland during the Republican convention; people protect themselves from a gunfight during a coup attempt in Turkey; a child carries a kettle through a flooded street in
California Governor Denies Parole for Manson Follower
Leslie Van Houten, the youngest member of the Manson "family" that staged a series of gruesome California murders in 1969, has been denied freedom again _ her past overshadowing her decades as a model prisoner
'Went Down Fighting': Slain Deputy to Be Laid to Rest
Friends and family are gathering to remember Brad Garafola, one of three officers shot and killed last Sunday by a gunman


text:
Hunter's Specialties Accessory Hook
NOW: $3.99 (20% off!)
Was: $4.99*
Product Information:
Hang you hunting gear with the Hunter's Specialties ® Accessory Hook. Accessory Hook features a single-prong hook that screws into a tree very easily. This hook provides you with the ability to hang calls, a rattling bag, or other hunting gear. Accessory Hook comes in a 3-pack.
- Single-prong hook
- Screws in tree easily
- Hang hunting gear
- 3-pack
- Hunter's Specialties
Country of Origin: ChinaWeb ID: 11885018
Customer Reviews:
Rated 4.8 out of 5�by 19 reviewers.
Rated 5 out of 5�by jimmy bow holder quick and easy to use to use, holds bow very well. January 27, 2016
Rated 5 out of 5�by Mac Works as it shoud! small and easy to install! will buy again if needed! November 11, 2015
Rated 5 out of 5�by TXNhuntingMD Hunter's Specialties Accessory Hook They are hooks. have used multiple time in the trees for hanging back pack and a few other items. they dig in easily with pine but some of the harder woods need some work. work good for me. October 6, 2015
Rated 5 out of 5�by JohnK611 Thumbs up Has the correct ratio to make screwing in easier compared to other brands September 22, 2015
Rated 5 out of 5�by 8pointer Inexpensive Great for hanging your gear while in your treestand.I put two in each tree ,one gor me and one for my son. September 1, 2015
Rated 5 out of 5�by Loco1969 Easy to start in any tree. Good Value Easy to start in any tree. Very easy to use. November 21, 2013
Rated 5 out of 5�by Jcook Bow hook I think these hangers work great easy to screw in quite and will hold just about anything you can imagine November 6, 2013
Rated 5 out of 5�by Mr.Bill Great Product for the Price These hooks work great. Easy to install and deep threads to secure and hold medium-heavy weight. A great product for the price. I would recommend them to anyone. November 5, 2013
Rated 5 out of 5�by Paul63 Good hanger These hooks are great for hanging small items above your tree stand. I have 3 above both of my stands. October 29, 2013
Rated 5 out of 5�by XIV Good stuff Strong enough to hold the bow where I can reach it. October 15, 2013


text:
Threaded View
18 Apr 2012 10:13 AM #1
Direct not working in Architect, but IS working in browser...
I have been using the Direct class system throughout the Architect 2 beta releases. At this point, I am unable to right click a store and "load data" (depending on the time of day, it is either grayed out or returns nothing). But, the stores are still working correctly when I look at the app in a browser, with no console errors.
Any ideas as to why a store would not work inside of Architect, but does work in a browser?


text:
This star rating is the opinion of the property owner only. A Self-Rated hotel has not been assessed by the AA or Visit Britain, whose official star ratings we use across LateRooms.com.
Peasehill House4 Self rated
24 26, Harrogate Road, Leeds, LS19 6HJ
Price FromView Rooms
- Very Good
- 28 guest reviews
"We stayed in room 7 & the only bad comments are when I was trying to dry/straighten my hair I had to plug into socket at the side of the bed..."
"Loved it..."
"When we arrived at the hotel we were greeted by a lovely young woman who showed us our room and explained to us everything we needed to know..."
"The first room we had was far to small and the shower head would not stay in the upright position. We were moved to a much larger room with..."
"All good- nice location and room and good value for money. Was unable to try the food on this occasion. The only problem was the smell in th..."
About the hotel
Peasehill House is a privately owned hotel and restaurant located in close proximity to Bradford, Leeds and Harrogate city centres. The hotel is located within 5 minutes of Leeds-Bradford International airport in an area considered the gateway to the Yorkshire Dales. Built from traditional Yorkshire stone at the end of the 19th Century Peasehill House retains many of its original features and offers customers a warm reception.
All our staff are dedicated to ensuring you have a comfortable stay in our newly refurbished surroundings. Our restaurant has a reputation for high quality, freshly prepared food and is open to both residents and non-residents for lunches, evening meals and private functions.
Read MoreLess
Facilities Show/hide
- Family friendly
- Cots available , Pets Allowed
- Other
- Wedding Licence
- Parking (charges may apply)
- Car parking available onsite
- Business
- Wi-Fi Available , Wi-Fi Available In Public Areas , Wi-Fi Available In Rooms
- Dining
- Restaurant , Bar , Breakfast to go
- In room entertainment
- In room facilities
- Tea/Coffee making facilities in each room , Hairdryer in each room
- Hotel services
- Limited room service for hot food , Wake Up Call Available
Useful Info Show/hide
- From 14:00 hours
- Until 11:00 hours
- The price shown is based on the occupancy and dates you have searched for. Prices and availability are subject to change based on the arrival date, number of nights and occupancy searched for. All prices are inclusive of all local taxes.
- Pets are allowed
Customer Reviews
Our reviews are from genuine LateRooms.com customers. We verify that the customer has stayed before leaving a review.
Very Good
82% would recommend it to a friend
Customer service
Food quality
Room quality
Fawlty Towers
This b and b was lovely in the 80's but in dire need of update.
Excellent B&B with a good breakfast
We stayed in room 7 & the only bad comments are when I was trying to dry/straighten my hair I had to plug into socket at the side of the bed, then kneel on the bed to look in the mirror, very awkward.
The en-suite needs a little attention to skirting on floor as it was rotten and very noticable, however this would not deter us from staying again
Read More Less