Ok so this one isn't really web development related but I'm putting it in here anyway. It's not like they're charging me by the blog post, right?
Right?
Er.. yeah so anyway here's another example of a time when you just want a simple answer to a simple problem and Googling for it is like asking for a repair manual for a car when all you need is to know where the oil dipstick is.
Here's the scenario. You're the friendly, happy sysadmin for your company running an Exchange 2003 E-mail server. You've been asked to create a new user account for some lucky new employee who will be accessing his mail using OWA. You create the account, set the password, open up your web browser to test and here's what happens:
You enter the credentials when prompted but it shrugs that off and asks again. You check to make sure you didn't fat finger anything and enter the credentials again. It shrugs that off too so you try one more time and all you get is an empty web page that says "Error: Access is Denied."
So you close the browser and re-open it and try again. Same thing.
So you go back into Exchange and reset the password to cover that base and you try logging in again. Same thing.
What's the problem?
Well you Google that and you'll get a laundry list of protocols, permissions, settings and inheritance to check over. Well that's great but what if everybody else's account is working and this new guy's isn't? Isn't there something simple you can check?
Yes there is.
Open up the properties for that user and click the "Account" tab. Look under "Account Options." See all the checkboxes? See the one on top? "User must change password at next logon" is checked, isn't it?
Yeah. Thought so. Uncheck it.
See, depending on how your protocols are set up, your server may be unable to prompt a user through the browser to change his or her password when they're trying to authenticate. If your user absolutely must login for the first time using OWA, they're going to have to change that password manually once they're logged in.
Friday, September 17, 2010
Tuesday, August 24, 2010
Eclipse Ganymede, Portlets and Weird Errors.
Ok so you're doing some of the training exercises from Liferay and you're all excited about working with Liferay 6. (You are, aren't you? Isn't everyone?) You're doing the classic Pitcher-Catcher portlets to practice with inter-portlet communication to show off the Portlet 2.0 specs and everything's going great when...
...You're getting weird errors in Eclipse Ganymede and can't seem to fix them.
The first one is in your view.jsp files where this line
taglib uri = "http://java.sun.com/portlet_2_0" prefix = "portlet"
Is erroring out. Specifically, it says "Cannot find the tag library descriptor for "http://java.sun.com/portlet_2_0"
And nothing you've done has made that go away. You've tried making sure you have the right util-taglib.java file in your build path and nevertheless it won't go away. What's wrong?
Blame Eclipse.
Now, I love Eclipse. I think it's the cat's meow and I don't see myself ever using anything else, but Ganymede isn't perfect and it has a few warts. This is one of them. The solution:
Ignore it. It's a bug but it won't mess up your ability to build and deploy it with Ant.
"But wait!" You say. "I have another error in my jsp. in the line
String pitch = (String)renderRequest.getParameter("pitch");
it has an error saying 'renderRequest cannot be resolved' so how do I fix that?"
Your portlet.jar file is where it's supposed to be, right?
"Right!"
Then ignore that one too. Run your Ant deploy. See, Eclipse is noticing that in that .jsp file there's no declaration for renderRequest so, in its neurotic wisdom, it has assumed that you simply failed to declare the variable and it errors it. That won't stop it from building your project since Java code in .jsp files doesn't get compiled until the first time the page is requested, and Tomcat's got the definition it needs for renderRequest. It'll be fine.
Batter up!
Thursday, July 15, 2010
Liferay 6 Plugins SDK and the Deploy Path
So I'm excited to start creating and deploying portlets in the new Liferay 6 portal, so even though I've built portlets for Liferay 5 already I wanted to go step by step in version 6 as if I'd never done it before, in case there were differences.
I'm doing this in Linux Ubuntu, although that shouldn't matter in this case.
Well as always, getting the SDK set up is pretty easy but when we say "easy" what we really mean is "Done in very few steps." It still assumes an awful lot about your situational awareness, as it were, as well as the adaptability of the tools you're working with.
This is Liferay Plugins SDK 6.0.2 by the way, and the Liferay itself is bundled with Tomcat 6.
When setting up your environment the best practice, according to the manual written by Richard Sezov, Jr (which I'm enjoying very much, by the way), is to have a folder structure that looks a bit like this:
[Code Home]/bundles/[Liferay Bundle]
[Code Home]/plugins
Now, this seems pretty clear, doesn't it? Just drop your unzipped Liferay Portal bundle into /bundles then alongside that your unzipped SDK. Simple, right? Well yeah, and no.
This notation is a bit confusing. When I set up a Liferay portal bundle on my development machine I like to keep the name of the original unzipped folder. The reason for this is at this moment I actually have 3 different Liferay bundles on my development computer, any one of which I may need to use at any time, and by keeping the original folder names I keep them straight and avoid confusion. This is what my structure looks like:
[Code Home]/liferay-portal-6.0.2/tomcat-6.0.26
[Code Home]/liferay-plugins-sdk-6.0.2
There is a side effect to this, you're going to have to fix your build properties. You see, the default configuration in the build.properties file in your SDK is assuming that your Liferay bundle is in a folder called /bundles and the actual tomcat home folder is inside that. In other words, it thinks you're renaming /liferay-portal-6.0.2 to /bundles. You could do that if you want to, but I prefer to keep my development structure consistent so I changed the default. To do that:
Create a file in the SDK directory and name it build.[your username].properties. In this file add the line:
app.server.dir=${project.dir}/../liferay-portal-6.0.2/tomcat-6.0.26
This overrides the line in build.properties that sets the app.server.dir variable to ${project.dir}/../bundles/tomcat-6.0.26.
Nice, huh?
Now when you run the create.sh to start building your new portlet it will follow the structure you've created.
Friday, May 21, 2010
Where is that EntityManagerFactory?
Ok so how much do you hate this error:
java.lang.NoClassDefFoundError: Ljavax/persistence/EntityManagerFactory;
Yeah, on a scale of 1 to 10 I'd rank that one about a 12. You're using Eclipse Ganymede, you've checked your Java build path and there are your jars. (Mine are in a User Library I named Eclipselink) You've checked the /bin folder in your Tomcat and there they are. You go to run your app and
KABOOM
EntityManagerFactory eludes you and your application.
By this point much of your hair may be in clumps on the floor around your chair, much to the disgust of the weekly cleaning crew. People are avoiding your desk at all costs because you're radiating frustration like the outer layers of a star going nova and still no solution presents itself.
And now for the solution:
Eclipse knows you want to use those particular jars, but it may have forgotten where they are. In the Project Explorer view expand your user library and right click your persistence jar. Select Properties. In the new window that pops up the dominant feature will be a text field labeled "Location path:" and if it's empty, BINGO that's your problem.
Click the "External File..." button and browse to the actual jar. Click "OK." Do this for each of the jars in your user library while you're at it.
Don't worry, the hair will grow back.
Thursday, April 22, 2010
Making JPA Play Nice With a DataTable
It can be done!
No... really... it can!
Lesson learned for today... The following two statements:
Query query = em.createQuery("Select p from Chapters p");
Query query = em.createNativeQuery("Select * from chapters");
are NOT interchangeable.
I'm serious.
don't believe me? Go ahead and try it. Do a
No... really... it can!
Lesson learned for today... The following two statements:
Query query = em.createQuery("Select p from Chapters p");
Query query = em.createNativeQuery("Select * from chapters");
are NOT interchangeable.
I'm serious.
don't believe me? Go ahead and try it. Do a
query.getResultList();
and then feed that output to a JSF DataTable and watch what happens.
The first one will work. The second: KABOOM.
You see, the getResultList() method returns a List. Simple, right? Nah. Not really. You see, at issue here is what, exactly that List contains.
Using the EclipseLink SQL-like language in the createQuery does two things: First, it abstracts the database so that the command will run no matter what kind of backend you're using. Second, it returns a List of objects of the type specified in the query. In the first statement, the createQuery method, the word 'Chapters' is capitalized because it refers to a class not a table. It will return a List of type Chapters (in this case) and when we wire that up later to the DataTable component it will happily cast the objects as Chapters objects (As specified in the faces-config.xml) and display them.
On the other hand, running that createNativeQuery method is asking for trouble. It's straight SQL, and in this example would run fine in prettymuch any database, but not all databases are created equal and the more complex your query is, the more committed you are to the database you originally wrote it for. Know what the other problem is? Yep, by now you should have guessed it... you'll get back a List of Objects.
Good luck trying to cast those as Chapters objects.
The EL isn't going to be much help so a list of generic Objects gets passed to your poor, unsuspecting DataTable and KABOOM! You'll be Googling this: "java.lang.NumberFormatException: For input string:"
See, when this big list of generic objects gets sent to the DataTable it doesn't know how to interpret these things, the EL is relying on the Chapters bean for guidance on finding the fields but these aren't Chapters objects. They're generic lumps of data that came from a database. It appears the EL is trying to stick the index of the elements into the first field you've defined in your table. That's an int. Bad mojo.
The first one will work. The second: KABOOM.
You see, the getResultList() method returns a List. Simple, right? Nah. Not really. You see, at issue here is what, exactly that List contains.
Using the EclipseLink SQL-like language in the createQuery does two things: First, it abstracts the database so that the command will run no matter what kind of backend you're using. Second, it returns a List of objects of the type specified in the query. In the first statement, the createQuery method, the word 'Chapters' is capitalized because it refers to a class not a table. It will return a List of type Chapters (in this case) and when we wire that up later to the DataTable component it will happily cast the objects as Chapters objects (As specified in the faces-config.xml) and display them.
On the other hand, running that createNativeQuery method is asking for trouble. It's straight SQL, and in this example would run fine in prettymuch any database, but not all databases are created equal and the more complex your query is, the more committed you are to the database you originally wrote it for. Know what the other problem is? Yep, by now you should have guessed it... you'll get back a List of Objects.
Good luck trying to cast those as Chapters objects.
The EL isn't going to be much help so a list of generic Objects gets passed to your poor, unsuspecting DataTable and KABOOM! You'll be Googling this: "java.lang.NumberFormatException: For input string:"
See, when this big list of generic objects gets sent to the DataTable it doesn't know how to interpret these things, the EL is relying on the Chapters bean for guidance on finding the fields but these aren't Chapters objects. They're generic lumps of data that came from a database. It appears the EL is trying to stick the index of the elements into the first field you've defined in your table. That's an int. Bad mojo.
Wednesday, April 21, 2010
persistence.xml and the Errors Who Love it.
Have you ever done a Google search for a problem you're having and all of the replies you find in various blogs, forums and tutorials say basically the same thing?
Yeah, me too.
That's what I did when looking for the reason why my EclipseLink JPA project wasn't behaving itself as a web app.
Search for this string sometime:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named
And you'll get a fascinating myriad of responses, most of which will tell you where to put your persistence.xml file (META-INF under WEB-INF/classes in the case of a web app, by the way, although typically your IDE will do that for you.) but what if you've done that already?
Some more will tell you to make sure you include the line
org.eclipse.persistence.jpa.PersistenceProvider
in your persistence.xml file and still others will tell you to verify that you're using the same Persistence Unit name in
persistence-unit name="myJPAname"
and the line in code where you're instantiating your EntityManager
emf = Persistence.createEntityManagerFactory("myJPAname");
But what if you've done all of that?
What to do?
Ready for the silly, stupid facepalm solution?
Make sure it's in your servlet container/web server lib folder.
For example, my Tomcat 6.0 has a folder in:
/home/mylogin/Portals/training_tomcat/apache-tomcat-6.0.20/lib
Yeah. Make sure your eclipselink and persistence jar files are in there too.
Yeah, me too.
That's what I did when looking for the reason why my EclipseLink JPA project wasn't behaving itself as a web app.
Search for this string sometime:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named
And you'll get a fascinating myriad of responses, most of which will tell you where to put your persistence.xml file (META-INF under WEB-INF/classes in the case of a web app, by the way, although typically your IDE will do that for you.) but what if you've done that already?
Some more will tell you to make sure you include the line
org.eclipse.persistence.jpa.PersistenceProvider
in your persistence.xml file and still others will tell you to verify that you're using the same Persistence Unit name in
persistence-unit name="myJPAname"
and the line in code where you're instantiating your EntityManager
emf = Persistence.createEntityManagerFactory("myJPAname");
But what if you've done all of that?
What to do?
Ready for the silly, stupid facepalm solution?
Make sure it's in your servlet container/web server lib folder.
For example, my Tomcat 6.0 has a folder in:
/home/mylogin/Portals/training_tomcat/apache-tomcat-6.0.20/lib
Yeah. Make sure your eclipselink and persistence jar files are in there too.
Eclipse Generates it, you fix it.
Lesson learned...
So as I continue my mad scientist like exploration of JPA, specifically EclipseLink, I have learned that while the Eclipse API offers a great deal of automation and management, you still have to watch it closely unless you want to spend time ripping your hair out.
Take the example I ran across this morning.
OS: Linux Ubuntu 9.10
Database: MySQL 5.1
API: Eclipse Ganymede
JPA Provider: EclipseLink
This was a simple console app designed to play around with columns while learning the EclipseLink SQL-ish query language. I created a table called "chapters" in my database designed to hold some simple data related to a wargame. (You Warhammer 40,000 fans will like this.) Columns include chapter_name, parent_legion, primarch... obviously all VARCHAR type columns.
One of my columns is called loyalist. It's a BIT column. Hold that in your mind for now...
Now, Eclipse has a nice little feature that allows you to automatically generate entities from your database. Very cool. Run the utility and watch that entity class grow. Nifty.
2 problems:
The first problem is that EclipseLink is going to assume your table name is in ALL CAPS. This is easy to get confused on because the select statement in a case like this reads:
Query query = em.createQuery("Select p from Chapters p");
That syntax is correct because "Chapters" here refers to the entity Chapters, not the table. That means that you're not directly controlling the name of the table the actual SELECT command will be run against. So if your table is named in all lowercase, like mine, running this code will blow up your app.
The solution: Pretty simple, actually. You just have to use an annotation to override the table name. Just add something like this under your @Entity annotation:
@Table(name="chapters")
Good to go. Now EclipseLink will run a SELECT command against table name "chapters" and not "CHAPTERS."
The second problem is a little easier to solve and yet I find it more annoying. When Eclipse generated the entity and tripped across that BIT column, it created a matching member in my class and made it type byte.
KABOOM.
So I manually changed it to boolean in my entity code and now it's happy as a clam.
So as I continue my mad scientist like exploration of JPA, specifically EclipseLink, I have learned that while the Eclipse API offers a great deal of automation and management, you still have to watch it closely unless you want to spend time ripping your hair out.
Take the example I ran across this morning.
OS: Linux Ubuntu 9.10
Database: MySQL 5.1
API: Eclipse Ganymede
JPA Provider: EclipseLink
This was a simple console app designed to play around with columns while learning the EclipseLink SQL-ish query language. I created a table called "chapters" in my database designed to hold some simple data related to a wargame. (You Warhammer 40,000 fans will like this.) Columns include chapter_name, parent_legion, primarch... obviously all VARCHAR type columns.
One of my columns is called loyalist. It's a BIT column. Hold that in your mind for now...
Now, Eclipse has a nice little feature that allows you to automatically generate entities from your database. Very cool. Run the utility and watch that entity class grow. Nifty.
2 problems:
The first problem is that EclipseLink is going to assume your table name is in ALL CAPS. This is easy to get confused on because the select statement in a case like this reads:
Query query = em.createQuery("Select p from Chapters p");
That syntax is correct because "Chapters" here refers to the entity Chapters, not the table. That means that you're not directly controlling the name of the table the actual SELECT command will be run against. So if your table is named in all lowercase, like mine, running this code will blow up your app.
The solution: Pretty simple, actually. You just have to use an annotation to override the table name. Just add something like this under your @Entity annotation:
@Table(name="chapters")
Good to go. Now EclipseLink will run a SELECT command against table name "chapters" and not "CHAPTERS."
The second problem is a little easier to solve and yet I find it more annoying. When Eclipse generated the entity and tripped across that BIT column, it created a matching member in my class and made it type byte.
KABOOM.
So I manually changed it to boolean in my entity code and now it's happy as a clam.
Subscribe to:
Posts (Atom)