Oracle Blog

Blog for Bobby

Wednesday Oct 01, 2008

In a previous
SocialSite blog, I had a short screen cast that described in brief what your
web site needs to do to include SocialSite
gadgets. To save you some clicking, here
it is again. In this blog, I'll give some more information, and, if you follow
along, a complete working example. A simple example, but a working example.

In a recent
email thread on our users list, Dave broke the integration down into three
necessary steps:

Step 0, part A

Have a web site. In this example, I've used
NetBeans to create
a simple web app. No frameworks, nothing fancy, just a simple web app called
SimpleWebApp with the default index.jsp file that is created for you. For
this web app, the index.jsp page could be reached at
http://localhost:8080/SimpleWebApp/. Start NetBeans, choose New Project,
then Java Web -> Web Application and follow the prompts.

Step 0, part B

Install SocialSite. If you haven't done that yet, you're in
the wrong blog. However, here are some steps that are necessary for getting gadgets
running. When you first install SocialSite and go to the web app in a browser, you'll
see a login form in the middle like this:

If you already have users in your web application, you can register them here. For
this example, I've clicked Want to register? and entered this information (the
password, not that it matters, was password):

Note: In one email to our user's list, someone tried using the built-in "admin"
user in a sample web app. By default, the "admin" user has no profile and so the gadgets
won't work until you create a profile. For instance, if you log into SocialSite as
the admin you'll see this on the main page:

Step 1

Add an authentication delegator page to your web app. In the screen cast,
this is the socialsite_context.jsp or
context.html.erb file. A request for this file is sent by the SocialSite
server, sending the same cookies to your web app that the client would. It's how
your site can assert the identity of the current user to SocialSite. A real-life
example of this file is in the socialsite workspace. For my
simple web app that has no user authentication, I've hard-coded the user for demonstration
purposes. Just create a socialsite_context.jsp page in your simple app and add
this:

In a real web app, make sure you specify the user here the same way you would in
your other web pages, either with request.getRemoteUser() for Java EE
container authentication or however you're handling authentication.

Step 2

Add the SocialSite context and Gadgets to pages in your app. Now you can add
gadgets to your pages, though first you need to add some context for SocialSite. In
this example
(save file and open in an editor), I've added two javascript elements at the top
to load information from SocialSite and to tell SocialSite where I put the authentication
delegator page. These calls need to be in all the pages that are going to include gadgets,
so it's a good idea if you have a header jspf file or something similar to put them
there. The calls look like this:

Step 3

Add socialsite_context.xml to SocialSite to specify your app's delegator page.
You're almost there. Finally, you need to let SocialSite know that it's ok to communicate
with an external app -- specifically, that it's ok to let another site assert the id
of the user. To do this, add a socialsite_context.xml file to SocialSite's
classpath. For my "SimpleWebApp" example,
here
is the file to use. Note that it contains the URL of the context delegator page
that you added in step 1. One easy way to add this file to your classpath is to copy
it to your
glassfish/domains/domain1/lib/classes/ directory, which should already
contain a socialsite.properties file that was added during installation. Restart
GlassFish to pick this up.

More official documentation is on the way, but I hope this helps you get started.
Feel free to add comments, and follow along on the
SocialSite blog for all the latest information.

Thursday Sep 04, 2008

I was fiddling with a couple sample applications to use with
Project SocialSite and found that none of the widgets I added to my pages were working. If you're unfamiliar with our widgets, they're little bits of JavaScript that you can add to your existing web pages in order to add social-networking functionality. Each one is written as a jMaki widget, and internally
they each wrap a Google OpenSocial Gadget to
provide the social networking UI.

So I had a couple new web apps that I created with NetBeans. With the jMaki plugin, I dragged some
SocialSite widgets into the pages and ran the projects. "Unable to create an
instance of jmaki.widgets.socialsite.search.Widget. Enable logging for more
details.." Oops. Turning on debugging in jMaki's glue.js file
at my web root, I see that the gadgetizer-core.js file on which the widgets rely
was not found. In fact, it was missing from my project completely, when it should
have been copied into /resources/socialsite/resources in my web root as described
next.

All of the SocialSite widgets live in /resources/socialsite/widget-name-here, and
each depends on a file, by convention, in /resources/socialsite/resources/. I can
specify this file in a widget.json configuration file, and two things are
supposed to happen. First, the jMaki plugin for my IDE copies this file into
the web app when I add a widget. Second, the jMaki runtime loads this file
before the widget so that it's available to the JavaScript engine when the
page is viewed. In my case, I see that my resources aren't being added properly
in my web apps. Even after I add them manually, I still see errors with
the file not found in certain web frameworks.

The culprit? Well, I guess I am. I wrote the original widget.json files for
our widgets, and somewhere along the way I messed up one tiny detail. Here is
the widget.json file for our search widget. This version works:

What I had, however, was a URL in the config entry that was relative to the root
of the web app:

'libs': [
'/resources/socialsite/resources/gadgetizer-core.js'
]

While this worked at runtime for some JSP apps, it failed in other cases where
the routing to resource balked at the path I was using. Looking through some existing
jMaki widgets (if using NetBeans, you can see all the code in
$HOME/.netbeans/<version>/jmakicomplib), I found my mistake. I probably took some hasty notes early in our development, or somewhere along the way the files
or jMaki changed.

We hope that Project SocialSite, besides being a useful addition to your own sites,
also serves as a good example for writing your own Google Gadgets and/or jMaki widgets.
If you're following along, though, make sure you pick up this change. Learning from
your mistakes is good; learning from my mistakes saves you time.

Tuesday May 27, 2008

Last week I gave a presentation on GlassFish to the Connecticut Java User's Group. I wanted to answer a couple questions here that came up during the talk. Big thanks to the group for letting me come talk to them, and also thanks to
Arun for letting me use his presentation.

One issue that came up was how GlassFish works with other frameworks, applications, etc., and I was asked about setting up GF as the servlet container with Apache as the web server for static content. The user was already using Apache web server in front of Tomcat and wanted to know how it would work with GF. The official docs one the topic are here, and the conversation can be followed on the GlassFish forum.

A related question was about the performance of GlassFish compared to Tomcat when used just as the servlet container with another web server in front. While I can't provide any official answer to this, the email thread can be followed (and continued!) on the forum page.

While talking about scripting support in GlassFish, I asked the group if there were other languages/frameworks that they were using besides the ones already supported. Someone asked about Perl with the Catalyst framework. I've passed along the info to the scripting team for their consideration. Please stay tuned to GlassFish Scripting for continuing information on scripting support.

Thanks again to the CT JUG for having me and for letting me plug my current project, Project SocialSite. I'll update this post with any more information as it comes in.

Monday Apr 28, 2008

I was recently setting up a couple new machines and went through my normal process:

Install a new browser or two.

Install Java if there isn't a version I want already.

Install NetBeans.

Need ant? It's already in NetBeans -- add the ant/bin directory in your NetBeans installation to your path (a good idea so you don't run into version mismatches between command line and IDE). Need cvs? There's already a nice cvs GUI in the IDE. So I'm ready for development, or so I thought.

A project I was working on, as part of the build process, used ant to check out a couple other workspaces under cvs. This failed since ant was expecting cvs to exist in my path. Oops. Ok, I could go download one of the many cvs clients, or on a Mac installation install the large developer bundle. But there's already some form of cvs inside NetBeans, so why can't I use that? No point duplicating bits on my hard drive.

Well, you can use the cvs client inside NetBeans from the command line. There is no executable cvs(.sh, .bat) script, but there's a cvs client jar file that will do the trick: org-netbeans-lib-cvsclient.jar

You can find it easily enough but here are the locations in NB 6.X:

6.0: <netbeans>/ide8/modules/org-netbeans-lib-cvsclient.jar

6.1: <netbeans>/ide9/modules/org-netbeans-lib-cvsclient.jar

So I just create a little script called "cvs" (or cvs.bat) to call the jar file. Here's the one I'm using on a Mac, with the full path left out for readability:java -jar <path>/org-netbeans-lib-cvsclient.jar "$@"

That's all there is to it. With this simple cvs script, I can now run all the command line cvs I want and use the GUI to handle the heavy lifting (ok, the heavy, the medium, and most of the light lifting).

Friday Sep 21, 2007

The Sun Tech Days Boston
event was held last week. As part of Sun Tech Day on Wednesday,
Tom Kincaid gave a talk on Java EE 6 and the future of the EE platform. This blog
captures the demonstration that we gave of an early preview of
GlassFish v3
(which is implementing Java EE 6). For more information on Sun Tech Days Boston, Ryan
Shoemaker has recorded his days at the conference:
part 1, part 2.

In the demonstration, we wanted to show four main features of GFv3:

The modular nature of GFv3, which results in very fast startup time.

Containers for web apps and JRuby apps loading on demand.

Simplified deployment of JRuby applications.

The inclusion of Java code inside a Ruby application.

Tom said I could have about ten minutes for the demonstration, but GFv3 is so
fast I think we only needed five. Hopefully the audience appreciated that -- more
of Tom, less of me fumbling around on a laptop.

The Software

GlassFish v3: The "preview1-b2" build is available
here.
Installation is simple: just java -jar <filename>. Drop the
bin directory into your path and you're all set.

NetBeans and the GFv3 plugin: By now, the Beta 1 version of
NetBeans 6
is out. Since it hadn't been released at the time of the conference,
I went with a daily build from September 7th and grabbed the GlassFish v3
plugin from the beta update center. When you add GF to the NetBeans's server list,
NB gives you a download button to grab the app server:

The version isn't the same as the preview 1 b2 shapshot that I was using,
but that combination worked anyway. You don't need to add the GFv3 server to NetBeans
for these examples since I give instructions for deploying/undeploying from the
command line.

JRuby: Following the directions on
Arun's blog,
you can install JRuby 1.0, add the
bin directory to your path, and install Rails with

jruby -S gem install rails -y --no-rdoc

After this, just add the JRUBY_HOME value to the end of the
asenv.\* file in glassfish/config/.

The Demonstration

Running GlassFish v3: In your glassfish/lib directory, you can see all of
the jars that make up the kernel and containers of GFv3. That little (less than 15k)
jar file called glassfish-10.0-SNAPSHOT.jar is your target. Assuming you are
in the glassfish directory, give the Java command:

Note the startup time, in this case under .8 seconds on a slightly old laptop.
You can browse http://localhost:8080 to see that the
server has indeed started and is serving static html content. Add another html file to
domains/domain1/docroot and you can view it in the browser, or edit
index.html
(go ahead, it's your app server!) to see changes. Now it's time to add some applications.

A web application example: In NetBeans, create a simple web application.
Ctrl-Shift-n is one way to bring up the "New Project" window, and you can
choose Web -> Web Application to create a simple web app. The
index.jsp file will come up automatically in the editor. Just add some text
of your choosing and build with F11. We called the project "jsphello" and the
war file was built in jsphello/dist/jsphello.war. If you have the GFv3 plugin,
you can deploy with NetBeans, but we deployed from the command line in order to watch
both the server and asadmin output at the same time. To deploy, use

asadmin deploy --path
<path to jsphello.war>

The asadmin script will call a Java command to deploy the application, and your
output should look something like:

Note that in the GlassFish server log, the web container is loaded when it is needed.
If you stop and restart the server now, you will that the web container is loaded at
startup since a web application has been deployed. You can undeploy the application
with:

asadmin undeploy --name jsphello

To get a list of deployed applications, use:

asadmin list-applications

After undeploying the web application and using the "list-applications" command, your
output will look like the text below. You can see that the web container is loaded,
ready for another web application to be deployed (if you restart the server, it will
not load the web container until you need it).

A JRuby example: In NetBeans, open the New Project window and choose
Ruby -> Ruby on Rails Application. On the next page, give the application
a name (e.g., "railshello") and click Finish. After the IDE is finished generating
the files needed, you can add a controller and view for a simple "Hello World" application.
Right-click on the project name and choose Generate. Fill out the resulting dialog
as below and click Ok:

NetBeans will then generate say_controller.rb and hello.rhtml files for
you. We edited the controller to add a string and then used that string in the "hello"
view.

GlassFish v3 supports a "straight" deployment of JRuby code. To deploy our 'railshello'
application, we don't have to first wrap it in a war file. We can simply call asadmin
and deploy the application directory (asadmin calls the proper "java -jar ..." command):

Watching the server log, you can see that the JRuby/Rails runtime is loaded into GFv3
as needed. Then the application is deployed and is ready to run.
To access the page once it's deployed, use http://localhost:8080/railshello/say/hello.
This directory deployment of the application makes for a very fast development
cycle. For instance, if you change the @hello_string value in say_controller.rb,
you only have to save the file and reload the page in your browser.

Adding some Java into the Ruby code: Using the same JRuby/Rails application, you
can add Java code directly into the say_controller.rb file without any other compilation
or deployment steps. For our example, we added some trivial Java code in to create a
HashMap and set the value of @hello_string using a value in this map. The
new version of say_controller.rb:

Now simply save the file and reload the page in your browser. The mix of Java and
JRuby code works without any other steps since we have done the directory deployment.
Finally, to undeploy the application, give the same command that you used to undeploy
the jsphello example:

asadmin undeploy --name railshello

Though this early version of GFv3 does not show anything in the log when
you undeploy the app, you can verify that it is no longer deployed with the asadmin
'list-applications' command described above.

Tuesday Apr 24, 2007

In Java EE applications, security roles are used to restrict access
to resources. A typical example is to limit access to parts of a
business web site to users who are in the role "customers," while
allowing users in the role "suppliers" access to other parts
of the site. The application developer can specify which
URLs or EJB methods can be accessed by users in which roles, and
can programmatically make security decisions based on user roles
at runtime. So a role is a logical privilege that can be granted
to (or withheld from) users to control access within an application.

The identities of the users are stored in the application server as
principals (also called "users"), which can belong to groups. Thus
the privileges represented by the roles can be mapped to actual users
by mapping the roles to principals or groups. This decoupling of
the application's roles and the container's principals/groups
allows the same application to be deployed on
different servers without any changes to the code. Only the
security role mapping needs to be changed in the deployment
descriptor (for GlassFish, this is in sun-application.xml,
sun-web.xml, or sun-ejb-jar.xml). The deployer could
map the role "suppliers" (continuing
above example) to an existing group "partners," a principal "admin,"
or even a group with the same name "suppliers." In this last case,
a simplification can be made such that the default principal to role
mapping is used and no role mapping is required in the deployment
descriptor. This can be useful when you are writing an application
and already know which groups are used in the server to which
you will be deploying.

The following is a simple web example that uses default principal to role
mapping and so does not use a <security-role-mapping> element
in the sun-web.xml file. In fact, it does not use sun-web.xml at all.
To add a user and group for this example, open the admin console (normally
localhost:4848) and choose:
Configuration -> Security -> Realms -> file in the
tree in the left pane. Then, in the right-hand pane, click
Manage Users. Click New, enter "sparky" for User ID,
add "users" to the Group List, and use "ee" for a
password. Click OK.

This application consists of a simple jsp page, and it can only be
accessed by someone in the role "users" (which matches the group "users"
created above). This is the entire page, index.jsp:

To create the application, save index.jsp into a directory, create
a subdirectory "WEB-INF" and save web.xml into it, and create
the war file: 'jar cvf test.war \*' The war file can also be
downloaded here.

Because security role mapping happens at deployment time, the default
mapping must be turned on before the application is deployed.
To turn on the default mapping, choose Configuration -> Security
in the admin console. Click Enabled next to Default Principal
to Role Mapping and Save.

Then the example war file can be deployed through the admin console
or with 'asadmin deploy test.war'. When you attempt to
reach the page in your browser (for instance with
http://localhost:8080/test),
you will be prompted for username and password. Entering "sparky" and
"ee" should take you to a page with Hello sparky. The example
works because the same string is used for both role and group, and
so any user in the group "users" will also be in the role "users."

Friday Sep 22, 2006

The milestone 2 release of WSIT includes some "behind the scenes" changes in the way endpoint metadata can be exchanged. All WSIT endpoints can now respond to metadata exchange ("Mex") requests to obtain the wsdl and schema information. These requests are small soap messages requesting the endpoint's data. They are nothing more than an action header and an empty body, and the endpoint responds with a mex response containing wsdl and schema documents.

On the client side, wsimport can use the mex code to make requests to the service for metadata. While this is normally transparent to the user, if you're running wsimport while using a traffic monitor (such as wsmonitor) you may see these messages.

Normally, wsimport will make mex requests when you give the address of the endpoint itself such as "http://example.com/myservice." In the past, you would have to use a "?wsdl" at the end of the address to specify the WSDL location. With mex, you can still give wsimport the WSDL location, or you can use the endpoint location. In this latter case, wsimport with mex will try various mex requests: for instance, a soap 1.2 attempt followed by a soap 1.1 attempt. If these all fail, meaning that you're trying an endpoint that doesn't support mex, wsimport will default to trying the HTTP Get call to the address with "?wsdl" appended.

These mex requests and responses allow greater flexibility in how metadata is obtained, and pave the way for obtaining metadata with other transports in the future.