On Wed, Sep 13, 2023 at 8:21 AM Christopher Schultz
<ch...@christopherschultz.net> wrote:
>
> Aryeh,
>
> On 9/12/23 17:50, Aryeh Friedman wrote:
> > On Tue, Sep 12, 2023 at 1:51 PM Christopher Schultz
> > <ch...@christopherschultz.net> wrote:
> >>
> >> Aryeh,
> >>
> >> On 9/12/23 12:42, Aryeh Friedman wrote:
> >>> On Tue, Sep 12, 2023 at 11:42 AM Christopher Schultz
> >>> <ch...@christopherschultz.net> wrote:
> >>>>
> >>>> Aryeh,
> >>>>
> >>>> On 9/11/23 10:05, Aryeh Friedman wrote:
> >>>>> On Mon, Sep 11, 2023 at 9:47 AM Christopher Schultz
> >>>>> <ch...@christopherschultz.net> wrote:
> >>>>>>
> >>>>>> Aryeh,
> >>>>>>
> >>>>>> On 9/9/23 19:36, Aryeh Friedman wrote:
> >>>>>>> On Sat, Sep 9, 2023 at 1:23 PM Mark Thomas <ma...@apache.org> wrote:
> >>>>>>>>
> >>>>>>>> On 09/09/2023 11:52, Aryeh Friedman wrote:
> >>>>>>>>> Every other jsp in my webapp (and other webapps on the same tomcat
> >>>>>>>>> instance [9.0.75]) works and I am using a the default container but 
> >>>>>>>>> as
> >>>>>>>>> curl/catalina.out show BasePage is *NEVER* being called (either the
> >>>>>>>>> _jspService() or the getX()):
> >>>>>>>>
> >>>>>>>> How have you configured your JSP(s) to use this alternative base 
> >>>>>>>> class?
> >>>>>>>
> >>>>>>> sudo cat 
> >>>>>>> /usr/local/apache-tomcat-9.0/webapps/tlaitc-dashboard-1a1/index.jsp
> >>>>>>> <!-- Copyright (C) 2023 TLAITC and contributors -->
> >>>>>>> <%@page extends="dashboard.web.pages.BasePage"%>
> >>>>>>> hi x is ${x}
> >>>>>>>
> >>>>>>> Output shown in log (sorry for not including the JSP the first time)
> >>>>>>> but to make it easier to find the output is "hi x is " when it should
> >>>>>>> be "hi x is 123234"... as you notice there are zero errors/warning in
> >>>>>>> catalina but there is none of the println's also... so the only thing
> >>>>>>> I can surmise is BasePage is never being called <%@page
> >>>>>>> extends="dashboard.web.pages.BasePage"%> somehow failed but I have
> >>>>>>> verified that correct spelling several times and also verified any
> >>>>>>> syntextual errors [including the contents of the string literal] will
> >>>>>>> show up in catalina.out (i.e. wrong class name is logged as an error)
> >>>>>>
> >>>>>> Your _jspService method in your base class will never be called, 
> >>>>>> because
> >>>>>> it is overridden by the auto-generated class for your JSP, which does
> >>>>>> not call super._jspService.
> >>>>>>
> >>>>>> I do not believe that this:
> >>>>>>
> >>>>>> Hi X is ${x}
> >>>>>>
> >>>>>> ...will result in this.getX() being called from the JSP. References in
> >>>>>> EL ${...} expressions will be resolved against the PageContext (and
> >>>>>> other wider contexts), not against the JSP class currently executing.
> >>>>>>
> >>>>>> If you want to call this.getX() then you will need to do this:
> >>>>>>
> >>>>>> Hi X is <% getX() %>
> >>>>>>
> >>>>>> I wouldn't bother messing-around with class hierarchies in JSP. It
> >>>>>> usually doesn't get you much but almost always requires you to bind
> >>>>>> yourself very closely with the specific implementation of the JSP 
> >>>>>> engine.
> >>>>>>
> >>>>>> It would be far better to use typical MVC-style development where a
> >>>>>> servlet (or similar) handles the real work of the request, possibly
> >>>>>> including writing a value of "x" to the request attributes. Then 
> >>>>>> forward
> >>>>>> your request to your JSP to produce the response content. This will be
> >>>>>> much more straightforward and you will have fewer problems like this,
> >>>>>> where expected behavior is confused by all the magic that JSP provides.
> >>>>>
> >>>>> Thanks but I have a very specific use case which the following working
> >>>>> example below should make more clear:
> >>>>>
> >>>>> <!-- Copyright (C) 2023 TLAITC and contributors -->
> >>>>> <%@page import="dashboard.web.page.Page"%>
> >>>>> <%
> >>>>>            // THIS WOULD NOT BE NEEDED if <%@page extends="..."%> worked
> >>>>>            //
> >>>>>            // for now we don't need to keep the page object just
> >>>>>            // the setAttributes in our ctx
> >>>>>            new Page(pageContext);
> >>>>> %>
> >>>>>
> >>>>> <html>
> >>>>> <head>
> >>>>>            <%@include file="/widgets/scripts/scripts.jsp"%>
> >>>>> </head>
> >>>>> <body>
> >>>>>             <jsp:include page="${pagePath}"/>
> >>>>> </body>
> >>>>> </html>
> >>>>>
> >>>>> and the Page class:
> >>>>>
> >>>>> package dashboard.web.page;
> >>>>>
> >>>>> import javax.servlet.http.HttpServletRequest;
> >>>>> import javax.servlet.jsp.PageContext;
> >>>>>
> >>>>> import org.petitecloud.util.PetiteCloudNullException;
> >>>>>
> >>>>> // making this extend the right subclass plus working page
> >>>>> extends="...." would mean zero in-line Java
> >>>>> // Copyright (C) 2023 TLAITC and contributors
> >>>>> public class Page
> >>>>> {
> >>>>>        public Page(PageContext ctx)
> >>>>>        {
> >>>>>            _dbc_construction(ctx);
> >>>>>
> >>>>>            this.ctx=ctx;
> >>>>>
> >>>>>            HttpServletRequest req=(HttpServletRequest) ctx.getRequest();
> >>>>>            String[] parts=req.getRequestURI().split("/");
> >>>>>            int split=2;
> >>>>>
> >>>>>            if(parts[0].equals("http:"))
> >>>>>                split+=2;
> >>>>>
> >>>>>            name="";
> >>>>>            for(int i=split;i<parts.length;i++)
> >>>>>                name+="/"+parts[i];
> >>>>>
> >>>>>            if(name.length()==0)
> >>>>>                name="/index.jsp";
> >>>>>
> >>>>>            // we can safely asssume all valid requests will end with
> >>>>>            // .jsp at this point
> >>>>>            name=name.substring(1,name.length()-".jsp".length());
> >>>>>            path="/content/"+name+"/main.jsp";
> >>>>>
> >>>>>            ctx.setAttribute("pagePath",path);
> >>>>>        }
> >>>>>
> >>>>>        // only used in testing
> >>>>>        public Page(String name)
> >>>>>        {
> >>>>>            this.name=name;
> >>>>>        }
> >>>>>
> >>>>>        public String getName()
> >>>>>        {
> >>>>>            return name;
> >>>>>        }
> >>>>>
> >>>>>        public String getPath()
> >>>>>        {
> >>>>>            return path;
> >>>>>        }
> >>>>>
> >>>>>        public PageContext getPageContext()
> >>>>>        {
> >>>>>            return ctx;
> >>>>>        }
> >>>>>
> >>>>>        @Override
> >>>>>        public String toString()
> >>>>>        {
> >>>>>            return name;
> >>>>>        }
> >>>>>
> >>>>>        @Override
> >>>>>        public int hashCode()
> >>>>>        {
> >>>>>            return name.hashCode();
> >>>>>        }
> >>>>>
> >>>>>        @Override
> >>>>>        public boolean equals(Object o)
> >>>>>        {
> >>>>>            if(o==null||!o.getClass().equals(getClass()))
> >>>>>                return false;
> >>>>>
> >>>>>            Page other=(Page) o;
> >>>>>
> >>>>>            return name.equals(other.name);
> >>>>>        }
> >>>>>
> >>>>>        private String name;
> >>>>>        private String path;
> >>>>>        private PageContext ctx;
> >>>>>
> >>>>>        // ----- # DBC # -------------------------------------------
> >>>>>
> >>>>>        private void _dbc_construction(PageContext ctx)
> >>>>>        {
> >>>>>            if(ctx==null)
> >>>>>                throw new PetiteCloudNullException("ctx is null");
> >>>>>        }
> >>>>> }
> >>>>>
> >>>>> So all I am attempting to do is write it like this (get rid of the
> >>>>> last remaining in-line java but not be forced to use tag instead of
> >>>>> ${} either):
> >>>>>
> >>>>> <!-- Copyright (C) 2023 TLAITC and contributors -->
> >>>>> <%@page extends="dashboard.web.page.Page"%>
> >>>>>
> >>>>> <html>
> >>>>> <head>
> >>>>>            <%@include file="/widgets/scripts/scripts.jsp"%>
> >>>>> </head>
> >>>>> <body>
> >>>>>             <jsp:include page="${pagePath}"/>
> >>>>> </body>
> >>>>> </html>
> >>>>>
> >>>>> Side note I am currently adding user detection to the above page class
> >>>>> to that it can auto-enforce ACL's
> >>>>
> >>>> I'm not sure I understand the point of the whole exercise. Nothing you
> >>>> have in the PageContext class constructor cannot be done from within the
> >>>> JSP itself, or -- better yet -- in an <%include> used by as many pages
> >>>> as you want. *OR* ... you could do it in a Filter and apply it to all
> >>>> requests, storing the information in the request attributes, which is
> >>>> much more standard than directly modifying the page context.
> >>>
> >>> The idea is to avoid any custom entries in web.xml (which filters
> >>> require)
> >>
> >> This is not entirely true, and seems to be an arbitrary requirement. The
> >> application is configured via web.xml. Why disallow any configuration in
> >> web.xml?
> >
> > Because of the need to run it on a potentially stripped down
> > (embedded) non servlet based (but Java) based HTTP service/servlet
> > (whether you want to admit it or not HTTP is used for a lot more then
> > just HTML and web browsers).  Many such servers are hard wired to
> > their application and thus the code would not be reusable with any
> > page framework they might use (the one I have in mind does use
> > sessions but they are made controlled by the caller).
>
> Hmm. Okay.
>
> >>> and the entire point is this is a top level template and
> >>> future versions will provide a number of standard setAttriburtes that
> >>> expose different things like the logged in user.
> >>
> >> Yeah, you are welcome to your own opinion, but everything you describe
> >> sounds like "we want to use JSPs for everything and not write Java code"
> >> and honestly what you need is plain-old Java code for this stuff.
> >
> > No, you read it completetly wrong we want 100% test coverage on any
> > code that can create dynamic results (java or JSP) and frankly without
> > making a fake set of servlet primitives (which we have done for just
> > this kind of testing) it is almost impossible to unit test stuff that
> > deals directly with the servlet/jsp-api's and thus we need to push as
> > much as absolutely possible out of un-testable compilation units/files
> > (aka no Java in JSP).... and the form of JSP that still keeps the
> > dynamics we want (i.e. it is visually  obvious what is dynamic content
> > and what is static content from just reading it) is the ${...} form.
> > (Note this is also compatible with a batch processed mail-merge like
> > text macro expander we made for other purposes so 2 birds with the
> > same stone).
> >
> > Just so you know the application is soft-life critical (remote cardiac
> > monitoring w/ webapp frontend) and is 100% Java and currently does the
> > standard intermix of in-line Java vs. non-in-line Java in JSP's but as
> > I said above due to the critically of the app  we have decided to make
> > blank rule that all lines of Java must be unit tested if at all
> > possible (i.e. not insanely hard to trigger all paths).
>
> So you have a requirement to test all Java code but not all JSP code?
> JSP is just elaborate syntactic sugar for Java.

Not when it comes to testability in that most "content" JSP's (I don't
use a apache httpd frontend/connector) the output needs to be
relatively short and stable to be tested against (for example if this
letter was such a page it would fail any such test on each reply).
Thus it is best to treat JSP as a black box (not tested) but test
every last dynamic (non-HTML/static file) content by checking if it 1.
Provides the right results when called and 2. has set the needed
attributes so ${...} is available for it (this gives a lot more
control over encapsulation then in-line java)

>
> >>> In general I try to avoid relying on any given low level framework
> >>> then is needed and doing this ties us more to servlet-api then makes
> >>> sense (i.e. it is not very portable to non-monolithic servers like
> >>> tomcat but it is portable if you avoid stuff like web.xml as
> >>> possible).
> >> I would argue the /absolute opposite/: using web.xml for its intended
> >> purpose is exactly the correct way to avoid tying yourself to a specific
> >> server. If you are trying to avoid bindings to the Servlet API but in
> >> exchange you are binding to Tomcat, I see that as a net-negative: the
> >> Servlet API is a better choice than Tomcat if you have to pick one to
> >> bind to.
> >>
> >> There are frameworks which you can use that do not require you do bind
> >> your application to either Tomcat OR the servlet-api (I'm thinking of
> >> Apache Struts 2, for example), but you do have to give up some small
> >> bits of capabilities because really advanced stuff requires binding to
> >> those APIs.
> >
> > Again you missed the point the idea is to make it so it can run on a
> > servlet based engine or non-servlet based one and the non-servlet
> > based one would need the configurations that are kept in web.xml (and
> > not have the built-in capacity to read it).  Think reuse.
> > Additionally any non-platform (servlet vs. non-servlet) code would be
> > in the servlets or other things.... I.e. regardless of the html/json
> > rendering engine used.
>
> I think you lost me again. Non-servlet code goes in the servlets?

there is no harm in extending the servlet class in testing (as long
you mock it) and due to the need for some one to receive forms/POSTS
servlets are needed on tomcat but should be as empty of shells as
possible (they are still needed for binding though)

>
> >> Writing JSPs is already very very VERY tightly binding your application
> >> to the Servlet API. I don't understand this requirement at a very
> >> fundamental level.
> >
> > See above it is not tightly binding if you ${...} because many text
> > macro packages use that as a delim (it is almost the defacto
> > standard).   Thus as long you present the same map of keys/values to
> > the ${...} it is 100% portable across many ecosystems where is
> > <%....%> is not for one reason it messes with PHP (which I don't use).
>
> Oh.
>
> You want to use JSP syntax with either a true JSP engine OR some other
> technology which can produce the same kind of output? That seems fragile.

When used correctly no where near as fragile as using tomcat for all
renderings.   A perfect example is our system sends a lot of (dynamic)
HTML email and really the only real differences can be handled by the
${....} format but as long in-line java is introduced your forced to
do some fancy foot work on the backend specificall:

servlet that triggers the email-->additional backend logic-->make
key/value map for the correct fill in the blanks in the emailed HTML
(sometimes not trivial)-->open a UDPConnection to tomcat and send the
correct request and query string-->JSP does it's magic-->copy the
results to email.... the correct procedure would remove the last 2
very time consuming steps.... instead we just call our text macro
package and it does everything in-place on files not this weird
indirect call tomcat thing.

>
> Why not just use something which has nothing to do with JSP at all?
> Obvious candidates are Apache Velocity and FreeMarker. You can use both
> of those without having to hand-wave your way around
> servlet-vs-non-servlet. Notably, they also do not translate ultimately
> into Java source.
>
> >> The answer to the question "how do I write my application in a way that
> >> avoids binding to (e.g) the servlet API" is "use a framework which
> >> insulates you and the application from that API". There are some (again,
> >> thinking of Apache Struts 2, here) that don't even require that you bind
> >> your code to THEIR APIs. You write POJOs and some configuration to glue
> >> it all together. No compile-time dependencies. You can port your
> >> application to Swing/JavaFX if you feel like going down that route, and
> >> only the GUI glue itself needs to be "bound" to
> >> AWT/Swing/JavaFX/whatever. Your core application code doesn't need any
> >> of that.
> >
> > For security reasons (not depending on more 3rd party black boxes then
> > we have to) we use only the bare min libraries currently (servlet-api,
> > jsp-api, json, itext and the standard library, and keeping the list to
> > just those is purposeful.
> >
> >>
> >> The stuff the Servlet Spec provides should be thought of as glue that
> >> allows your core application (without Servlet API bindings) to be
> >> accessible through a web-based interface. But you appear to be trying to
> >> implement your core application in JSP which is counter-intuitive to me
> >> and seems to be the opposite of your goal to be API-independent.
> >
> > Not counter unititive at all for reasons cited above (near defacto
> > standard text macro format).
> >
> >>
> >>> Case in point for performance reasons I wrote a server called
> >>> babyHttp that is an extremely stripped down API endpoint oriented
> >>> server that does not use web.xml or anything of the kind (purposely
> >>> make it so the only linkage between modules is actual Java source
> >>> code).   Keep in mind HIPAA is a requirement here.
> >> I do not know why your "case in point" is relevant. Sure, you were able
> >> to create a toy HTTP server but anybody who has read an introductory
> >> Java programming book can probably copy such a thing out of the examples
> >> from that same book. HIPAA is a red herring, other than you'd better be
> >> careful about implementing your own HTTP endpoint since it's very easy
> >> to do it incorrectly.
> >
> > I am well aware of that having written about 6 or 7 HTTP servers since
> > the mid 90's including the first single threaded server, held the
> > record of most concurrent connections before 2000 at 10k concurrent
> > requests (that through a few forks turned into thttp).  The only
> > reason for even bringing this up is I have learned over the years not
> > to question why someone has a specific use case (as long it is not
> > completely idiotic) and do my best to help them implement it the way
> > they see fit (aka domain experts know better then generalists)
>
> Sounds like you know everything you need to know, then. I guess I'll
> show myself out.

All I was asking originally is there anything inherently wrong with
<%@page extends="..."%> to do the specific use case I have in mind
(remove all in-line java from JSP) I was not attempting to justify the
use case (nor should I have had to if people had not decided to
reinterpret the reason for my question).   BTW turns out for reasons
mentioned else where in the thread I was barking up the wrong try and
can at least isolate it down to one or two lines of in-line java (and
at that point automated testing is pointless for the most part)
--
Aryeh M. Friedman, Lead Developer, http://www.PetiteCloud.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to