
Using Objective-C On The Server - jrmg
http://blog.securemacprogramming.com/2012/03/using-objective-c-on-the-server/
======
Argorak
I had the "joy" to work on a pretty broken WebObjects project a few years ago.
I also didn't enjoy the framework a lot back then. So, the open question:

Is there anything in WebObjects that makes it worth revisiting the framework?

~~~
gecko
WebObjects is, in many ways, two products: EOF4 and the web components. I'm
going to separate them.

EOF4 was an absolutely insanely well-designed ORM that I absolutely still
think has held up very well. EOF4 assumed, _hey, you already have a relational
schema!_ and _hey, you like your objects to actually act like objects!_ , and
rather than trying to shoehorn one into the other, EOF4 instead provided
excellent tools so that _you_ could specify how your database should be
represented as objects. Other tools today still provide that (e.g.,
Hibernate), but EOF4 provided it in an extremely easy-to-use way that at once
provided good abstractions, _and_ the easy ability to dive under the covers
when necessary.

WebObjects's web components, on the other hand? Probably not. Prior to
widespread JavaScript, WebObjects made it extremely easy to write stateful
websites without going crazy playing with sessions and the like. Nowadays, the
right way to do that is to write a JavaScript application and call a bunch of
REST endpoints--something doable in WebObjects, but needlessly complicated.
Throw in Objective-C's memory model, and I don't really have any desire to
work with WebObjects again.

If this project revives EOF4, and provides a cleanly RESTy way to use
WebObjects, I think there could actually be a lot of value for companies that
want to reuse their Cocoa models on the server. I don't think we're going to
see a general renaissance of WebObjects, though.

~~~
Argorak
Thank you for the insight. I mostly used the frontend components and was
already using proper frameworks handling sessions and alike, so this might be
why I didn't enjoy it a lot.

------
swalsh
I often feel like IOS apps work well despite Objective-C, not because of it.
The idea of someday having to maintain a server written in Objective-C scares
me.

~~~
justinvoss
iOS and Mac apps are a lot of fun to write and work with, for two reasons:

1) Objective-C is a pretty decent language. It's not perfect, it has some
baggage, but overall it's pretty neat and has enough flexibility to build a
good platform.

2) Apple has built two good platforms, in AppKit (Mac) and UIKit (iOS). These
frameworks are the real secret sauce, not the language. They're comprehensive
and generally well-built, and make working on Apple platforms a joy. They
actually take advantage of the unique features of Obj-C.

If someone could produce a web framework of the same caliber as UIKit, I think
Objective-C would make a great server-side language. But building such a
framework is not easy.

------
equalarrow
This is interesting; just last night I was looking for some obj-c web app
frameworks. I spend most of my day working on iOS stuff and I thought why not
play around with implementing some web services with obj-c?

While I tip the hat to the gsw folks, I always thought WebObjects was a
horrible dev environment. It always seemed overly complicated and compared to
where the web is now, to me it doesn't make any sense to use.

The closest thing I've found to 'usable' for making a dynamic site or api is
frothkit: <http://code.google.com/p/frothkit/> But, it needs Cocotron to work
and I don't know if it works with the Lion Xcode.

Anyway, I think obj-c is totally legit for webapps that require speed. Maybe
that magic framework will break through. However, I definitely do not think
GSW is it, sorry.

------
prodigal_erik
Compared to the JVM (and probably even V8), it's slow. Compared to Javascript
or Ruby or Python, it's no more expressive, probably less. And it's more
dangerous than any of those, being just as brittle as C. I don't see any
relevant niche in which it's best suited, other than being artificially
blessed for half of the smartphone market.

~~~
mrsteveman1
Slow is something you're going to have to define more, in which situations?
Drawing? String parsing? Concurrency? And in which real world situations does
obj-c "slowness" hurt it where any of the others you mentioned would be a
better fit?

~~~
prodigal_erik
Message dispatch: The Hotspot JVM contains years of work to branch-on-type or
inline as many method bodies as possible, while the ObjC runtime has to search
a cache for the IMP to handle a SEL and then jump through that function
pointer (which superscalar pipelines really hate) every time you do anything.

Object layout: The modern ObjC runtime imposes some indirection on every field
access (because your old object code doesn't know the current size of your
base class), where a JIT compiler can bake offsets right into machine code.

GC: ObjC has a conservative collector, so it has to do some work for each dead
object rather than just copying the live ones and recycling the whole arena.
And a lot of people still use reference counting, which is the slowest high-
overhead form of GC by far.

It's all clever stuff but seriously compromised by the need to produce static
object code that's resilient against changes. If you can afford ObjC, you can
probably afford a bigger runtime where everything really is an object and the
slightest mistake doesn't blow up randomly.

~~~
alastairh
Message dispatch: If you really, genuinely, need higher performance, you can
grab the IMP yourself. On some architectures, jumping through an IMP is
actually faster than an apparently direct call (e.g. because of the way the
dynamic linker works).

Object layout: Again, if you care, you can grab a pointer to the variable
you're using.

GC: I doubt the GC is used all that much in practice because retain/release is
faster and better understood. Your claim that reference counting is "the
slowest high-overhead form of GC" is wrong, because it is based on old
automated implementations that inserted reference counting operations
automatically _everywhere_. _Manual_ reference counting is not usually dealt
with in the GC literature, and as it happens Apple's more recent automatic
implementation, ARC, does substantially better than the historic auto-
reference-counting implementations that most papers discuss (indeed, in some
cases it is more efficient than manual reference counting).

Another thing worth noting is that Apple's Foundation (and Core Foundation
underneath it) have very efficient implementations of the collection data
types, and indeed adapt their behaviour depending on their content. This does
not happen to the same extent in STL or Java, and means that simple programs
can sometimes outperform their equivalents in other languages merely because
high performance implementations in competitor languages would require that
the author tailor his/her use of collections according to e.g. the number of
items presented, which is not necessary with ObjC (at least on OS X). You can
read a little about this kind of thing here:

    
    
      http://ridiculousfish.com/blog/posts/array.html
    

Finally, I'll note that in ObjC, you always have the option of writing
performance-critical code paths in plain C, or even in assembly language. You
can even construct your own task-specific JIT, if you like (which is made
considerably easier by the availability of the LLVM libraries, though they are
not the only possibility).

To summarise: I don't buy your "Hotspot JVM means Java is faster" argument.
It's based around a set of assumptions that don't hold in practice. Java is
definitely a fast language these days, and for some applications the JIT does
indeed result in a performance boost, but it is _always_ possible to equal or
exceed Java's performance in plain C (and hence in Objective-C), albeit with
some degree of effort.

------
Aqua_Geek
I've thought about this a lot over the past few years. I think it'd be awesome
to be able to compile your web app into a bundle that gets loaded by some
Objective-C server.

That being said, I think the performance improvement would have to be
substantial to get me to switch from a scripting language.

~~~
mrsteveman1
That's exactly what I did (see other response), and it works pretty well for
the most part. The bundle gives you both a nice container to deploy, along
with the ability to pull assets out of it with a relative bundle path, just
like on iOS/Mac.

Launchd works really well for keeping your server process running too, zero
issues there.

The performance was really good, with the right libraries involved and some
tuning you could have something really nice, but very few groups are focusing
on it at the moment :\

------
mrsteveman1
A few months ago I was making plans for what is now my home base website for
App Store & other projects. I'd been working in obj-c for about 2 years both
on the Mac and on iOS, but also had a fair bit of python experience with
Django, App Engine, etc. I decided to give it a shot with obj-c.

I knew about the handful of "big" frameworks for handling this task with
obj-c, but rejected them in favor of getting more hands-on experience building
it, pushing myself and learning in the process. It was, of course, a personal
project, something I alone was responsible for working with, so I decided it
was OK if I experimented a little.

I went into the project knowing I would eventually have to port it to Python
(and I did), but it was a lot of fun :)

I hand picked some lightweight libraries to handle specific parts of the
server. One has to be cautious knowing that a library developer who thinks
their sole target is a tiny cellphone, may not be worrying about things you
will eventually have to worry about on a server.

I picked CocoaHTTPServer to handle requests and responses, and someone else
had written a nicer "route" style interface for it which meant all of the
possible responses to an http request were simply a series of blocks defined
in a row, each with a regex or named parameter style URL route defined right
there next to the code that would handle it. This works out to be quite a
similar layout in code as something like Bottle/Python or Express/Node.js,
both of which I've worked with now and I very much prefer this style.

I made good use of blocks & dispatch queues elsewhere as well, firing off an
async block whenever I needed to pull new tweets from Twitter's api, or update
Github repo stats (both are cached and displayed on the site).

I picked a Mustache template library and a Markdown parser library I found on
Github for handling dynamic page generation & blog post syntax, respectively.
Sqlite for storing anything that needed to be stored, Regexkit-lite for
properly checking and handling anything that may be passed in to a url query
or post body, etc.

I changed the Xcode project type to build me an executable binary that lived
inside a bundle (Server.bundle) containing all the pages and assets the thing
needed, so it could be deployed as a single "thing".

I also got Lion's sandboxing to work quite easily, which in theory would give
some moderate protection against the entire server being compromised if
someone managed to get an exploit to run inside the process.

Other than some CPU usage issues with the template library (easily solved by
nginx caching pages), it all worked really, really well. I threw enough abuse
at it, and did enough debugging that I was confident it would hold up well in
production (which turned out to be wrong).

And then it came time to deploy somewhere, a problem I had been working on
since day one, so i knew what i was getting in to.

There were only a few options: a cross-compiler framework like Cocotron
(compile on Mac, run on Linux), one of the native *step libraries like GNUstep
running on Linux or FreeBSD, or simply deploy on a Mac somewhere.

I tried all combinations other than Mac first, I built out a GNUstep
environment with libobjc2 on FreeBSD, tried the cocotron->linux stuff, each
time watching something blow up in my face due to my choice of components and
my requirements.

While obj-c is cross platform, some of the libraries and features I chose to
use were not. CocoaHTTPServer is built on top of CFNetwork, which is not part
of any obj-c framework/library, but rather a lower level Apple C library only
found on Macs. There's a "lite" open source version, but I quickly discovered
that solving one issue like that would only bring up another. For instance,
dispatch blocks will only work with GNUstep at the moment, and only when it is
compiled with clang, against libobjc2, a combination few if any Linux distros
actually ship in their repos.

Not a lot of people interested in deploying modern, dispatch/block-heavy,
obj-c 2.0 code to Linux, not nearly as many as there are deploying such things
to OS X or iOS.

So I decided why not just run on a Mac server somewhere? After all I can't
solve every problem all at the same time, and on a Mac a lot of those problems
were non-existent, plus the Mac approach would allow me to use things only
available on a Mac, like easy sandboxing and potentially keychain integration
for auth.

I found a Mac VPS provider that ran Xserves and hosted copies of Lion server
inside VMware (HostMyApple, not someone fudging the licensing in moms
basement). It worked really, really well, as long as I treated it like a
headless server (issues with Lion Server are another story for another time).
My sandboxing worked, performance was fantastic aside from the CPU usage
during a cache miss, so I was fairly happy.

Long story short though, memory leaks in 3rd party libraries (that only
someone running a server would likely hit), coupled with higher hosting costs
(and fewer choices), smaller community and a desire to use some things that
are really only "mature" in other languages (database adapters, etc), caused
me to spend a few days porting the entire thing to Python.

My site now runs on a Linode, and is a nearly identical clone of the obj-c
version, ported as a Python/Bottle app. There was nothing particularly wrong
with the obj-c approach, but the primary focus of nearly all obj-c developers
and libraries is iOS, where processes never live longer than a few minutes, or
Mac where a crash or leak is only going to affect one person rather than a few
hundred in-flight requests. I expect if I had stuck with one of the
"frameworks" intended for this purpose it would have been a viable option but
as I said before I wasn't looking for turn-key, but wanting to get my hands
dirty :)

------
binarycheese
I don't think Objective-C was ever designed for large scale Enterprise
projects.

~~~
gecko
Dell ran its entire business on the Objective-C version of WebObjects (4.5)
for quite some time, until about 2000, if I recall correctly. I'm not quite
sure what you mean by "large-scale enterprise", but I'd hope Dell at its
heyday would qualify.

