Problem with porting current system

Posted by jmls on 25-Jul-2008 06:18

Came across the first problem in porting our application to 10.2A.

We initialize a single "session" class. In order to find out if we need to instantiate this class, we run through the session objects looking for the right class. The code snippet is :

DEF VAR SomeObject AS CLASS PROGRESS.lang.OBJECT NO-UNDO.

ASSIGN SomeObject = SESSION:FIRST-OBJECT.

FindSomeObject:

DO WHILE VALID-OBJECT(SomeObject):

IF SomeObject:getClass():TypeName EQ "myapp.library.sessionsingleton" THEN

DO:

ASSIGN SessionObject = CAST(SomeObject, "myapp.library.sessionsingleton" ).

LEAVE FindSomeObject.

END.

ELSE ASSIGN SomeObject = SomeObject:NEXT-SIBLING.

END.

IF NOT VALID-OBJECT(SessionObject) THEN /* load it */

The problem we came across was trying to run this program from the OEA . This problem manifested itself when the GetClass method returned ?.

Now, the help for GetClass mentions "This method does not apply to instances of .NET classes. If the current class is an instance of a .NET class, this method returns the Unknown value (?)."

So, this is expected behavior in 10.2A. The problem is that it breaks an existing system, and we would have to modify existing code to make this work, so it is not desirable behavior.

Could a flag / option be added to the GetClass method ? So that:

GetClass() or

GetClass(Progress) only looks at progress object(s)

GetClass(Net) only looks at .net objects

GetClass(ALL) looks at both sets

Message was edited by:

Julian Lyndon-Smith

fixed typo in typename

All Replies

Posted by jankeir on 25-Jul-2008 06:25

Isn't it the object chain that would require the parameter, rather than the GetClass method?

So that you get

SESSION:FIRST-OBJECT

or SESSION:FIRST-OBJECT(Progress)

...

and NEXT-SIBLING(Progress)...

Posted by jmls on 25-Jul-2008 06:27

That would make a lot more sense.

Posted by Admin on 25-Jul-2008 06:28

Hi Julian, are you aware that we have static data members since 10.1c? So instead of searching the one (and only) instance of the session class, you could either turn that sessionsingleton completly into a class with static methods and data members or use a static class to point to the instance of the session class (and launch it if required) instead of seeking it. This one static data member to return the sessionsingleton instance could probably as well be maintained in the sessionsingleton class itself.

Since the modification to the signature of the GetClass() method would also require some changes in your code, I guess a change to:

IF VALID-OBJECT(SomeObject:GetClass()) AND SomeObject:GetClass():TypeName EG "debtnet.library.sessionsingleton" ....

would not have a bigger impact to your code. Strucutred Error-Handling (an empty CATCH Progress.Lang.Error block) might be an option as well - but that depends on the structure of the remaining code.

Posted by Admin on 25-Jul-2008 06:30

Too mee that looks too much like creating to classes of objects. I like the fact, that .NET and ABL classes are handled (as close to each other) as possible.

Posted by jmls on 25-Jul-2008 06:31

Yeah, I was aware - however there is one of our clients who is still on 10.1B ...

Posted by Admin on 25-Jul-2008 06:31

possible the most robust change to your code, would be the use of the TYPE-OF function, instead of Querying the TypeName:

IF TYPE-OF (SomeObject, myapp.library.sessionsingleton) THEN ...

Please note, that there are no quotes to the Typename in the TYPE-OF function.

Posted by jmls on 25-Jul-2008 06:32

I like it as well - trouble is that it breaks an existing codebase, which is never a good thing.

Posted by Admin on 25-Jul-2008 06:34

I'm pretty sure, TYPE-OF was available in 10.1B as well

Posted by jmls on 25-Jul-2008 06:36

no, my reply "I like it as well" was referring to the comment you made about .net and progress classes being treated the same

Posted by jankeir on 25-Jul-2008 06:38

Strictly speaking I think the existing codebase is not broken when moved to 10.2. The existing code doesn't use .NET objects so it will still run under 10.2.

Only when you start making changes to your application and add .NET objects to it the application will break. But if you can add .NET objects you can probably also make the required change to that code (except when you've only got xcode for that part of your application).

Posted by jmls on 25-Jul-2008 06:40

I beg to disagree - I cannot run my application from the OEA because of the visual designer .net class. So, even without using .net classes I have a problem.

Posted by Admin on 25-Jul-2008 06:41

I understand.

But if you like to stay with the same codebase for 10.1B and 10.2A development a change in the signature ot the GetClass method of the SESSION:FIRST-OBJECT property will work without changes to the code anyway. And those (new) parameters will not be available in 10.1B anyway.

So you really need to modify your code anyway for maintaining the backwards compatility. Either use error handling, the valid-object check of the TYPE-OF validation. All that (except structured error handling and statics) would work with 10.1B as well.

Posted by jankeir on 25-Jul-2008 06:45

Is the class there when you've not started the designer yet? Although I do agree that it's undesirable and may very well be a significant problem for companies who have a large part of their application only as xcode and an uncoperative (or even no-longer existing) software vendor who wrote the code in the first place.

Posted by jmls on 25-Jul-2008 06:47

No I wouldn't have to change my code, because by default the GetClass() would return only progress objects, so the code would work under 10.1B and 10.2A

However, with the help from everyone here, I've modified the code to use TYPE-OF and committed the change to the 10.1B codebase problem no longer exists.

I really just wanted to highlight the fact that there was a problem with existing code not working as it did before.

Posted by Admin on 25-Jul-2008 07:00

I really just wanted to highlight the fact that there

was a problem with existing code not working as it

did before.

Without being too picky here. The code still works as it did before.

In 10.1B this was coded in the assumption, that any object belongs to a class and that this class can be queried using the GetClass() method of that object.

Now we have .NET objects in addition. They have a different way to return the type they belong to. That's why your code breaks. Not because a change in the behaviour of the ABL objects.

Posted by jmls on 25-Jul-2008 07:05

Heh. you and I obviously have a different opinion on "works as before"

if the same line of code works in 10.1B, but doesn't in 10.2A then I would claim that it "doesn't work as before"

If with 10.2A PSC changed the def var statement, so that

DEF VAR a AS CHAR.

doesn't compile anymore, as you need to say

DEF VAR a AS PROGRESS-CHAR.

instead.

would you still say that the code works as it did before, because they have a different way of defining a variable ?

Posted by Admin on 25-Jul-2008 07:15

He He. I like Friday afternoon threads

I would totally agree that this (CHAR to PROGRESS-CHAR) would be broken by 10.2A.

But using a chained reference without ensuring the validity of your code is not the fault of a new language feature - for my personal understanding.

How about this: SESSION:FIRST-PROCEDURE normally always returns a procedure handle, since progress clients need a startup procedure. What if that will ever be changed, so that a progress client can use a class (default constructor I guess) as it's startup procedure and you can code complely without the legacy of procedures.

I would not consider that broken by that (desirable) nice feature at all. It would be fault of all the times I did not check the validity of my chained object references (or used appropriate error handling).

In your case here, the only .NET object in memory was the visual designer. How about using a launch configuration in a separate progress runtime (a very cool feature in 10.2a). Then at least the visual designer should not interfer with your code.

Mike (from finally sunny Cologne)

Posted by jmls on 25-Jul-2008 07:24

Me too! Time for a beer thread ...

Under 10.1B, the ClassType() always returned a valid handle - it was, and is, documented that all progress objects have a class type. I would have been unaware that a couple of years later Psc would change the documented behavior (for very good reasons) by adding a different type of object into the chain and make my code not work.

I have been using that cool feature, but as mentioned earlier, I've fixed my code Took much less time to change the code than to discuss it in this thread !

Thanks for the help and points of view.

Posted by jankeir on 25-Jul-2008 07:30

If Progress decided to make the default locking behavior NO-LOCK instead of SHARE-LOCK I would consider it a very desirable feature, however I don't think that will ever happen because it would break too many applications.

If exactly the same code runs under 10.1A and doesn't run under 10.2 compatibility is broken.

The question however when considering a significant change to avoid this break is:

- Can it be considered the same code when actually there's suddenly more code running.

- is the break significant enough to allow major changes, will it every cause real problems for a company or is it more a theoretic problem?

Progress can decide upon the answers

The example you gave about the SESSION:FIRST-PROCEDURE won't break existing applications, because every existing application has a startup procedure. It may not work in future applications which don't have a FIRST-PROCEDURE, but the existing applications will still run unchanged in the new progress version that supports a procedureless application.

Personally I think no change to the syntax is really desirable here (given the limited impact.) Mentioning the issue in the release notes or some other documentation would be enough.

Posted by jmls on 17-Oct-2008 04:13

Me too! Time for a beer thread ...

Under 10.1B, the ClassType() always returned a

valid handle - it was, and is, documented that all

progress objects have a class type. I would have been

unaware that a couple of years later Psc would change

the documented behavior (for very good reasons) by

adding a different type of object into the chain and

make my code not work.

I have been using that cool feature, but as mentioned

earlier, I've fixed my code Took much less time to

change the code than to discuss it in this thread !

Thanks for the help and points of view.

Man, just got bitten by this again. I've fixed it again (long story, I delete the branch of code I was using for 10.2A and recreated it from trunk) . But I still see no reason why I should have to modify existing code in order for it to work in 10.2A.

Posted by Shelley Chase on 21-Oct-2008 14:16

Hi Julian,

If you are not using .NET at all in your application, the object chain is expected to work as in previous releases, there should not be any .NET classes in your session. One of the ways to test this would be to make sure you use a run configuration with -noclr and launch your non-.NET application using that run configuration. In theory you should not need -noclr, its mainly to speed up compilation time.

If OEA thinks you are using the .NET it may have loaded .NET classes into the project's OpenEdge development session (used for compiling, etc). With OOABL it is a good idea to always run your application in a fresh session and not use this development session.

-Shelley

Posted by Matt Baker on 21-Oct-2008 14:56

Shelley has a good point here. If you are using the AVM associated with a project to run your code, you need to be aware that you are operating in a polluted environment. OEA may at any time decide to run something on the project AVM or perform a compile and you may not be aware of it. Testing your code in this environment could lead to unexpected results.

The proper way to test/run is to use a separate AVM. Run configurations can help with this. If you are absolutely sure you are not using any .NET stuff in your project then you can you the -noclr option to disable the .NET functionality completely. This will prevent the VD from running and the compiler from looking for and loading .net types.

Posted by jmls on 21-Oct-2008 16:19

I understand completely that there are .net objects in the OEA environment - and I understand why I got the error.

What am trying to say is that if I happened to instantiate a .net object in my application session, then my existing code is broken.

It is a trivial fix, it is a trivial use case. However, it is still the case that existing code does not work as it did in 10.1.

There may (must) be lots of other developers who use SESSION:FIRST-OBJECT etc to loop through the object chain who may fall into the same trap and report it as a bug / be dissatisfied.

On the other hand, maybe they simply wrote better code than I did

Thanks for the advice though.

Posted by jankeir on 22-Oct-2008 02:52

However, it is still the case that existing code does

not work as it did in 10.1.

No, the existing code did not have .NET objects, if you add .NET objects you're no longer using the same code, you're using more code. The unchanged application will still run exactly as it did before.

Posted by jmls on 22-Oct-2008 04:01

No, the existing code did not have .NET objects, if

you add .NET objects you're no longer using the same

code, you're using more code. The unchanged

application will still run exactly as it did before.

The existing code still does not have .net objects - let's say I add a new program that creates a .net object, and then the existing application is run. The error will happen, even though the code (of the program that encounters the error) has not changed at all. IOW the unchanged program will encounter the error because a new program has created a .net object.

Posted by jankeir on 22-Oct-2008 04:18

No, the existing code did not have .NET objects,

if

you add .NET objects you're no longer using the

same

code, you're using more code. The unchanged

application will still run exactly as it did

before.

The existing code still does not have .net objects -

let's say I add a new program that creates a .net

object, and then the existing application is run. The

error will happen, even though the code (of the

program that encounters the error) has not changed at

all. IOW the unchanged program will encounter the

error because a new program has created a .net

object.

Yes but if I have an application that references a field without mentioning the table and tomorrow I add a field with the same name to another table the application will also fail. Why? Because the application changed.

Or even better. Imagine you wrote the application exactly as it is now in 10.2, for example because you are not using .NET objects, you will not notice anything. If you suddenly decide to start using .NET objects your application will fail. It's not because of 10.2, it's because of a change in your application. (for me 1 session = 1 application)

Posted by jmls on 22-Oct-2008 04:27

Yes but if I have an application that references a

field without mentioning the table and tomorrow I add

a field with the same name to another table the

application will also fail. Why? Because the

application changed.

only because you are not following good practice. (table.field)

Let's put it another way: In 10.1 I can run my application from the OEA. In 10.2 I can't. I have made no code changes to the application at all.

Posted by Admin on 22-Oct-2008 14:18

Given the fact, the we should only be weeks from the release of 10.2A, what can PSC do, to make Julian happy again? I guess a change in the product behaviour is unrealistic, so how about a big fat release note entry?

Including the suggestion to use TYPE-OF instead of oRef:GetClass():TypeName .

Posted by Thomas Mercer-Hursh on 22-Oct-2008 14:35

I'm not sure that I have followed all of this exactly, so can I ask for a clarification, Julian?

In earlier versions, it was common to RUN code in OEA using the same AVM which one was using to parse, syntax check, etc. While keeping down the number of AVMs running, this has some obvious issues, e.g., things which didn't get cleaned up from earlier activities because the session didn't terminate in the way it would had we been doing the RUN in a separate AVM.

So, now we have shifted best practice in OEA such that we are starting a separate AVM for a RUN. No? While this can mean that one ends up with extra hung AVMs needing to be cleaned up, it means that one can have several configurations available for testing at any time. Yes?

Are you saying that, if you follow current best practice and run code which has no .NET references, that you are having the problem? Or is it that you run code which now has .NET references in the session and you are having a problem with code which used to work no longer working because there are .NET entities in the class tree?

If the latter, which is my best guess at the moment, would I be correct that this will be a problem in production, not just in development? That would seem to be true if it were the presence of a .NET class anywhere in the session. Or, are you saying that it only happens in the context of OEA?

Posted by Admin on 22-Oct-2008 14:40

If I understood his converns:

IF SomeObject:getClass():TypeName EQ "myapp.library.sessionsingleton" THEN

this issues appears at runtime. As soon as a .NET class is loaded, the SomeObject:getClass():TypeName can fail (when walking the SESSION:FIRST-OBJECT chain) because getClass() does not return a class reference when run for .NET objects.

Posted by Thomas Mercer-Hursh on 22-Oct-2008 15:40

OK, so the problem is both development and production and as long as one is going to have the potential for .NET objects in the session ... which is rather the point, then the options are to check for a valid object first or use TYPE-OF. Right?

I would think that it should be a fairly straightforward refactoring to change

SomeObject:getClass():TypeName EQ "myapp.library.sessionsingleton"

into

TYPE-OF(SomeObject, myapp.library.sessionsingleton)

Mind you, I can see why Julian is grumbling, but the reasons seem valid, the workaround doesn't seem too difficult, and the new construct is not objectionable in form.

Posted by jmls on 22-Oct-2008 16:26

I'm not sure that I have followed all of this

exactly, so can I ask for a clarification, Julian?

Sure thing.

In earlier versions, it was common to RUN code in OEA

using the same AVM which one was using to parse,

syntax check, etc. While keeping down the number of

AVMs running, this has some obvious issues, e.g.,

things which didn't get cleaned up from earlier

activities because the session didn't terminate in

the way it would had we been doing the RUN in a

separate AVM.

True. However, I am still trying to wean myself off pressing the procedure editor button, and typing "run startup.p"

So, now we have shifted best practice in OEA such

that we are starting a separate AVM for a RUN. No?

While this can mean that one ends up with extra hung

AVMs needing to be cleaned up, it means that one can

have several configurations available for testing at

any time. Yes?

Yes. And a very very nice feature it is too. Thanks !

Are you saying that, if you follow current best

practice and run code which has no .NET references,

that you are having the problem?

If there is no .net, everything works just peachy.

>Or is it that you

run code which now has .NET references in the session

and you are having a problem with code which used to

work no longer working because there are .NET

entities in the class tree?

Yes.

If the latter, which is my best guess at the moment,

would I be correct that this will be a problem in

production, not just in development?

Yes.

>That would seem

to be true if it were the presence of a .NET class

anywhere in the session. Or, are you saying that it

only happens in the context of OEA?

No - it's if there is any .net object present in the session, regardless of OEA

Posted by jmls on 22-Oct-2008 16:27

If I understood his converns:

IF SomeObject:getClass():TypeName EQ

"myapp.library.sessionsingleton" THEN

this issues appears at runtime. As soon as a .NET

class is loaded, the SomeObject:getClass():TypeName

can fail (when walking the SESSION:FIRST-OBJECT

chain) because getClass() does not return a class

reference when run for .NET objects.

Yes - that's the problem.

Posted by jmls on 22-Oct-2008 16:28

OK, so the problem is both development and

production and as long as one is going to have the

potential for .NET objects in the session ... which

is rather the point, then the options are to check

for a valid object first or use TYPE-OF. Right?

Right.

I would think that it should be a fairly

straightforward refactoring to change

SomeObject:getClass():TypeName EQ

"myapp.library.sessionsingleton"

into

TYPE-OF(SomeObject, myapp.library.sessionsingleton)

It was See my earlier posts. I was just grumbling that I had to change my code to move my app into 10.2A. I'm just a bitter old man that wants to run his v3 code unchanged ...

Mind you, I can see why Julian is grumbling, but the

reasons seem valid, the workaround doesn't seem too

difficult, and the new construct is not objectionable

in form.

All absolutely true.

Posted by Thomas Mercer-Hursh on 22-Oct-2008 16:40

I was just grumbling that I had to change my code to move my app into 10.2A.

Well, if you didn't want to use the new features, you could! No different than those times in the past when one discovered that one had made the mistake of using a field name which turned into a reserved word in a later release. One could always use the keyword forget list to keep going, but then one couldn't use the new feature.

I'm just a bitter old man that wants to run his v3 code unchanged ...

I suspect there's no contest around here who is more of an old man ... but, the really amazing thing about ABL is the extent to which that V3 code still does run. In fact, it is only last week or so that I was educating someone on ProgressTalk about why solving a problem with an editing clause wasn't really the best idea ... he was just copying what he saw everywhere else in his application and was tickled pink to know the answer to someone else's question. When I think what has happened to this language between 1984 when I first discovered it and now, it is staggering and yet how rarely I have had to make a change because of a version shift and when I did it was quite minor.

More likely you are closer to being spoiled than bitter!

Posted by jmls on 22-Oct-2008 16:45

Well, if you didn't want to use the new features, you

could!

Yeah, that point was already conceded.

I suspect there's no contest around here who is more

of an old man ... but, the really amazing thing about

ABL is the extent to which that V3 code still does

run.

It's pretty damned amazing. However, I hate to think of the amount of "spaghetti code" that must be lying around supporting all the old v3+ stuff and the poor sod that has to maintain it. It's hard enough for me to maintain my own code from 5 years ago. not some other programmer's from 20 years ago !

More likely you are closer to being spoiled than

bitter

Definitely spoiled.

Posted by Thomas Mercer-Hursh on 22-Oct-2008 16:53

I hate to think of the amount of "spaghetti code" that must be lying around supporting all the old v3+ stuff and the poor sod that has to maintain it.

Well, as evidenced by that fellow on ProgressTalk, in many cases they don't know any better. They get the job, quite possibly learn the language on the job, look at their own application for examples, and just keep trundling along. Depending on how much they read, they might realize that they are in something of a backwater, but I suspect many of them don't feel the pain the way we would because they really don't know any better. Moreover, even if they do have some perception of being in a backwater, they probably think of it in terms of other languages, not realizing that they are in a terrible backwater with respect to ABL itself.

Of course, the flip side is that it makes a lot of transformation candidates to be my prospect base!

Posted by jmls on 22-Oct-2008 16:55

Well, as evidenced by that fellow on ProgressTalk, in

many cases they don't know any better. They get the

job, quite possibly learn the language on the job,

look at their own application for examples, and just

keep trundling along.

Sorry, I meant the "c" code for the ABL itself .

Posted by Thomas Mercer-Hursh on 22-Oct-2008 17:13

I suspect that the underlying code has had considerably more architectural revision than many of the ABL systems and that it isn't nearly as horrible. This is not to say that there aren't some dinosaurs wandering around in there.

Of course, some of reasons for some of those dinosaurs is exactly the upward compatibility we have enjoyed on the outside. Think how often someone has thought that there were all these places which were doing something similar which could be brought together into common code, but they were quite orthogonal so it was hard to combine and maintain that compatibility. Painful.

This thread is closed