Re: Tapestry-hibernate module seemingly leaking connections

2024-06-11 Thread Ben Weidig
Hi Chris,

the RegistryProxy should work, we use something similar for a script editor
component with access to the Registry.
We don't use WebSockets, though, so the normal lifecycle applies.

With WebSockets, however, someone has to handle it manually.
Beware, I don't have any experience with Tapestry and WebSockets, so it's
more like an educated guess.

If you look at the Registry, it has a cleanupThread() method, which locks
the Registry and calls cleanup() on the delegates to PerThreadManager.

https://github.com/apache/tapestry-5/blob/5655dd7fcb0441971147670254dd54800b93f4c0/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java#L545

The PerThreadManager#cleanup() call is the one triggering
HibernateSessionManager#threadCleanup() to close the Session.

We had a similar issue with anything that needs to run outside a "normal"
HTTP "1 request == 1 Thread" environment, like using Quartz for job
scheduling.

With my limited WebSockets knowledge, I guess that you'd need to call
Registry#cleanupThread() or at least PerthreadManager#cleanup() after each
@OnMessage to ensure that Tapestry resets itself to a sensible state.

Cheers
Ben

On Wed, Jun 12, 2024 at 3:08 AM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hi Ben,
>
> Thank you for those helpful suggestions!  You're right... debugging is
> tricky given the large number of moving parts. 
>
> I've made some progress since last writing.  By activating
> "hibernate.c3p0.debugUnreturnedConnectionStackTraces" within my
> Hibernate configuration I've been able to narrow down exactly which
> calls to HibernateCrudServiceDAO produce these leaked connections.  When
> this DAO service is invoked using dependency injection - as it is in
> most cases - connections do not get leaked.  So, for the most part the
> tapestry-hibernate module is working exactly as it should.
>
> Connections get leaked when the client is a desktop app that connects
> via WebSocket.  With such connections, Tomcat instantiates a concrete
> wrapper class found within the parent web application.  The constructor
> of this class acquires a particular Tapestry IoC service directly from
> the Tapestry registry (below is my RegistryProxy class which facilitates
> this).  Overall this approach has worked well, allowing the parent
> web-app to "push" updates out to external desktop clients via WebSocket.
>   Aside from the small issue of leaked DB connections - back end
> Hibernate sessions seemingly not closed when the front end WebSocket
> session is closed.  Perhaps there is something I can do within the
> onClose() of my wrapper class to resolve this?
>
> If, based on your better knowledge of Tapestry IoC, something springs to
> mind I'd be keen to hear it.
>
>
> public class RegistryProxy {
>
>  private static ServletContext context;
>
>
>  public static  T getService(Class serviceInterface){
>  Registry registry =
> (Registry)context.getAttribute(TapestryFilter.REGISTRY_CONTEXT_NAME);
>  return registry.getService(serviceInterface);
>  }
>
>
>  //Called by TapestryContextListener
>  public static void setServletContext(ServletContext context){
>  RegistryProxy.context = context;
>  }
>
>  //Use this method to access context from any location
>  public static ServletContext getServletContext(){
>  return RegistryProxy.context;
>  }
> }
>
>
> Kind regards,
>
> Chris.
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Tapestry-hibernate module seemingly leaking connections

2024-06-09 Thread Ben Weidig
Hi Chris,

debugging Hibernate connection problems is no fun at all...

You're correct that org.apache.tapestry5.hibernate.HibernateSessionManager
is thread-scoped and is supposed to clean up after itself by rolling back
any uncommitted transaction and closing the session.

Hibernate/Connection issues are difficult to track down, as there are so
many parts involved, and no setup is equal to the next one.
For example, we neither use Tapestry's HibernateSessionManager nor C3PO, so
I can only give some generic recommendations of what I'd do if I had issues
with Hibernate etc.:

- @Advise HibernateSessionManager methods and log each call to get a better
understanding of what is happening when.

- Override HibernateSessionManager with a 1:1 copy and log additional info
to get more context about the calls

- Debug the HibernateSessionManager#threadDidCleanup to see if C3PO gets
called correctly to close the connection.

- Use a profiler like https://www.yourkit.com/


Also, I'd go over every little detail of the connection pool and Hibernate
configuration, especially default values. Did you update Hibernate or the
connection pool lately? Maybe a default changed?

It took us quite some time and experimentation to get it "just right" for
our use case without any surprises for edge cases, and I dread the day we
have to take another look at it...

Cheers
Ben


On Wed, Jun 5, 2024 at 5:48 AM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hi,
>
> My application's DAO class is employing an injected Hibernate Session
> for accessing a MySQL DB.  Connection pooling is provided by C3PO.
>
> My understanding is that the Tapestry Hibernate IoC (per thread) service
> takes care of closing DB connections under the hood, releasing them back
> to the pool, without any explicit requirements inside the DAO.  However,
> in some cases connections are not being released and eventually MySQL
> kills them (after 8 hours or so).  This then results in broken pipe
> errors within the application which C3PO resolves by recreating the
> pool.  Obviously not ideal.
>
> One solution is to have C3PO check connections are live when checking
> them out from the pool, but before heading down this path I thought it
> worth exploring options from a programmatic point of view.  Possibly
> there is a recommended practice that I'm not following in my DAO class.
>
> In the below DB query you can see two likely leaked connections that
> haven't timed out at 300 seconds as configured in C3PO.
>
>
>  MariaDB [mydb]> show full processlist;
>
>
> ++-+-+-+-+--+---+---+--+
>  | Id | User| Host| db  | Command | Time |
> State | Info  | Progress |
>
>
> ++-+-+-+-+--+---+---+--+
>  | 298177 | user| localhost:41638 | mydb| Sleep   | 2286 |
> | NULL  |0.000 |
>  | 298178 | user| localhost:41640 | mydb| Sleep   | 1858 |
> | NULL  |0.000 |
>  | 298179 | root| localhost   | mydb| Query   |0 |
> init  | show full processlist |0.000 |
>  | 298232 | user| localhost:42014 | mydb| Sleep   |7 |
> | NULL  |0.000 |
>  | 298233 | user| localhost:42016 | mydb| Sleep   |7 |
> | NULL  |0.000 |
>  | 298234 | user| localhost:42018 | mydb| Sleep   |7 |
> | NULL  |0.000 |
>  | 298235 | user| localhost:42020 | mydb| Sleep   |7 |
> | NULL  |0.000 |
>  | 298236 | user| localhost:42022 | mydb| Sleep   |7 |
> | NULL  |0.000 |
>  | 298237 | user| localhost:42024 | mydb| Sleep   |7 |
> | NULL  |0.000 |
>  | 298238 | user| localhost:42026 | mydb| Sleep   |7 |
> | NULL  |0.000 |
>  | 298239 | user| localhost:42028 | mydb| Sleep   |7 |
> | NULL  |0.000 |
>
>
> ++-+-+-+-+--+---+---+--+
>  11 rows in set (0.00 sec)
>
>
> Kind regards,
>
> Chris.
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Illegal char <<> at index 18: StreamableResource

2024-05-20 Thread Ben Weidig
Hi Chris,

that's most likely https://issues.apache.org/jira/browse/TAP5-2605 and it
should be fixed next Tapestry release.

In the meantime, you could override the GoogleClosureMinimizer by
copying the code from
org.apache.tapestry5.internal.webresources.GoogleClosureMinimizer to a new
class and look for the line:

SourceFile input = SourceFile.fromInputStream(resource.toString(),
resource.openStream(), StandardCharsets.UTF_8);

Replace resourse.toString() with a valid filename-like String, e.g.,
"streamable-resourece".

The first argument of the SourceFile.fromInputStream call doesn't actually
matter, but it might fail if the filesystem doesn't like angle brackets or
any other character in the String representation of StreamableResource.


Override the existing Minimizer with:

@Contribute(ResourceMinimizer.class)
@Primary
public static void overrideJavaScriptMinimizer(MappedConfiguration conf) {
conf.overrideInstance("text/javascript",
FixedGoogleClosureMinimizer.class);
}


Cheers
Ben

On Mon, May 20, 2024 at 11:55 AM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hi all,
>
> Today I encountered the below exception after upgrading from Tapestry
> 5.8.2 to 5.8.6, and am wondering what changed between these versions
> that might have led to this.  A dependency incompatibility perhaps?
>
> Evidently not liking the angle bracket immediately following
> "StreamableResource".  Running in production mode on Java 1.8, if this
> makes any difference.
>
> "Render queue error in SetupRender[core/ExceptionReport]: Illegal char
> <<> at index 18: StreamableResource JavaScript stack, for locale en,
> resources=classpath:META-INF/assets/tapestry5/require.js,
> classpath:META-INF/assets/tapestry5/underscore-1.13.6.js,
> classpath:META-INF/assets/tapestry5/t53-compatibility.js,
> classpath:META-INF/assets/tapestry5/jquery.js,
> classpath:META-INF/modules/t5/core/init.js,
> classpath:META-INF/assets/tapestry5/jquery-shim.js,
> classpath:META-INF/modules/t5/core/alert.js,
> classpath:META-INF/modules/t5/core/ajax.js,
> classpath:META-INF/modules/t5/core/bootstrap.js,
> classpath:META-INF/modules/t5/core/console.js,
> classpath:org/apache/tapestry5/t5-core-dom-jquery.js,
> classpath:META-INF/modules/t5/core/events.js,
> classpath:META-INF/modules/t5/core/exception-frame.js,
> classpath:META-INF/modules/t5/core/fields.js,
> classpath:META-INF/modules/t5/core/forms.js,
> classpath:META-INF/modules/t5/core/pageinit.js,
> classpath:META-INF/modules/t5/core/messages.js,
> classpath:META-INF/modules/t5/core/utils.js,
> classpath:META-INF/modules/t5/core/validation.js,
> classpath:META-INF/assets/tapestry5/underscore-shim.js COMPRESSABLE
> lastModified: Mon May 20 21:09:15 NZST 2024 size: 506185>"
>
> Kind regards,
>
> Chris.
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: IntelliJ Plugin

2024-04-27 Thread Ben Weidig
Hi Andreas,

what a coincidence, I was thinking about the plugins this week!

I'm not an IntelliJ user, but I see the need for readily available plugins,
for both Eclipse and IntelliJ, that work with the latest Tapestry and IDE
versions.

IMO, the plugins are good candidates for the "Community Projects" I
mentioned in the roadmap earlier this month.

By bringing them closer under the Tapestry umbrella but still separate from
the core project, it's easier to make sure they're compatible
and easier to discover without the pressure of a prime project.

With more available resources, they might see further development, but
that's not the most pressing issue with the plugins.
As long as their core features are available/compatible, I'd be happy.

Even though I'm not using IntelliJ, I might investigate what would be
necessary to get it working again.
Unless someone else already has done some work?

Cheers
Ben

On Thu, Apr 25, 2024 at 3:54 PM Andreas Ernst  wrote:

> Hi,
>
> for the new Version of IntelliJ there is no actuell Plugin anymore, it's
> now obsolete.
>
> I tried to update it to the new IntelliJ Version, but due to some
> deprecated classes, this need a deeper refactoring.
>
> Is there anyone who tried it also or already done this?
>
> Regards
> Andreas
> --
> ae | Andreas Ernst | IT Spektrum
> Postfach 5, 65612 Beselich
> Schupbacher Str. 32, 65614 Beselich, Germany
> Tel: +49-6484-91002 Fax: +49-6484-91003
> a...@ae-online.de | www.ae-online.de
> www.tachyon-online.de
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Attribute Usages Within Grid Implementation

2024-04-23 Thread Ben Weidig
Hi Michael,

we've also stumbled over private/final fields in components in the past.

I don't know the actual reason, but I'm guessing it simply was a design
choice made long ago and never changed.

Going forward, maybe many (or maybe all?) of the core components should be
easier to extend by making properties and methods protected instead of
private.

This would especially be helpful in cases where copying isn't possible
because the component uses more non-public/non-protected types and stuff.

Personally, I'd like to open up even more parts of the core components.
For example, last week, I needed to affect the @BeginRender of
AbstractTextField, but not all steps are available via a protected method.

However, fully opening up the components requires a uniform scheme, similar
to how the rendering phases are well-defined.
This way, extending any component would become straightforward, and custom
components would behave as expected.

Still, making the parameters protected seems sensible and shouldn't
introduce any issues, except for already existing custom replacements that
extend the original.

Cheers
Ben

On Mon, Apr 22, 2024 at 3:19 PM Michael Helbig 
wrote:

> Hi
>
> i am using an extension for the Grid Table from Tapestry Core by some
> own Developed additional Features (eg. Download, Customizable Column
> Selection, etc.). The initial plan was to use an ExtendedGrid Class by
> extending the Superclass Within the Core LIbrary Grid.java.  Due to the
> fact the Parameter Within the Grid.java class, are configured private
> final , there is no chance to use the information. By changed the
> part to for example like this:
>
> Original
>
> @Property
> @Parameter(required = true, autoconnect = true)
> private final GridDataSource source;
>
> Could be:
>
> @Property
> @Parameter(required = true, autoconnect = true)
> protected GridDataSource source;
>
> all "Extensions" Are able to access the information without further
> impacts. Currently the Workaround is to use a "Copy" of Grid.class,
> changing the attributes to protected, with this approach other available
> Components using Core Grid classes could not be mixed.
>
> Is there a Reason for having the Values final ? Could this be improved
> by using protected ?
>
> Would be interested in hear your ideas on that ?
>
> Michael
>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Development Roadmap 2024

2024-04-04 Thread Ben Weidig
Hello Tapestry Community!


We're excited to share a rough roadmap of upcoming developments and the
overall strategy for the project in 2024.


Head over to https://tapestry.apache.org/development-roadmap.html to learn
more, but here's the overview:

   - (IN PROGRESS) Jakarta EE
   - (IN PROGRESS) Website/Documentation updates
   - (PLANNED) Making contributions more accessible
   - (PLANNED) Community Projects
   - (PLANNED) Updating Guides


The roadmap is also found on the project's website as a navigation sub-item
of "Development."


Please keep in mind that the roadmap isn't fixed in stone.

Still, it paints a particular picture of what we plan to do this year and
what is happening now.


This way, it's easier for the community to get involved and shape
Tapestry's future with us together!


Cheers

The Tapestry Team


Re: translations and poedit

2024-03-12 Thread Ben Weidig
Hi Geoff,

we translated a Tapestry app for one of our customers in recent years but
don't have a ready-to-deploy workflow...
But I can share our experiences and how we managed to do it in the end.

Tools like poedit or plugins for IDEs are great tools, but only if both
sides use them.
Still, they often change the order of lines or the formatting just a bit,
which results in many unnecessary changes in Git and makes it harder to
track the actual progress.

The most important question when using a third-party translator is what
kind of files they expect to receive for translation and how you receive
them back.
We looked into different services, and most are quite pricey and not
flexible in their workflow or tooling.
That's understandable, but for smaller translation projects, it's just too
much friction...

Instead of an agency/full-service, we ended up using multiple freelancers
who we could create a custom workflow with.

We wrote two scripts to export all property files of a language into a
single CSV, so they could use Excel for doing the translation *shudder* but
that was most people's easiest tool to use.
Then, they exported it as CSV again (or we converted the XLS ourselves),
and we imported it with another script.


If your translation people can work directly with the property files, you
could copy the resources folder and remove all non-properties with

find -not -name '*.properties' -type f -delete

and then create an ZIP archive, send it to them, they translate it, zip it
up again, you copy it back, check in Git the changes.

However, such manual approaches don't provide much additional info like "is
everything translated" or marking any problems.

To solve the latter, the translators could add comments like "# TODO: ..."
directly into the file.
Many tools detect TODO/FIX/etc., like the "Todo Tree" extensions by
"Gruntfuggly" for Visual Studio Code.


Another useful tool for finding missing translations and text that wasn't
moved to a property file yet is advising the PropertyFilesParser.

The following code adds the language of the property file a text was loaded
from.

@Advise(serviceInterface = PropertiesFileParser.class)
public static void advisePropertiesFileParser(MethodAdviceReceiver receiver,

@Symbol(PROPERTIES_DISPLAY_LOCALE) boolean displayLocale) throws
NoSuchMethodException,

SecurityException {

if (displayLocale == false) {
return;
}

Method method =
PropertiesFileParser.class.getMethod("parsePropertiesFile", Resource.class);

Pattern pattern = Pattern.compile(".+_(.[a-zA-Z]{1,3})\\.properties");

receiver.adviseMethod(method, advice -> {
advice.proceed();
Object returnValue = advice.getReturnValue();
if (returnValue == null || returnValue instanceof Map == false) {
return;
}

@SuppressWarnings("unchecked")
Map values = (Map) returnValue;

Resource resource = (Resource) advice.getParameter(0);
if (resource == null) {
return;
}

String file = resource.getFile();
if (file == null) {
return;
}

Matcher matcher = pattern.matcher(file);
String suffix = matcher.matches() ? " [" + matcher.group(1) + "]" :
" []";
for (var key : values.keySet()) {
values.put(key, values.get(key) + suffix);
}

advice.setReturnValue(values);
});
}


Overall, it's still a hacky and manual workflow, but it works for us quite
well and was way cheaper than going the agency/full-service route.
Any new translations are usually done by sending the new base property
files of an added component or page to the translators.


Cheers
Ben

On Tue, Mar 12, 2024 at 12:05 AM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> Hi all,
>
> I need to provide a new translation for my app and then keep it
> maintained, and I’ll need to use a third-party to do the translation, but I
> don’t want to give them access to the entire project’s source.
>
> Instead, I presume what’s needed is automatic extraction of all the
> .properties files that have the right language extension (and a few
> English .tml files), get them translated, and then automatically write back
> to the right places.
>
> Does anyone have a good workflow for this? Does it involve poedit?
>
> Cheers,
>
> Geoff
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: [ANNOUNCEMENT] Tapestry 5.8.4 release

2024-02-14 Thread Ben Weidig
Hi David,


To expand the answer a little further, no schedule still means "the next
thing to release".


We absolutely understand the community's need for Jakarta EE.

It's just that, given our available resources, we won't/can't commit to a
fixed timeline.

The Java 21 release was done first to get a better starting point and not
prolong the duration for the next release.


After evaluating different approaches to handle the Jakarta EE migration,
we believe a manual approach might be best for our project/maintainer size.

An automated patch and build process sounds quite alluring, and we invested
some time looking into it. But the migration is sadly not a simple
plug-and-play.


Fighting Gradle is already no fun, even without trying to add Jakarta
shenanigans... And requiring more extensive changes of the overall build
process would definitely delay the release.

Also, the more time passes, the more difficult it will be to keep feature
parity without manual intervention, for example, if a dependency is updated
and no longer compatible with the older version.


That's why we decided on a two-branch approach, with Jakarta EE becoming
the new main development branch based and non-Jakarta getting all the
features, security fixes, etc., backported manually for the foreseeable
future. This way, we have more control and can handle problems with
incompatibilities directly instead of replacing an automatic system when it
can no longer do its job.

Manual backporting is, of course, a chore. But we think it's doable for the
foreseeable future and in the community's interest.


As Thiago already said, there's also a roadmap on the horizon, so the
community gets a better understanding of what we're working on and in which
direction the project is going, and to gather feedback earlier and give
everyone a chance to participate and contribute.


tl;dr;

   - Jakarta EE will be released next
   - However, we can't commit to a timeline, given our resources, but it's
   ASAP
   - Two-branch manual approach instead of developing an automatic
   solution. Backporting all the things as long as it's feasible
   - Roadmap coming soon!


Cheers

Ben

On Wed, Feb 14, 2024 at 1:48 PM Thiago H. de Paula Figueiredo <
thiag...@gmail.com> wrote:

> On Tue, Feb 13, 2024 at 6:57 PM David Taylor
>  wrote:
>
> > First, thanks for the 5.8.4 release! The timing was perfect since
> > underscore.js was one of the items flagged in a recent vulnerability
> scan.
>
> Nice!
>
> > Given there is no schedule for official Tapestry Jakarta EE support, we
> > decided to create and host an internal build of Tapestry. I applied the
> > changes provided by Christian Köberl in pull request TAP5-2741 to the
> > 5.8.4 sources and everything is looking good so far. Thank you so much
> > for providing the pull request!
>
> We already expected Köberl's pull request to work, but it's nice to
> see some additional testing being done by the community. :) Thanks you
> for that and thanks Köberl for the PR!
>
> > I would be very interested in everyone's thoughts on how the official
> > Jakarta EE support should work. Perhaps it would be feasible to create
> > an automated patch and build process that can be maintained in parallel
> > to the official Tapestry build? While it may not be as elegant as a
> > fully integrated approach, I believe it would address the immediate need
> > for Jakarta EE artifacts without significantly increasing the
> > maintenance costs. Thoughts?
>
> Volker Lamp already tried that approach, but it reached a few dead
> ends since it's not just a package name change, but some Servlet API
> changes too.
>
> The Tapestry team should announce the project's planned roadmap,
> including the Jakarta EE issue, in the upcoming weeks. Stay tuned! :)
>
> Cheers!
>
> --
> Thiago H. de Paula Figueiredo
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Help request with LCR and IntelliJ

2023-10-30 Thread Ben Weidig
Hi Riccardo,

At my company, we're using Eclipse and registered .tml with the XML editor,
to have at least rudimentary tag-completion and highlighting.
Tapestry's xsd scheme only contains the most essential elements, so there's
no code completion for its components.

The Eclipse Tapestry Plugin has completion proposals, but we're only using
it for context switching, I don't know how good the support is
https://github.com/anjlab/eclipse-tapestry5-plugin#completion-proposals

AFAIK, the IntelliJ Tapestry plugin isn't working with a current Tapestry
version, as the documentation still states "Tapestry 5.1" and it's in the
"intellij-obsolete-plugins" repository
https://github.com/JetBrains/intellij-obsolete-plugins/tree/master/tapestry

Cheers
Ben

On Mon, Oct 30, 2023 at 3:14 PM Riccardo De Menna 
wrote:

> Thank you Thiago,
>
> Yes I was able to somehow make it work. It’s not as fast as in eclipse
> where it’s basically instantaneous, but it works. Now I’m fighting the
> Tapestry plugin that is doing weird things with the syntax claiming prop:
> type entries to be unrecognised but then linking them correctly to the code
> !!!
>
> What’s the preferred way of editing .tml with some visual support? Do you
> guys mostly use eclipse? Something else?
>
> Thank you,
> Riccardo
>
> > On 30 Oct 2023, at 14:37, Thiago H. de Paula Figueiredo <
> thiag...@gmail.com> wrote:
> >
> > On Thu, Oct 26, 2023 at 1:50 PM Riccardo De Menna 
> wrote:
> >
> >> Hi everyone,
> >
> > Hi!
> >
> > Welcome to the Tapestry community!
> >
> > There's a fundamental difference in how Eclipse and IntelliJ idea work
> > regarding how they build Java code which affects the Tapestry live
> > class reloading experience.
> >
> > Every time you save a Java file in Eclipse, it gets automatically and
> > instantaneously compiled by default (i.e. unless you disable the
> > "Build automatically" option).
> > In IntelliJ, as far as I know, Java files are only compiled when
> > requested (in most cases, when you ask it to build the project). The
> > shortcut for build is Control-F9, so I guess we have a typo in the
> > documentation.
> >
> > Please let me know if you have further questions.
> >
> > Cheers!
> >
> > --
> > Thiago
> >
> > -
> > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> > For additional commands, e-mail: users-h...@tapestry.apache.org
> >
> >
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: https://issues.apache.org/jira/browse/TAP5-2630

2023-09-03 Thread Ben Weidig
Hi Jens,

I finally found some free time to take a look, but I can't reproduce your
issue with the current HEAD.

PAGE:

public class StaticFieldAsPropertyDemo {
public static int[] INT_ARRAY = {1, 3, 5, 7, 9};
public static final String CONSTANT = "this is a constant";
}


TML:

http://tapestry.apache.org/schema/tapestry_5_0_0.xsd;
  t:type="Border">

Static Field As Property Demo



${prop:CONSTANT}




I put this into the tapestry-core integration tests, added a unit test, and
it succeeds without a problem (Java 11/17).

Do you have any more info, or could you share a simplified sample project
that I can run on my machine?

Cheers
Ben

On Tue, Aug 1, 2023 at 4:46 PM Ben Weidig  wrote:

> That's weird...
>
> Here's an example from my code with some custom types:
>
> public static final List WEEK_DAY_SOURCE = List.of(...);
>
> In the TML:
>
>  t:source="prop:WEEK_DAY_SOURCE"
> t:value="prop:weekDay">
> ...
> 
>
> Works fine for me, but I'm running 5.8.2 with OpenJDK 17, not 11.
>
>
>
> On Tue, Aug 1, 2023 at 4:29 PM Jens Breitenstein  j-b-s...@toc-mailserver.de> wrote:
>
>> Sorry, Ben, tried it, but this is not working.
>>
>>
>>  private final String x = "...";
>>  public final String x = "...";
>>
>> throws: "Update to non-static final field ...x... attempted from a
>> different method (initializeInstance) than the initializer method "
>> which is correct, because the field isn't static.
>>
>>
>> Using
>>
>>  private static final String x = "...";
>>
>> works, but requires additional get method.
>>
>>
>> In contrast
>>
>>  public static final String x = "...";
>>
>> is not accessible from the page (tml). Exception is:
>>
>> "Exception assembling root component of page X: Could not convert 'x'
>> into a component parameter binding: Exception generating conduit for
>> expression 'x': Class X does not contain a property (or public field)
>> named 'x'.
>>
>>
>> Tested with T5.8.3 and OpenJDK 11.07
>>
>>
>> Jens
>>
>>
>>
>> Am 01.08.23 um 15:29 schrieb Ben Weidig:
>> > Hi Jens,
>> >
>> > I was looking into static fields and the @Property annotation worker the
>> > other day but stopped, as I realized you can use "public static final"
>> > fields directly in the TML without any additional work.
>> >
>> > So the following code should be fine:
>> >
>> > public final String[] keys = new String[] {
>> >   "A", "B", "C"
>> >   };
>> >
>> > Use it as usual, like "prop:keys" in the TML
>> >
>> >
>> > Private fields that are only exposed to the TML would be preferable, but
>> > it's a simple workaround, and I'm not sure how easy it would be to
>> > implement it in the PlasticClass transformation.
>> >
>> > The change in final handling is most likely related to an older ticket
>> of
>> > mine
>> >
>> > https://issues.apache.org/jira/browse/TAP5-2630
>> >
>> > Cheers
>> > Ben
>> >
>> >
>> > On Tue, Aug 1, 2023 at 2:57 PM Jens Breitenstein > > j-b-s...@toc-mailserver.de> wrote:
>> >
>> >> HI!
>> >>
>> >> I noticed due to JDK 11 there is a subtile change in handling of final
>> >> fields and initialization.
>> >>
>> >> On rare cases we used final fields including @Property(write = false),
>> >> which is no longer working. Example:
>> >>
>> >>   @Property(write="false") private final String[] _keys = new
>> String[] {
>> >>   "A", "B", "C"
>> >>   };
>> >>
>> >> This allowed us to initialize the field once, but still access it from
>> >> the page (tml). Using JDK 11 and T5.8.x this now throws an exception.
>> >> But modifying it to
>> >>
>> >>   private static final String[] _keys = new String[] {
>> >>   "A", "B", "C"
>> >>   };
>> >>
>> >>   public String[] getKeys() {
>> >>   return _keys;
>> >>   };
>> >>
>> >> requires an additional instance method, because @Property can't handle
>> >> static fields. Are there any plans to solve it by Tapestry itself (eg
>> to
>> >> add this "get" method automatically while class transformation is
>> >> applyed in case a field is marked as static and and property)?
>> >>
>> >> Currently I do not see another workaround apart rewriting parts like
>> >> this, right?
>> >>
>> >> Thanks
>> >>
>> >> Jens
>> >>
>> >>
>> >>
>> >> -
>> >> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> >> For additional commands, e-mail: users-h...@tapestry.apache.org
>> >>
>> >>
>>
>> -
>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>
>>
>
>


Re: https://issues.apache.org/jira/browse/TAP5-2630

2023-08-01 Thread Ben Weidig
That's weird...

Here's an example from my code with some custom types:

public static final List WEEK_DAY_SOURCE = List.of(...);

In the TML:


...


Works fine for me, but I'm running 5.8.2 with OpenJDK 17, not 11.



On Tue, Aug 1, 2023 at 4:29 PM Jens Breitenstein  wrote:

> Sorry, Ben, tried it, but this is not working.
>
>
>  private final String x = "...";
>  public final String x = "...";
>
> throws: "Update to non-static final field ...x... attempted from a
> different method (initializeInstance) than the initializer method "
> which is correct, because the field isn't static.
>
>
> Using
>
>  private static final String x = "...";
>
> works, but requires additional get method.
>
>
> In contrast
>
>  public static final String x = "...";
>
> is not accessible from the page (tml). Exception is:
>
> "Exception assembling root component of page X: Could not convert 'x'
> into a component parameter binding: Exception generating conduit for
> expression 'x': Class X does not contain a property (or public field)
> named 'x'.
>
>
> Tested with T5.8.3 and OpenJDK 11.07
>
>
> Jens
>
>
>
> Am 01.08.23 um 15:29 schrieb Ben Weidig:
> > Hi Jens,
> >
> > I was looking into static fields and the @Property annotation worker the
> > other day but stopped, as I realized you can use "public static final"
> > fields directly in the TML without any additional work.
> >
> > So the following code should be fine:
> >
> > public final String[] keys = new String[] {
> >   "A", "B", "C"
> >   };
> >
> > Use it as usual, like "prop:keys" in the TML
> >
> >
> > Private fields that are only exposed to the TML would be preferable, but
> > it's a simple workaround, and I'm not sure how easy it would be to
> > implement it in the PlasticClass transformation.
> >
> > The change in final handling is most likely related to an older ticket of
> > mine
> >
> > https://issues.apache.org/jira/browse/TAP5-2630
> >
> > Cheers
> > Ben
> >
> >
> > On Tue, Aug 1, 2023 at 2:57 PM Jens Breitenstein  > j-b-s...@toc-mailserver.de> wrote:
> >
> >> HI!
> >>
> >> I noticed due to JDK 11 there is a subtile change in handling of final
> >> fields and initialization.
> >>
> >> On rare cases we used final fields including @Property(write = false),
> >> which is no longer working. Example:
> >>
> >>   @Property(write="false") private final String[] _keys = new
> String[] {
> >>   "A", "B", "C"
> >>   };
> >>
> >> This allowed us to initialize the field once, but still access it from
> >> the page (tml). Using JDK 11 and T5.8.x this now throws an exception.
> >> But modifying it to
> >>
> >>   private static final String[] _keys = new String[] {
> >>   "A", "B", "C"
> >>   };
> >>
> >>   public String[] getKeys() {
> >>   return _keys;
> >>   };
> >>
> >> requires an additional instance method, because @Property can't handle
> >> static fields. Are there any plans to solve it by Tapestry itself (eg to
> >> add this "get" method automatically while class transformation is
> >> applyed in case a field is marked as static and and property)?
> >>
> >> Currently I do not see another workaround apart rewriting parts like
> >> this, right?
> >>
> >> Thanks
> >>
> >> Jens
> >>
> >>
> >>
> >> -
> >> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> >> For additional commands, e-mail: users-h...@tapestry.apache.org
> >>
> >>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: https://issues.apache.org/jira/browse/TAP5-2630

2023-08-01 Thread Ben Weidig
Hi Jens,

I was looking into static fields and the @Property annotation worker the
other day but stopped, as I realized you can use "public static final"
fields directly in the TML without any additional work.

So the following code should be fine:

public final String[] keys = new String[] {
 "A", "B", "C"
 };

Use it as usual, like "prop:keys" in the TML


Private fields that are only exposed to the TML would be preferable, but
it's a simple workaround, and I'm not sure how easy it would be to
implement it in the PlasticClass transformation.

The change in final handling is most likely related to an older ticket of
mine

https://issues.apache.org/jira/browse/TAP5-2630

Cheers
Ben


On Tue, Aug 1, 2023 at 2:57 PM Jens Breitenstein  wrote:

> HI!
>
> I noticed due to JDK 11 there is a subtile change in handling of final
> fields and initialization.
>
> On rare cases we used final fields including @Property(write = false),
> which is no longer working. Example:
>
>  @Property(write="false") private final String[] _keys = new String[] {
>  "A", "B", "C"
>  };
>
> This allowed us to initialize the field once, but still access it from
> the page (tml). Using JDK 11 and T5.8.x this now throws an exception.
> But modifying it to
>
>  private static final String[] _keys = new String[] {
>  "A", "B", "C"
>  };
>
>  public String[] getKeys() {
>  return _keys;
>  };
>
> requires an additional instance method, because @Property can't handle
> static fields. Are there any plans to solve it by Tapestry itself (eg to
> add this "get" method automatically while class transformation is
> applyed in case a field is marked as static and and property)?
>
> Currently I do not see another workaround apart rewriting parts like
> this, right?
>
> Thanks
>
> Jens
>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: T5.8.3 upgrade T5.4 webapp

2023-08-01 Thread Ben Weidig
Hi Jens,

There was thread with a similar problem in April, and it turned out that
the new Module organization could lead to missing one if you don't use the
TapestryFilter directly, like via web.xml:

https://lists.apache.org/thread/ocy882q8tgdyq6j3mjs50mjx4y7l7yod

You could try to import the TapestryModule in your AppModule explicitly.

Cheers
Ben

On Mon, Jul 31, 2023 at 7:26 PM Jens Breitenstein  wrote:

> Hi!
>
> we are currently trying to upgrade our webapp from T5.4 to T5.8.3
> The migrator did his job, entire applications builds and starts, well,
> partly.
>
> It looks like our migration is incomplete because we use two external
> libs "federated-accounts" and "json-bindinding". We made a fork of both,
> fixed all compile errors against T5.8.3 and we are able to start the
> Quickstart application linked with these modules.
>
> Unfortunately in our migrated T5.4 application startup fails with:
>
> 31-Jul-2023 14:20:15.889 SEVERE [RMI TCP Connection(2)-127.0.0.1]
> org.apache.catalina.core.StandardContext.filterStart Exception starting
> filter [Application]
>  java.lang.IllegalArgumentException: Contribution
> org.tynamo.security.federatedaccounts.services.FederatedAccountsModule.contributeComponentClassResolver(Configuration)
>
> (at FederatedAccountsModule.java:31) is for service
> 'ComponentClassResolver', which does not exist.
>  at
>
> org.apache.tapestry5.ioc.internal.RegistryImpl.validateContributeDefs(RegistryImpl.java:298)
>  at
>
> org.apache.tapestry5.ioc.internal.RegistryImpl.(RegistryImpl.java:242)
>
> The method causing the error:
>
> public static void
> contributeComponentClassResolver(Configuration
> configuration) { configuration.add(new LibraryMapping(PATH_PREFIX,
> "org.tynamo.security.federatedaccounts")); }
>
> So nothing surprising.
>
> When debugging "RegistryImpl" indeed "ComponentClassResolver" is missing
> as ServiceId in the map serviceIdToModule...
>
> if (!cd3.isOptional()) { if (cd3.getServiceId() != null) { if
> (!this.serviceIdToModule.containsKey(serviceId)) { throw new
> IllegalArgumentException(IOCMessages.contributionForNonexistentService(cd));
>
> } } else if (!this.isContributionForExistentService(module, cd3)) {
>
> ...throwing the exception above.
>
>
> Any idea why the core class "ComponentClassResolver" misses? Maybe an
> initialization / ordering issue concerning module loading?
>
> I forgot: all sources build with JAVA 11 without any problems.
>
> Thanks in advance
>
>
> Jens
>
>


Re: Problem running Tapestry 5.8.2 with Hibernate 5.4.32.Final

2023-06-24 Thread Ben Weidig
I think I found the issue.
Not 100% sure yet, but my first tests look good.

The PropertyShadowBuilder got changed in TAP5-2582, so it can handle
duplicate methods if interfaces extend each other.


In the case of Session, however, the return types of the methods differ, as
it's totally valid to elevate a return type if you extend an interface, as
long as the new return type extends/implements the previous one.
The
org.apache.tapestry5.ioc.internal.services.PropertyShadowBuilderImpl.MethodSignatureUniqueComparator
is used for sorting the methods, so only the first of each method is used.


For example,without checking the return type, the method

public abstract org.hibernate.query.Query
org.hibernate.SharedSessionContract.getNamedQuery(java.lang.String)

gets removed.



With comparing return types, the method

public default org.hibernate.Query
org.hibernate.SharedSessionContract.getNamedQuery(java.lang.String)

gets removed.


What confused me was the "default" modifier on the method, as the method
declarations in the interface don't have a "default" implementations.
Let's recreate the scenario:

interface Original {
Number test();
}
interface Extended extends Original {
Double test();
}

Time for some bytecode:

Classfile /Users/ben/code/tapestry/tapestry-5/Extended.class
  Last modified 24 Jun 2023; size 254 bytes
  SHA-256 checksum
708c3793a9074f5afdd523542cf287559d5cbeee871a0ca9757444dc28edafe3
  Compiled from "Extended.java"
interface Extended extends Original
  minor version: 0
  major version: 61
  flags: (0x0600) ACC_INTERFACE, ACC_ABSTRACT
  this_class: #2  // Extended
  super_class: #7 // java/lang/Object
  interfaces: 1, fields: 0, methods: 2, attributes: 1
Constant pool:
   #1 = InterfaceMethodref #2.#3  //
Extended.test:()Ljava/lang/Double;
   #2 = Class  #4 // Extended
   #3 = NameAndType#5:#6  // test:()Ljava/lang/Double;
   #4 = Utf8   Extended
   #5 = Utf8   test
   #6 = Utf8   ()Ljava/lang/Double;
   #7 = Class  #8 // java/lang/Object
   #8 = Utf8   java/lang/Object
   #9 = Class  #10// Original
  #10 = Utf8   Original
  #11 = Utf8   ()Ljava/lang/Number;
  #12 = Utf8   Code
  #13 = Utf8   LineNumberTable
  #14 = Utf8   SourceFile
  #15 = Utf8   Extended.java
{
  public abstract java.lang.Double test();
descriptor: ()Ljava/lang/Double;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT

  public default java.lang.Number test();
descriptor: ()Ljava/lang/Number;
flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Code:
  stack=1, locals=1, args_size=1
 0: aload_0
 1: invokeinterface #1,  1// InterfaceMethod
test:()Ljava/lang/Double;
 6: areturn
  LineNumberTable:
line 1: 0
}
SourceFile: "Extended.java"

Ok, the "default" method now makes more sense, as the two methods exist on
the interface but with different return types.
This might feel like invalid Java, as the return type doesn't count to the
method signature, but the JVM allows that.
The ACC_BRIDGE flag means that the method was generated by the compiler to
"bridge" between the original method declaration and the override.


With that knowledge, my hunch is that even though the default method, which
should call the correct method, can't because, well, Proxies do a lot of
bytecode magic themselves.


On Fri, Jun 23, 2023 at 8:22 PM Vangel V. Ajanovski 
wrote:

> On 21.6.23 20:32, Volker Lamp wrote:
> > Is there any chance I can motivate you to contribute your test case as
> > a unit test to the Tapestry code base? Have a look at the test apps in
> > tapestry-jpa as a starting point.
>
> If I find some free time in the following months to look it up and learn
> how to create an entire test case. For the time-being it will be faster
> for me to create a docker container spec to reproduce the bug.
>
> As an alternative, I tried to modify the tapestry sources and the
> existing tests. I have never tried to build tapestry from source in the
> past, so bare with my ignorance. I cloned the sources from git, and
> decided for the command line route and just did ./gradlew build.
>
> It seems successful. All the .jars are at the expected locations. I
> modified the gradle build file and hibernate.cfg.xml in the test folders
> inside tapestry-hibernate so that it should connect to another database
> and it uses another driver, just to see if this will stir things up, but
> nothing happened. The problem is that I don't see any connections to the
> database when I run the build, which seems strange to me. How do I force
> the tests to rerun and which is the specific test that i should run that
> uses the connection information in
> tapestry-hibernate/src/test/resources/hibernate.cfg.xml?
>
>
> 

Re: Avoiding page loading

2023-06-18 Thread Ben Weidig
Hi Thiago,

I like your implementation as a general solution better, as it solves the
problem in a simple and straightforward way, whereas my approach would only
provide the tools to build a solution by yourself.

One thing I might have added is a helper method in the ReferenceType to
create the most common contribution easier, maybe something like this
pseudo/untested code:

public enum ReferenceType {
SOFT,
STRONG;

public PageCachingReferenceTypeService forPages(String...
canonicalPageNames) {
// Handle simplest case without allocating a HashSet
if (canonicalPageNames.length == 1) {
return pageName ->
canonicalPageNames[0].equalsIgnoreCase(pageName) ? this : null;
}

// Prepare the page names for case-insensitive lookup
Set pageNames = new HashSet<>(canonicalPageNames.length);
for (String pageName : canonicalPageNames) {
pageNames.add(pageName.toLowerCase());
}

return pageName -> pageNames.contains(pageName.toLowerCase()) ?
this : null;
}
}

configuration.add("StrongPages", ReferenceType.STRONG.forPages("VeryLarge",
"AndTheOtherLargePage"));

Cheers
Ben

On Sun, Jun 18, 2023 at 12:11 AM Thiago H. de Paula Figueiredo <
thiag...@gmail.com> wrote:

> Hello!
>
> So I've just implemented what I suggested in Tapestry 5.8.3:
> https://issues.apache.org/jira/browse/TAP5-2756. Example:
>
> public static void contributePageCachingReferenceTypeService(
>   OrderedConfiguration
> configuration) {
> configuration.add("VeryLarge", p -> p.equals("VeryLarge") ?
> ReferenceType.STRONG : null);
> }
>
> This would cause the page named VeryLarge to be cached using a
> regular, strong, non-garbage-collectable reference while leaving all
> other pages cached with a soft, garbage-collectable reference.
>
> Ben, I find your idea interesting, but I believe it's a bit orthogonal
> to what I did, both being able to coexist.
>
> On Thu, Jan 5, 2023 at 10:23 AM Thiago H. de Paula Figueiredo
>  wrote:
> >
> > Hello, everyone!
> >
> > I prefer Ben's idea of a thread or cron job to keep it fresh other
> > than overriding a service, especially now that I'm working on
> > something (smarter page invalidation, which is actually smarter
> > invalidation of some key Tapestry caches) which changes that
> > PageSourceImpl a bit and this override would likely break live class
> > reloading. I'd have the cron/thread call ComponentSource.getPage()
> > instead, since PageSource is an internal service and ComponentSource
> > isn't.
> >
> > Another possibility is to introduce a configuration to tell whether
> > PageSource should use regular references or soft ones, defaulting to
> > current behavior. Or a new service to tell whether a specific page
> > class should use a regular reference instead of a soft one. This would
> > be more flexible.
> >
> > On Wed, Dec 28, 2022 at 6:55 AM Ben Weidig  wrote:
> > >
> > > Hi Geoff,
> > >
> > > I've read through the SoftReference documentation and as far as I
> > > understand it the references do only get garbage-collected in case of
> > > memory-pressure.
> > > However, the behavior to keep recently used objects is only
> encouraged, not
> > > explicitly required.
> > >
> > > Looking over the source code, you mabye can replace PageSource with a
> > > custom implementation that uses another caching implementation.
> > > Something like this (untested) code maybe?
> > >
> > > package tapestry;
> > >
> > > import java.lang.ref.SoftReference;
> > > import java.util.Map;
> > >
> > > import org.apache.tapestry5.commons.util.CollectionFactory;
> > > import org.apache.tapestry5.internal.services.PageLoader;
> > > import org.apache.tapestry5.internal.services.PageSourceImpl;
> > > import org.apache.tapestry5.internal.structure.Page;
> > > import
> > >
> org.apache.tapestry5.services.pageload.ComponentRequestSelectorAnalyzer;
> > > import
> org.apache.tapestry5.services.pageload.ComponentResourceSelector;
> > >
> > > public class CustomPageSourceImpl extends PageSourceImpl {
> > >
> > > private PageLoader   pageLoader;
> > > private ComponentRequestSelectorAnalyzer selectorAnalyzer;
> > >
> > > public CustomPageSourceImpl(PageLoader pageLoader,
> > > ComponentRequestSelectorAnalyzer selectorAnalyzer) {
> > > super(pageLoader, selectorAnalyzer);
> > > this.page

Re: Problem running Tapestry 5.8.2 with Hibernate 5.4.32.Final

2023-06-11 Thread Ben Weidig
Hi Chris,

I've created a ticket: https://issues.apache.org/jira/browse/TAP5-2754

If I understand it correctly, the getSession() call just returns the
associated session of the org.hibernate.jpa.HibernateEntityManager which
Session extends since 5.2, see
https://github.com/hibernate/hibernate-orm/blob/5.2/migration-guide.adoc#hibernate-entitymanager-merged-into-hibernate-core

As the "session" in the session.getSession() call is still the injected
per-thread scoped one, the Session should just be original/not
shadow-propertied one, not a new one.

Cheers,
Ben

On Sun, Jun 11, 2023 at 3:19 AM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hi Ben,
>
> Thank you for your investigative efforts, even though you weren't yet
> able to pinpoint the exact cause.  And thank you, you and Vangel, for
> sharing that workaround.
>
> Occasionally, this HibernateCrudServiceDAO method works as expected.
> Most times not.  This seeming randomness fits with your explanation of
> the 'shadow Session' being generated at runtime... perhaps something is
> prematurely getting garbage collected?
>
> For now, I'll switch to session.getSession() as suggested.  I guess this
> returns an actual Hibernate session, bypassing Tapestry's per-thread
> (scope) logic in between.
>
> Should this issue be recorded as a potential bug so that it eventually
> gets fixed?
>
> Kind regards,
>
> Chris.
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Problem running Tapestry 5.8.2 with Hibernate 5.4.32.Final

2023-06-10 Thread Ben Weidig
I've tried to debug the issue again, but to no avail :-/

Here are my observations/findings/notes:

The Session you get injected is actually a shadowed property of
org.apache.tapestry5.hibernate.HibernateSessionManager that is created in
org.apache.tapestry5.hibernate.modules.HibernateCoreModule.buildSession(HibernateSessionManager,
PropertyShadowBuilder)

The PropertyShadowBuilder creates a proxy of a single property of a source
object, and delegates all calls to the source object when used.
This allows the shadowed property, in this case Session, to be extracted
from the source, HibernateSessionManager, and used as an isolated instance.
Behind the scenes, though, it's still the session of a HSM.
This is done so the HSM can be per-Thread scoped and only create a session
if it's actually used.

I've debugged through the shadowing process and checked the created
PlasticClass and underlying ClassNode, and they look good to me.

As everything is runtime-generated bytecode, maybe a tool like
https://github.com/AdoptOpenJDK/jitwatch could help to analyze what's
actually happening.
But so far, I only got Eclipse to run out of heap space...

My guess is that the big changes starting Hibernate 5.2 (moving towards
javax.persistence, like Session now extending
javax.persistence.EntityManager and
org.hibernate.jpa.HibernateEntityManage) are not 100% compatible with what
Plastic/PropertyShadowBuilder are doing behind the scenes.
It's not completely broken, but certain things seem to work a little
differently.

On Fri, Jun 9, 2023 at 7:07 PM Vangel V. Ajanovski 
wrote:

> On 9.6.23 14:30, Ben Weidig wrote:
> > we ran into similar issues with custom queries, our workaround is calling
> > getSession() on the session, like this:
> >
> > return this.session.getSession().createQuery(sql) //
> > .setParameter("replyToId", relatedId) //
> > .setParameter("type", type) //
> > .executeUpdate();
> >
> Hi, I have the same issue since 5.7.3 -- I encountered the issue in a
> different context and discussed it briefly here in that context when
> 5.7.3 was released.
>
> The problem and solution is the same:
>
> @Inject private Session session;
>
> session.createQuery("from Table")
>
> fails as createQuery returns null
>
> On the other hand
>
> session.getSession().createQuery("from Table")
>
> works without issues.
>
>
> Who knows maybe there is some other consequence of using
> session.getSession().
>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Problem running Tapestry 5.8.2 with Hibernate 5.4.32.Final

2023-06-09 Thread Ben Weidig
Hi Chris,

we ran into similar issues with custom queries, our workaround is calling
getSession() on the session, like this:

   return this.session.getSession().createQuery(sql) //
   .setParameter("replyToId", relatedId) //
   .setParameter("type", type) //
   .executeUpdate();

It's ugly and the call is deprecated, but it worked for us.
We never really looked into it, though, as we usually don't use Hibernate
via named/custom queries that much.

My guess would be that something changed in the Hibernate session,
and 
org.apache.tapestry5.hibernate.modules.HibernateCoreModule.buildSession(HibernateSessionManager,
PropertyShadowBuilder) doesn't work as initially intended anymore.

Cheers
Ben

On Fri, Jun 9, 2023 at 1:43 PM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hello,
>
> I've encountered an issue after upgrading from Tapestry 5.6.4 to 5.7.3.
> This included moving from Hibernate 5.1.0.Final to 5.4.32.Final (as per
> the guidelines).
>
> The HibernateCrudServiceDAO method below is now failing to fetch named
> queries via the injected org.hibernate.Session, resulting in a null
> pointer exception when attempting to write parameters to it.
>
> I'm wondering whether this might have something to do with
> org.hibernate.Query having been deprecated and replaced with
> org.hibernate.query.Query.  I understand the tapestry-hibernate package
> was reworked around the time of Tapestry 5.7.3 to support changes in
> Hibernate.
>
> Incidentally, the issue remains with Tapestry 5.8.2.
>
> Any help/insights would be much appreciated.
>
> Thanks & regards,
>
> Chris.
>
>
> import org.hibernate.query.Query;
> import org.hibernate.Session;
> ...
>  @Inject
>  private Session session;
> ...
>  public  T findUniqueWithNamedQuery(String queryName, Map Object> params){
>  Set> rawParameters = params.entrySet();
>  Query query = session.getNamedQuery(queryName);
>
>  if(query == null) LOG.error("Oops, Hibernate session returned
> null Query object!");
>  if(query != null) LOG.debug("Query string = " +
> query.getQueryString());
>
>  for(Entry entry : rawParameters){
>  LOG.debug("Entry key = " + entry.getKey());
>  LOG.debug("Entry value = " + entry.getValue().toString());
>  query.setParameter(entry.getKey(), entry.getValue());
>  }
>
>  return (T) query.uniqueResult();
>  }
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: ComponentClassResolver error

2023-04-27 Thread Ben Weidig
Is org.apache.tapestry5.modules.TapestryModule in the list of loaded
modules?
Is tapestry-core missing in the dependencies?
Which version did you update from to 5.8?
Which TapestryFilter are you loading in the web.xml?
Is there maybe an old JAR somewhere screwing up the classpath?

Without more info it's hard to suggest anything more than "the usual"
things that could've gone wrong.

On Thu, Apr 27, 2023 at 1:28 PM Ric 2000  wrote:

> Hi Ben,
>
> Yes, we Start in Standard jboss eap 7.x
>
> Thanks and Regards
> Ric
>
> Ben Weidig  schrieb am Do., 27. Apr. 2023, 13:04:
>
> > Hi Ric,
> >
> > that's weird, the method signature looks fine to me.
> >
> > Is org.apache.tapestry5.modules.TapestryModule listed in the loaded
> modules
> > in the log output?
> >
> > How do you start your Tapestry project?
> > Do you use the standard way of starting Tapestry in a
> > ServletContainer/web.xml/TapestryFilter or do you use any other means to
> > start the Registry?
> > For example, we use a custom starter project initializing Tapestry
> > manually, so we need to add the TapestryModule manually, too, as it's
> only
> > provided by the TapestryFilter.
> >
> > Cheers
> > Ben
> >
> > On Thu, Apr 27, 2023 at 9:57 AM Ric 2000 
> wrote:
> >
> > > Hi all,
> > > After Migration to Tapestry 5.8 I face the following issue
> > > with ComponentClassResolver during Server start:
> > >
> > > "Contribution XYZ(Configuration) is for service
> 'ComponentClassResolver',
> > > which does not exist"
> > >
> > > In my own filter module in my library I used code like the following:
> > >
> > > void contributeComponentClassResolver(Configuration
> > > configuration)
> > >
> > > Do you Haven Idea what is going wrong here?
> > >
> > > Thanks for your Help.
> > >
> > > Regards, Ric
> > >
> >
>


Re: ComponentClassResolver error

2023-04-27 Thread Ben Weidig
Hi Ric,

that's weird, the method signature looks fine to me.

Is org.apache.tapestry5.modules.TapestryModule listed in the loaded modules
in the log output?

How do you start your Tapestry project?
Do you use the standard way of starting Tapestry in a
ServletContainer/web.xml/TapestryFilter or do you use any other means to
start the Registry?
For example, we use a custom starter project initializing Tapestry
manually, so we need to add the TapestryModule manually, too, as it's only
provided by the TapestryFilter.

Cheers
Ben

On Thu, Apr 27, 2023 at 9:57 AM Ric 2000  wrote:

> Hi all,
> After Migration to Tapestry 5.8 I face the following issue
> with ComponentClassResolver during Server start:
>
> "Contribution XYZ(Configuration) is for service 'ComponentClassResolver',
> which does not exist"
>
> In my own filter module in my library I used code like the following:
>
> void contributeComponentClassResolver(Configuration
> configuration)
>
> Do you Haven Idea what is going wrong here?
>
> Thanks for your Help.
>
> Regards, Ric
>


Re: Preventing double click eventlink and form submit

2023-02-26 Thread Ben Weidig
Hi Nathan,

Maybe I misunderstood your goal, but I would solve it with a module
configured by CSS classes or data attributes instead of dedicated
components.

Something along the line of this (untested) CoffeeScript I improvised:


define ['jquery', 't5/core/events'], ($, events) ->

EVENT = 'click.request-in-progress'

register = ->
$('.show-request-in-progress').off(EVENT).on EVENT, ->
$el = $(this)

$el.addClass('request-in-progress')

relatedZone = $el.data('target-zone')
elEvent = "#{t5events.zone.wilUpdate}.##{$el.id}"
zone.on elEvent, ->
zone.off(elEvent)
trigger.removeClass('request-in-progress')
return true

$ ->
register()
$(document).on events.zone.didUpdate, register

See https://gist.github.com/benweidig/2f2fdb32c74cbd57764b1f7dabbe7079 for
a nicely formatted version.

This way, you wouldn't need an additional zone and just need to listen to
the content zone to be updated. Only the ".show-request-in-progress" and
"data-target-zone" must be set accordingly.
Actually, the CSS classes isn't needed and the relevant elements could be
targeted via the data attribute.

Cheers
Ben

On Fri, Feb 24, 2023 at 2:11 PM Nathan Quirynen 
wrote:

> Hi,
>
> I am looking for a solution to prevent multiple clicks on event links or
> form submits in our Tapestry application and in the meanwhile if
> possible giving the user visual feedback while the request is being
> processed.
> We use ajax (async="true") on both our eventlinks and form components,
> but there are no javascript events to hook into right before the request
> is fired and when the request response is handled. But after some
> research I found I can use the zone parameter instead of the async
> parameter and then make use of the t5:zone:refresh and
> t5:zone:did-update events to do exactly that.
> So I came up with following javascript module which can be used for both
> form submit buttons and eventlinks:
>
>  var init = function(triggerClientId, zoneClientId) {
>
>  var trigger = $('#' + triggerClientId);
>  var zone = $('#' + zoneClientId);
>
>  var event_request = 't5:zone:refresh' + '.' +
> triggerClientId;
>
>  zone.on(event_request, function(e) {
>
> // disable trigger + add css class
>  trigger.css('pointer-events', 'none');
>  trigger.addClass('request-in-progress');
>
>  var event_response = 't5:zone:did-update' + '.' +
> triggerClientId;
>  zone.on(event_response, function() {
>
>  // remove response event handler
>  zone.off(event_response);
>
>  // reenable trigger + remove css class
>  trigger.css('pointer-events', 'auto');
> trigger.removeClass('request-in-progress');
>
>  });
>  });
>
>  }
>
> I would make new components AjaxForm/AjaxEventLink to wrap the original
> ones and implement everything there.
> This seems to work as I hoped it would be, but then a zone element is
> added for every EventLink/Form which seems a bit like overkill, but I
> don't see another way at the moment.
> I was wondering if others have tried to do something like I am, or if
> there's any better way of achieving what I am trying here? Or anything
> that I am missing could be wrong with my implementation?
>
>
> Nathan
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Use SASS Stylesheets

2023-01-27 Thread Ben Weidig
Hi Chirag,


We successfully included SASS in our projects.

However, our implementation isn't open-source, and it's quite a specific
solution as we need to modify and compile different Bootstrap versions
depending on each request in a singular project.


Here's what we do:


We use https://gitlab.com/jsass/jsass to compile SASS to CSS.

Sadly, the underlying libsass is more or less EOL, as is jsass itself.

It didn't include a library for Apple Silicon, which we had to build and
add ourselves.


On the Tapestry side, we created SASS-specific variants of:

   - org.apache.tapestry5.commons.Resource
   - org.apache.tapestry5.services.AssetFactory
   - org.apache.tapestry5.services.assets.ResourceTransformer


You could checkout
org.apache.tapestry5.internal.webresources.LessResourceTransformer and how
it's contributed/used in Tapestry to see how to integrate something similar.


Cheers

Ben

On Fri, Jan 27, 2023 at 11:21 AM Chirag Misra
 wrote:

> Hi,
>
> I was looking into using SASS stylesheets on our application which runs on
> Tapestry version 5.7.3
>
> I noticed that there is support for LESS using the less4j library. Has
> anyone been able to use SASS? I was expecting that there would be support
> for wro4j in tapestry but that doesn’t seem to be the case. Any pointers on
> how you would go about using SASS?
>
> Thanks,
> Chirag
>
> Confidentiality note: This e-mail may contain confidential information
> from Clarivate. If you are not the intended recipient, be aware that any
> disclosure, copying, distribution or use of the contents of this e-mail is
> strictly prohibited. If you have received this e-mail in error, please
> delete this e-mail and notify the sender immediately.
>


Re: Avoiding page loading

2023-01-05 Thread Ben Weidig
Hello!

Your're right, overriding an internal service is usually an invitation for
trouble with any bigger Tapestry update.
Still, personally, I prefer a service override over cron jobs triggering
things behind the scenes.
Especially since it's one of Tapestry's greatest features to replace almost
any part of it as needed, so I can break all the things :-D

Making the caching style more configurable might be a nice addition to
provide more freedom.
However, my first thought was a little bit more detached from
"SoftReference or not".

Something trivial like this:

interface PageCacheService {
Page  getPage(String canonicalPageName, ComponentResourceSelector
selector);
void setPage(Page page, String canonicalPageName,
ComponentResourceSelector selector);
}

This way, any type of caching could be used, like a dedicated caching
library like EhCache.

The org.apache.tapestry5.internal.services.PageSourceImpl.CachedPageKey
could be exposed to be used instead of dedicated arguments for
canonicalPageName and selector.

The default implementation could be a simple wrapper around a
Map>, just like the one used now.

Cheers

On Thu, Jan 5, 2023 at 2:23 PM Thiago H. de Paula Figueiredo <
thiag...@gmail.com> wrote:

> Hello, everyone!
>
> I prefer Ben's idea of a thread or cron job to keep it fresh other
> than overriding a service, especially now that I'm working on
> something (smarter page invalidation, which is actually smarter
> invalidation of some key Tapestry caches) which changes that
> PageSourceImpl a bit and this override would likely break live class
> reloading. I'd have the cron/thread call ComponentSource.getPage()
> instead, since PageSource is an internal service and ComponentSource
> isn't.
>
> Another possibility is to introduce a configuration to tell whether
> PageSource should use regular references or soft ones, defaulting to
> current behavior. Or a new service to tell whether a specific page
> class should use a regular reference instead of a soft one. This would
> be more flexible.
>
> On Wed, Dec 28, 2022 at 6:55 AM Ben Weidig  wrote:
> >
> > Hi Geoff,
> >
> > I've read through the SoftReference documentation and as far as I
> > understand it the references do only get garbage-collected in case of
> > memory-pressure.
> > However, the behavior to keep recently used objects is only encouraged,
> not
> > explicitly required.
> >
> > Looking over the source code, you mabye can replace PageSource with a
> > custom implementation that uses another caching implementation.
> > Something like this (untested) code maybe?
> >
> > package tapestry;
> >
> > import java.lang.ref.SoftReference;
> > import java.util.Map;
> >
> > import org.apache.tapestry5.commons.util.CollectionFactory;
> > import org.apache.tapestry5.internal.services.PageLoader;
> > import org.apache.tapestry5.internal.services.PageSourceImpl;
> > import org.apache.tapestry5.internal.structure.Page;
> > import
> > org.apache.tapestry5.services.pageload.ComponentRequestSelectorAnalyzer;
> > import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
> >
> > public class CustomPageSourceImpl extends PageSourceImpl {
> >
> > private PageLoader   pageLoader;
> > private ComponentRequestSelectorAnalyzer selectorAnalyzer;
> >
> > public CustomPageSourceImpl(PageLoader pageLoader,
> > ComponentRequestSelectorAnalyzer selectorAnalyzer) {
> > super(pageLoader, selectorAnalyzer);
> > this.pageLoader = pageLoader;
> > this.selectorAnalyzer = selectorAnalyzer;
> >
> > }
> >
> > private static final record CachedPageKey(String pageName,
> > ComponentResourceSelector selector) {
> > }
> >
> > private final Map pageCache =
> > CollectionFactory.newConcurrentMap();
> >
> > public Page getPage(String canonicalPageName)
> > {
> > var selector = selectorAnalyzer.buildSelectorForRequest();
> >
> > var key = new CachedPageKey(canonicalPageName, selector);
> >
> > while (true)
> > {
> > Object cachedObject = pageCache.get(key);
> >
> > Page page = null;
> > if (cachedObject instanceof SoftReference ref) {
> > page = ref == null ? null : (Page) ref.get();
> > } else {
> > page = (Page) cachedObject;
> > }
> >
> > if (page != null)
> > {
> > return page;
> > }
> > // In rare race conditions, 

Re: Avoiding page loading

2022-12-28 Thread Ben Weidig
Hi Geoff,

I've read through the SoftReference documentation and as far as I
understand it the references do only get garbage-collected in case of
memory-pressure.
However, the behavior to keep recently used objects is only encouraged, not
explicitly required.

Looking over the source code, you mabye can replace PageSource with a
custom implementation that uses another caching implementation.
Something like this (untested) code maybe?

package tapestry;

import java.lang.ref.SoftReference;
import java.util.Map;

import org.apache.tapestry5.commons.util.CollectionFactory;
import org.apache.tapestry5.internal.services.PageLoader;
import org.apache.tapestry5.internal.services.PageSourceImpl;
import org.apache.tapestry5.internal.structure.Page;
import
org.apache.tapestry5.services.pageload.ComponentRequestSelectorAnalyzer;
import org.apache.tapestry5.services.pageload.ComponentResourceSelector;

public class CustomPageSourceImpl extends PageSourceImpl {

private PageLoader   pageLoader;
private ComponentRequestSelectorAnalyzer selectorAnalyzer;

public CustomPageSourceImpl(PageLoader pageLoader,
ComponentRequestSelectorAnalyzer selectorAnalyzer) {
super(pageLoader, selectorAnalyzer);
this.pageLoader = pageLoader;
this.selectorAnalyzer = selectorAnalyzer;

}

private static final record CachedPageKey(String pageName,
ComponentResourceSelector selector) {
}

private final Map pageCache =
CollectionFactory.newConcurrentMap();

public Page getPage(String canonicalPageName)
{
var selector = selectorAnalyzer.buildSelectorForRequest();

var key = new CachedPageKey(canonicalPageName, selector);

while (true)
{
Object cachedObject = pageCache.get(key);

Page page = null;
if (cachedObject instanceof SoftReference ref) {
page = ref == null ? null : (Page) ref.get();
} else {
page = (Page) cachedObject;
}

if (page != null)
{
return page;
}
// In rare race conditions, we may see the same page loaded
multiple times across
// different threads. The last built one will "evict" the
others from the page cache,
// and the earlier ones will be GCed.

page = pageLoader.loadPage(canonicalPageName, selector);

// TODO: Decide here if how you want to store the Page

Object cacheValue = new SoftReference(page);

pageCache.put(key, cacheValue);
}
}
}

I'm not sure what the implications are if a page is kept forever, but as a
SoftReference isn't guaranteed to be garbage-collected, I don't see an
immediate downside, except needing more memory.

Alternatively you could trigger the page with a cron job to keep it
"fresh", but an overriden service is the more robust solution in my opinion.

Cheers
Ben

On Tue, Dec 27, 2022 at 3:24 PM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> Hi,
>
> I have one page in my production app which takes a long time to load -
> minimum 18 seconds. Once loaded, it is very quick to request. But from time
> to time throughout the day, when this page is requested Tapestry decides it
> has to reload it. I presume this is because the page cache uses
> SoftReference (PageSourceImpl.pageCache) and the page has been garbage
> collected. For the unlucky user, they have to wait an unbearably long time.
> Sometimes when the system is under load the request can even time out. Is
> there a simple, reliable, safe way to prevent it being garbage collected?
> Or have I misunderstood what’s going on?
>
> Cheers,
>
> Geoff
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Where to find dom js

2022-08-17 Thread Ben Weidig
Hi Ric,

the file is preprocessed as a Gradle task of Tapestry itself to support
jquery and prototype. [1]
The version matching your JS provider is added as "t5/core/dom" here [2]

Hope this helps!

Cheers
Ben

[1]
https://github.com/apache/tapestry-5/blob/5.4.x/tapestry-core/src/main/preprocessed-coffeescript/org/apache/tapestry5/t5-core-dom.coffee
[2]
https://github.com/apache/tapestry-5/blob/06de1716e6cf3085fb60b33de3d49fdfb6f05285/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java#L397



On Wed, Aug 17, 2022 at 8:20 AM Ric 2000  wrote:

> Hi all,
>
> We use Version 5.4.6 of Tapestry.
> The script select.js uses via require a library dom.js, and also zone.js
> and events ja. The two latter ones are existing in modules/t5/core, but
> dom.js I can't find in the tapestry-core sources.
> Do you know where to find it?
>
> Regards, Ric
>


Re: JumpStart is up

2022-07-11 Thread Ben Weidig
Looks good!

I've did a simple search for "jumpstart" and updated the links (~ 14 pages).
Hopefully that's all of them.

Gonna check later after the cron job ran if the site is updated correctly.


On Mon, Jul 11, 2022 at 8:42 AM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> Thank you Ben. Please try again now.
>
> > On 11 Jul 2022, at 2:26 pm, Ben Weidig  wrote:
> >
> > Hi Geoff,
> >
> > thanks!
> >
> > I've started updating the links in Confluence, but ran into an
> > exception: Database data has not been set up!
> >
> >
> https://tapestry-jumpstart.org/jumpstart/examples/navigation/onactivateandonpassivate/3
> >
> > Cheers
> > Ben
> >
> > On Mon, Jul 11, 2022 at 2:00 AM JumpStart <
> > geoff.callender.jumpst...@gmail.com> wrote:
> >
> >> JumpStart is up! Its new home is
> https://tapestry-jumpstart.org/jumpstart
> >> <https://tapestry-jumpstart.org/jumpstart>. Yesterday it had the wrong
> >> certificate but that has now been fixed.
> >>
> >> Would someone please update the links from the Tapestry site?
> >>
> >> Cheers,
> >>
> >> Geoff
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: JumpStart is up

2022-07-11 Thread Ben Weidig
Hi Geoff,

thanks!

I've started updating the links in Confluence, but ran into an
exception: Database data has not been set up!

https://tapestry-jumpstart.org/jumpstart/examples/navigation/onactivateandonpassivate/3

Cheers
Ben

On Mon, Jul 11, 2022 at 2:00 AM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> JumpStart is up! Its new home is https://tapestry-jumpstart.org/jumpstart
> . Yesterday it had the wrong
> certificate but that has now been fixed.
>
> Would someone please update the links from the Tapestry site?
>
> Cheers,
>
> Geoff


Re: ChecksumPath exception on unexistent assets

2022-05-09 Thread Ben Weidig
Hi Bob,

thanks for the patch!
I've changed it to an early return to don't check for -1 again, and added
some tests.

https://github.com/apache/tapestry-5/commit/b01906961a456656404fc2bc9d85ea2aeff10c53

Cheers,
Ben

On Mon, May 9, 2022 at 3:57 PM Roberto  wrote:

> Hi Ben,
>
> a possible solution for TAP5-2713 (ChecksumPath:
> java.lang.StringIndexOutOfBoundsException) ticket could be this:
>
> In 'ChecksumPath' method only check 'slashx' variable and if it is -1
> return NON_EXISTING_RESOURCE, otherwise it executes the normal code.
>
> The patch is in attached.
>
> Regards,
> Bob
>
> Roberto Marotta
> D.B.M. Srl
> Via Enrico Noe, 23
> 20133 Milano
> Tel. 02.26.60.05.21
>
>
> --
> *From: *"Ben Weidig" 
> *To: *"Tapestry users" 
> *Sent: *Monday, 28 March, 2022 4:30:28 PM
> *Subject: *Re: ChecksumPath exception on unexistent assets
>
> Hi Bob,
>
> thanks for informing us about the exception on non-existant resources,
> I've created an issue: https://issues.apache.org/jira/browse/TAP5-2713 and
> will take a look.
>
> Cheers,
> Ben
>
>
> On Mon, Mar 28, 2022 at 4:15 PM Roberto  wrote:
>
> >
> >
> > Hi,
> >
> > It appears that the
> > "org.apache.tapestry5.internal.services.assets.ChecksumPath" class throws
> > exception
> > like "String index out of range: -1" when trying to apply substring
> > function on unexistent resource path.
> > Maybe throwing an exception like "404 code error and resource not found"
> > would be more convenient.
> >
> > kind regards
> > bob
> >
> >
> >
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org


Re: Tapestry PeriodicExecutor - CronExpression issue with "L"

2022-04-26 Thread Ben Weidig
Hi Charles,


I gave it a quick look and debugged
org.apache.tapestry5.ioc.internal.services.cron.CronExpression.getTimeAfter(Date)
with your expression and can confirm that there's an issue with handling
"L-".

At first, it got the right day, but then it gets reset to today.

The code is quite complex, and I haven't found the bug yet.


There are three possible workarounds I can think of:

   - Implement org.apache.tapestry5.ioc.services.cron.Schedule yourself
   with another Cron-Parser. This option might be overkill and hard to get
   right.
   - Use a scheduling framework like http://www.quartz-scheduler.org/ which
   might also be a hassle to do correctly. We use it, but with a lot of
   boilerplate/glue code.
   - Schedule a Job on every 18th that calculates the next execution date
   for the "real" Job and add it with a fixed day of month.
   Jobs get removed if no further execution date is calculable, so it
   shouldn't accumulate memory over time.


I've created an issue: https://issues.apache.org/jira/browse/TAP5-2723


Cheers

Ben

On Mon, Apr 25, 2022 at 11:50 PM Charles Karow  wrote:

> Hi,
>
> There seems to be an issue with CronExpression using "L" (last day of
> month).
>
> When I place the following code in my AppModule, the job is triggered at
> the appointed time, and then keeps executing over and over immediately in a
> seemingly infinite loop. I can work around by using a day-of-the-month
> number only, but would prefer using "L-10."
>
> Is there any other work around?
>
> Thanks,
>
> Charles
>
> @Startup
> public static void scheduleJobs(PeriodicExecutor executor)
> {
> executor.addJob(
> new CronSchedule("0 55 8 L-9 * ? *"),
> "Testing",
> new Runnable() {
> @Override
> public void run() {
> System.err.println("Executing Test...");
> }
> });
>
> }
>
>
> --
> [image: Karow Associates] 
> Charles Karow  Software Architect/Engineer
> 1.410.276.4016  •  [image: LinkedIn] 
> "Specializing in Fast, Reliable Web Applications"
>
>


Re: Javascript module isn't generating css asset url

2022-04-15 Thread Ben Weidig
Hi George,

I can't help with a "good" solution, only what we did to get the Monaco
Editor running which loads css/js by itself.

IIRC the underlying problem is that JS using require() builds the "wrong"
URL for the requested asset/tapestry on the client-side.
Tapestry expects modules to be in META-INF/modules and anything else in
META-INF/assets.
That's why they need to be split up accordingly, and we intercept any
requests to the "wrong" folder and fix them.

I know it's quite hacky, but when I wrote it in the past I didn't know any
better, and it worked for our problem.
But maybe there should be an easier way to support loading related files
for JS modules.

Gist for readability:
https://gist.github.com/benweidig/aba58e79be2850f55ab3fb14424ff311

public class MonacoEditorModule {

private static final Pattern CSS_PATTERN =
Pattern.compile("^/modules(\\.gz)?/monaco/(.+\\.css)$");
private static final Pattern JS_PATTERN =
Pattern.compile("^/modules(\\.gz)?/monaco/vs/(.+\\.js)$");

public static void
contributeRequestHandler(OrderedConfiguration conf,
ResourceStreamer streamer) {

conf.add("monaco-assets-redirect-request-filter", (request,
response, handler) -> {
var matcher = cssPattern.matcher(request.getPath());
if (matcher.matches() == false) {
return handler.service(request, response);
}

var resource = new
ClasspathResource("META-INF/assets/backend/monaco/" + matcher.group(2));
streamer.streamResource(resource, //
"",

EnumSet.of(ResourceStreamer.Options.OMIT_EXPIRATION));
return true;
});

conf.add("monaco-module-redirect-request-filter", (request,
response, handler) -> {
var matcher = jsPattern.matcher(request.getPath());

if (matcher.matches() == false) {
return handler.service(request, response);
}

var resource = new
ClasspathResource("META-INF/modules/monaco/0.26.1/" + matcher.group(2));

request.setAttribute(TapestryConstants.DISABLE_JAVASCRIPT_MINIMIZATION,
Boolean.TRUE);

streamer.streamResource(resource, //
"z",

EnumSet.of(ResourceStreamer.Options.OMIT_EXPIRATION));
return true;
});
}
}

Cheers
Ben

On Thu, Apr 14, 2022 at 11:04 PM George Christman 
wrote:

> Hi, I upgraded to Tapestry 5.8.1 and I moved all my js, css and modules to
> the webapp directory. I have a ckeditor module that is trying to load some
> ckeditor css and image files. In older versions of tapestry I resolved this
> with ClasspathAssetAliasManager, but that seems to be deprecated and no
> longer functional. "configuration.add("ck", "META-INF/modules/vendor");".
> My package structure is webapp/modules/editor.js
> webapp/modules/vendor/ckeditor
>
> My editor.js file looks like this.
>
> requirejs.config({
> shim: {
> 'ckeditor-jquery': ['jquery', 'ckeditor-core']
> },
> paths: {
> 'ckeditor-core': 'vendor/ckeditor/ckeditor',
> 'ckeditor-jquery': 'vendor/ckeditor/adapters/jquery'
> }
> });
> define(["jquery", "ckeditor-jquery"], function($) {
>
> init = function(spec) {
> $('#' + spec.id).ckeditor();
> };
>
> return init;
> });
>
> How is this achieved in 5.8?
> --
>
> George Christman
>
>
>
> This e-mail may contain confidential, proprietary information on Zigster.
> It is intended solely for the name recipient(s) listed above and should be
> maintained in strictest confidence. If you are not the intended recipient,
> you are hereby notified that any disclosure, copying, distribution, or use
> of the information contained herein (including any reliance thereon) is
> STRICTLY PROHIBITED. If you have received this e-mail in error, please
> immediately notify the sender and delete this information from your
> computer and destroy any related paper copies. Unless otherwise expressly
> stated in the text of the e-mail, the addition of a typed name or initials
> to this e-mail does not (i) evidence an intent to sign the e-mail, or (ii)
> constitute either (a) signature or (b) consent to use electronic records or
> signatures in place of a writing or a handwritten signature.
>


Re: [ANNOUNCEMENT] Tapestry 5.8.1 released!

2022-04-05 Thread Ben Weidig
Hi Tim,

thanks for notifying us!

After a quick glance it looks like it's an issue since 5.7+

I've created a ticket: https://issues.apache.org/jira/browse/TAP5-2718

Cheers,
Ben

On Tue, Apr 5, 2022 at 8:32 AM D Tim Cummings 
wrote:

> Thanks Thiago
>
> I checked the updates in quickstart and they look great.
>
> One minor thing when running quickstart, the ascii art no longer knows
> which tapestry version is running :(
>
>   __  __ 
> /_  __/__   ___ ___ / /___ __  / __/
>   / / / _ `/ _ \/ -_|_- /_/  \_,_/ .__/\__/___/\__/_/  \_, / //
>  /_/   /___/  UNKNOWN (development mode)
>
> Cheers
>
> Tim
>
> On 4/4/22 21:53, Thiago H. de Paula Figueiredo wrote:
> > Hello, Tapestry community!
> >
> > We've just released Tapestry 5.8.1. It's mostly about getting
> Tapestry-IoC
> > to support all Java language features introduced between Java 9 and 17.
> It
> > also includes some other bug fixes and small improvements.
> >
> > Tapestry 5.8.1 is a drop-in replacement and recommended upgrade for
> > Tapestry 5.7.0+ projects.
> >
> > All the details are in the release notes:
> > https://tapestry.apache.org/release-notes-581.html.
> >
> > As always, if you have questions, post them here in the Tapestry users
> > mailing list.
> >
> > Happy coding!
> >
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: ChecksumPath exception on unexistent assets

2022-03-28 Thread Ben Weidig
Hi Bob,

thanks for informing us about the exception on non-existant resources,
I've created an issue: https://issues.apache.org/jira/browse/TAP5-2713 and
will take a look.

Cheers,
Ben


On Mon, Mar 28, 2022 at 4:15 PM Roberto  wrote:

>
>
> Hi,
>
> It appears that the
> "org.apache.tapestry5.internal.services.assets.ChecksumPath" class throws
> exception
> like "String index out of range: -1" when trying to apply substring
> function on unexistent resource path.
> Maybe throwing an exception like "404 code error and resource not found"
> would be more convenient.
>
> kind regards
> bob
>
>
>


Re: Navigation to section of a page

2022-03-21 Thread Ben Weidig
Hi Chris,


you're right, the returned String is used directly as the page name and
doesn't support any additions.


IMO, there are two options how to implement such a feature:



   - Allow an anchor at the end of the String, and set it
   PageNameComponentEventResultProcessor
   - Use an intermediate type holding all the options available for a Link
   with a fluent API instead, e.g.
   LinkParams.page("index").anchor("footer").addQueryParameter("foo",
   "bar").activationContext(myContext1, myContext2)


The first option would be the easiest to implement because it only affects
a single class (if I'm correct).

But this approach leaves out the other features a customized Link could
provide.


The second option would require a new ComponentEventResultProcessor and the
holder type.


What do the others think?

Should this be pursued as an easier option for navigation?


If you need/want the feature now you could override the
PageNameComponentEventResultProcessor, it's contributed here:


https://github.com/apache/tapestry-5/blob/1578f4427fdf7e2113de8d5b4159ff40bbd2c5b6/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java#L1618


Cheers,

Ben



On Mon, Mar 21, 2022 at 5:35 AM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hi,
>
> Quick question: Tapestry is flexible when it comes to return types for
> page navigation.  "When a string is returned, it is expected to be the
> logical name of a page."  Although I've not tried it, presumably this
> means the likes of "Index#footer" isn't possible for navigating to a
> particular place in a page.  Is creating a 'Link' object along with
> setAnchor() the usual/only approach for achieving this from within a
> page's class?
>
> Thanks & regards,
>
> Chris.
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: New update site for anjlab/eclipse-tapestry5-plugin

2022-03-02 Thread Ben Weidig
Thank you Dmitry!

Maybe hosting it as a GitHub page would be an option?

https://www.lorenzobettini.it/2021/03/publishing-an-eclipse-p2-composite-repository-on-github-pages/

Or just as a raw repo?

https://microeducate.tech/is-it-possible-to-host-an-eclipse-update-site-on-github/

Or my company could host it, too.

Cheers
Ben



On Wed, Mar 2, 2022 at 4:23 AM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> Magnificent, thank you.
>
> I will consider in the coming months whether I can host the update site.
> Unfortunately, right now my team and I don't have the time to spend on it.
>
> > On 2 Mar 2022, at 10:55 am, Dmitry Gusev  wrote:
> >
> > Hi,
> >
> > Until we find a better way of hosting the update site we can use GitHub
> > releases:
> > https://github.com/anjlab/eclipse-tapestry5-plugin/releases
> >
> > I just published new version and updated installation instructions in
> > README:
> > https://github.com/anjlab/eclipse-tapestry5-plugin#install
> >
> > There's also a quick note on how to build the project locally should
> > you need it:
> > https://github.com/anjlab/eclipse-tapestry5-plugin#how-to-build
> >
> > Regards,
> > Dmitry
> >
> > On Tue, Mar 1, 2022 at 10:38 AM Ben Weidig  wrote:
> >
> >> Hi Geoff,
> >>
> >> AFAIK there's no alternative since bintray was shutdown.
> >> We've tried to get it up and running, but Eclipse Plugin stuff is
> weird...
> >>
> >> In theory you can copy it directly into a dropins folder, or put in in
> the
> >> correct location.
> >> But it hasn't worked for us reliably, or even at all, and most
> >> documentation is outdated.
> >>
> >> Only thing that worked was setting up Plugin-Development in Eclipse and
> >> running the plugin directly, because it gets installed that way. But I
> >> can't remember how much work was needed to get it up and running.
> >>
> >> Maybe we give it another try and create a how-to guide.
> >> Or even better, hosting it somewhere for easier usage.
> >>
> >> Cheers
> >> Ben
> >>
> >>
> >> On Tue, Mar 1, 2022 at 9:38 AM JumpStart <
> >> geoff.callender.jumpst...@gmail.com> wrote:
> >>
> >>> Does anyone know whether there is a new update site for the Eclipse
> >> plugin
> >>> anjlab/eclipse-tapestry5-plugin ?
> >>>
> >>> With the original site we're getting:
> >>>
> >>> HTTP Server 'Bad Gateway' :
> >>> https://dl.bintray.com/anjlab/eclipse-tapestry5-plugin/content.xml
> >>> HttpComponents connection error response code 502.
> >>>
> >>> I really loved this plugin, so it’s a shame to see the good work go to
> >>> waste.
> >>>
> >>> Cheers,
> >>>
> >>> Geoff
> >>>
> >>>
> >>>
> >>> -
> >>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> >>> For additional commands, e-mail: users-h...@tapestry.apache.org
> >>>
> >>>
> >>
> >
> >
> > --
> > Dmitry Gusev
> >
> > AnjLab Team
> > http://anjlab.com
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>

-- 

Netzgut GmbH

Kirchstr. 18
69115 Heidelberg

Telefon:
+49 6221 39298 53

Telefax:
+49 6221 39298 59

E-Mail:b...@netzgut.net

Handelsregister: Amtsgericht Mannheim, HRB 709833
Sitz der Gesellschaft: Heidelberg
Geschäftsführer: Felix Gonschorek, Benjamin Weidig
Ust-IdNr.: DE272871752


Re: New update site for anjlab/eclipse-tapestry5-plugin

2022-03-01 Thread Ben Weidig
Hi Geoff,

AFAIK there's no alternative since bintray was shutdown.
We've tried to get it up and running, but Eclipse Plugin stuff is weird...

In theory you can copy it directly into a dropins folder, or put in in the
correct location.
But it hasn't worked for us reliably, or even at all, and most
documentation is outdated.

Only thing that worked was setting up Plugin-Development in Eclipse and
running the plugin directly, because it gets installed that way. But I
can't remember how much work was needed to get it up and running.

Maybe we give it another try and create a how-to guide.
Or even better, hosting it somewhere for easier usage.

Cheers
Ben


On Tue, Mar 1, 2022 at 9:38 AM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> Does anyone know whether there is a new update site for the Eclipse plugin
> anjlab/eclipse-tapestry5-plugin ?
>
> With the original site we're getting:
>
> HTTP Server 'Bad Gateway' :
> https://dl.bintray.com/anjlab/eclipse-tapestry5-plugin/content.xml
> HttpComponents connection error response code 502.
>
> I really loved this plugin, so it’s a shame to see the good work go to
> waste.
>
> Cheers,
>
> Geoff
>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: LESS compiler in 5.6.4

2022-02-21 Thread Ben Weidig
Hi Geoff,

the CssCompressor is based on YUI Compressor
https://github.com/yui/yuicompressor  and has some minor issues...

We replaced it with a customized variant in our projects to reduce any
problems and improve performance, but maybe it's time to update/optimize it
in Tapestry, too.
Even though I would prefer such tasks to be done by a dependency, it seems
it won't be updated by Yahoo anytime soon.
And I've checked the available CSS-related solutions for Java (although I
was looking for vendor-prefixing for our SCSS support), there's not much
available that's this simple, working, and up-to-date.

I've created an issue for updating/optimizing it
https://issues.apache.org/jira/browse/TAP5-2708

Cheers
Ben


On Mon, Feb 21, 2022 at 9:28 AM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> Ah, it’s looking like CssCompressor is the culprit.
>
> > On 21 Feb 2022, at 3:29 pm, JumpStart <
> geoff.callender.jumpst...@gmail.com> wrote:
> >
> > Tapestry 5.6.4 uses the same less4j-1.12.0.jar as Tapestry 5.4.3, but
> I’m getting a strange output problem.
> >
> > 5.4.3 outputs this: height: calc(100vh - env(safe-area-inset-top) -
> 44px);
> > 5.6.4 outputs this: height: calc(100vh - env(safe - area-inset-top) -
> 44px);
> >
> > The blanks in “safe - area” cause an error in the browser “unsupported
> property value”, so the height is not set.
> >
> > Has this been reported before? If it’s not less4j causing this, then
> where should I look?
> >
> > Cheers,
> >
> > Geoff
>
>


Re: Apache FOP integration

2022-01-27 Thread Ben Weidig
Hi Volker,

can't help with FOP, but we're using JasperReport.

With the HTML-to-PDF path it's often quite hard to get the layout right.
That's why Jasper uses its own WYSIWYG designer, which isn't the nicest
tool but it gets the job done.
You can include variables, link other Jasper-files, loop through stuff...

For  other PDF operations (e.g. merging) we use PDFBox.

Cheers,
Ben



On Thu, Jan 27, 2022 at 10:03 AM Numa Schmeder  wrote:

> Hello,
>
> I tried all solutions, and I finally use iText that converts an html file
> into PDF. You can tweak iText with specific css rules for page breaks etc..
> This solution is quicker and easier to have a nice look and feel than FOP.
>
>
>      Numa Schmederwww.dfacto.ch  <
> http://www.dfacto.ch/>
> n...@dfacto.ch    |   M +41 79 538 30 01
>
> DIGITAL STRATEGY   |   DESIGN   |   DEVELOPMENT
>
>
>
>
> > Le 27 janv. 2022 à 08:19, Volker Lamp  a écrit :
> >
> > Hello Tapestry users,
> >
> > Our Tapestry webapp needs to generate printable PDFs including user
> input. We are currently looking at using Apache FOP for that.
> >
> > Has anyone integrated FOP in their Tapestry webapp and perhaps a
> Tapestry module to share?
> >
> > Suggestions for other approaches are also welcome.
> >
> > Cheers,
> >
> > Volker
> > -
> > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> > For additional commands, e-mail: users-h...@tapestry.apache.org
> >
>
>


Re: Ressource Minimization - Ahead of time

2021-12-23 Thread Ben Weidig
Hello Stefan,

we had a thread recently about health checks and possible warmup techniques
on the mailing list:

http://mail-archives.apache.org/mod_mbox/tapestry-users/202111.mbox/%3c92ee40fb-cb4c-4a6d-8257-b8215a136...@gmail.com%3e

Dmitry shared some awesome code to warmup without needing to call pages
manually, see
http://mail-archives.apache.org/mod_mbox/tapestry-users/202111.mbox/%3cCA+v6cT9C4XmkSmp=2nfs_vobw30qwgvzurbaprefwww_do6...@mail.gmail.com%3e

Doing Resource-minification at build-/deploy-time is a whole other can of
worms...
The first thing that comes to mind is a Gradle task preparing the assets as
needed and Tapestry to load them directly on startup and fill it caches.
Both functionalities don't exist (yet).

Hope this helps as a starting point.

Cheers,
Ben


On Thu, Dec 23, 2021 at 2:43 PM Stefan Starke 
wrote:

> Hello,
>
> I am currently looking into the topic of minimizing resources like JS, CSS
> ahead of time and not before they are requested for the first time.
>
> I already know that the resource minimizations are cached on a per-locale
> base inside JavaScriptStackAssemblerImpl.
>
> Unfortunately I can not find a way on how to minimize all resources before
> a user first requests them.
>
> My current approach would is to call a Tapestry page that loops over all
> javascript resources and therefore triggers the minimization
> Something like
>
> @Inject
>
> private JavaScriptStackSource javaScriptStackSource;
>
>
> @Inject
>
> private JavaScriptStackPathConstructor javaScriptStackPathConstructor;
>
>
> /*
> *
>
> * Event Handlers
>
> */
>
>
> public void minimizeJS()
>
> {
>
> for (String stackName : javaScriptStackSource.getStackNames())
>
> {
>
>
>
> javaScriptStackPathConstructor.constructPathsForJavaScriptStack(stackName);
>
> }
>
>
> }
>
> But I do not really like this approach as it implies that somehow I have
> to open this URL to make the minimization ahead of time - and even worse I
> would need to do this on every machine in a clustered setup.
>
> So basically I am looking for a way to minimize the resources together
> with starting the server or even at build time if possible.
>
> Thanks for hints and advices!
> Stefan
>


Re: Page links returned as http, not https or relative

2021-12-19 Thread Ben Weidig
We use Jetty, too, either behind HAProxy (production) or Nginx (dev).

This is my local dev nginx setup, with the domain mapped to 127.0.0.1 via
/etc/hosts

map $http_x_forwarded_proto $xscheme {
default $scheme;
https https;
}

set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

server {
listen 80;
server_name my.awesome-domain.com;

return 301 https://$host$request_uri;
}

server {
listen  443 ssl;
server_name my.awesome-domain.com;

ssl_certificate /Users/ben/.ssl/fullchain.pem;
ssl_certificate_key /Users/ben/.ssl/privkey.pem;

location / {
proxy_pass  http://127.0.0.1:8080;
proxy_set_headerHost $host;
proxy_set_headerX-Real-IP $remote_addr;
proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_headerX-Forwarded-Proto $scheme;
proxy_read_timeout  1h;
}
}



On Sun, Dec 19, 2021 at 12:09 PM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> Thank you Ben, you are absolutely right.
>
> In production, our AWS ALB (application load balancer) terminates HTTPS
> but automatically adds the X-Forwarded-Proto header, which forwards “https”
> or whatever the protocol was, and Wildfly respects it if you make the
> configuration changes described here:
> https://wjw465150.gitbooks.io/keycloak-documentation/content/server_installation/topics/clustering/load-balancer.html
> . Redirects of relative URLs now get turned into absolute URLs with “https”
> as the protocol.
>
> For my dev environment I use Jetty, often behind nginx with nginx
> terminating HTTPS. I’ll pass on the solution for that when I find one.
>
> > On 19 Dec 2021, at 4:35 pm, Ben Weidig  wrote:
> >
> > Hi Geoff,
> >
> > I can't reproduce the behavior in our setup, redirecting with relative
> URLs
> > while HTTPS works fine.
> >
> > Which Servlet Container are you using?
> > AFAIK it's the responsibility of the container to do the right thing and
> > how to handle relative URLs from sendRedirect.
> >
> > What's in the "Location" header of the response?
> > Still a relative URL, or already the HTTP version?
> >
> > Cheers,
> > Ben
> >
> >
> > On Sun, Dec 19, 2021 at 5:59 AM JumpStart <
> > geoff.callender.jumpst...@gmail.com> wrote:
> >
> >> I forgot to mention that HTTPS terminates at the load balancer. The app
> >> server sees just AJP or HTTP.
> >>
> >>> On 19 Dec 2021, at 12:10 pm, JumpStart <
> >> geoff.callender.jumpst...@gmail.com> wrote:
> >>>
> >>> Hi all,
> >>>
> >>> At long last I’ve moved redirection of HTTP to HTTPS from the app to
> the
> >> infrastructure, and set tapestry.secure-enabled <
> >> https://tapestry.apache.org/configuration.html>=false as recommended in
> >> https://tapestry.apache.org/https.html <
> >> https://tapestry.apache.org/https.html> . But now I’m hitting an
> age-old
> >> issue: page links are returning absolute URIs with “http” protocol. For
> >> example:
> >>>
> >>>  Link pageDeniedLink =
> >> pageRenderLinkSource.createPageRenderLinkWithContext(PageDenied.class,
> >>>  parameters.getLogicalPageName());
> >>>  response.sendRedirect(pageDeniedLink);
> >>>  break;
> >>>
> >>> pageDeniedLink is a relative address, but it seems to be converted to
> an
> >> absolute address with “http://“ by the time it gets back to the
> browser.
> >>>
> >>> This appears to have been an issue for a long time, but must have been
> >> solved, so is there a config change I need to make?
> >>>
> >>> From
> >>
> https://users.tapestry.apache.narkive.com/dapo2zzk/url-writing-problem-with-production-mode-true
> >> <
> >>
> https://users.tapestry.apache.narkive.com/dapo2zzk/url-writing-problem-with-production-mode-true
> >
> >> :
> >>>
> >>> "To be clear, it's not an HTTP/HTTPS problem I encountered, it was a
> >>> relative/absolute URL problem. With it off, the URLs were relative and
> >>> happy under HTTPS, with it on, the URLs were then set to absolute and
> >>> used HTTP.”
> >>>
> >>> Cheers,
> >>>
> >>> Geoff
> >>
> >>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Page links returned as http, not https or relative

2021-12-19 Thread Ben Weidig
Hi Geoff,

I can't reproduce the behavior in our setup, redirecting with relative URLs
while HTTPS works fine.

Which Servlet Container are you using?
AFAIK it's the responsibility of the container to do the right thing and
how to handle relative URLs from sendRedirect.

What's in the "Location" header of the response?
Still a relative URL, or already the HTTP version?

Cheers,
Ben


On Sun, Dec 19, 2021 at 5:59 AM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> I forgot to mention that HTTPS terminates at the load balancer. The app
> server sees just AJP or HTTP.
>
> > On 19 Dec 2021, at 12:10 pm, JumpStart <
> geoff.callender.jumpst...@gmail.com> wrote:
> >
> > Hi all,
> >
> > At long last I’ve moved redirection of HTTP to HTTPS from the app to the
> infrastructure, and set tapestry.secure-enabled <
> https://tapestry.apache.org/configuration.html>=false as recommended in
> https://tapestry.apache.org/https.html <
> https://tapestry.apache.org/https.html> . But now I’m hitting an age-old
> issue: page links are returning absolute URIs with “http” protocol. For
> example:
> >
> >   Link pageDeniedLink =
> pageRenderLinkSource.createPageRenderLinkWithContext(PageDenied.class,
> >   parameters.getLogicalPageName());
> >   response.sendRedirect(pageDeniedLink);
> >   break;
> >
> > pageDeniedLink is a relative address, but it seems to be converted to an
> absolute address with “http://“ by the time it gets back to the browser.
> >
> > This appears to have been an issue for a long time, but must have been
> solved, so is there a config change I need to make?
> >
> > From
> https://users.tapestry.apache.narkive.com/dapo2zzk/url-writing-problem-with-production-mode-true
> <
> https://users.tapestry.apache.narkive.com/dapo2zzk/url-writing-problem-with-production-mode-true>
> :
> >
> > "To be clear, it's not an HTTP/HTTPS problem I encountered, it was a
> > relative/absolute URL problem. With it off, the URLs were relative and
> > happy under HTTPS, with it on, the URLs were then set to absolute and
> > used HTTP.”
> >
> > Cheers,
> >
> > Geoff
>
>


Re: Best practice for health check URL?

2021-11-30 Thread Ben Weidig
Hi Geoff,

we have a multi-tenant/-domain multi-language site that required pre-heated
servers after deployment, so we created a WarmupTaskRunner to run at
startup, which gets contributed different kinds of tasks.
They can either be blocking or just run in the background, depending on
what they do (e.g., pre-heating caches/assets, ensuring indices in MongoDB
are set in dynamic collections, ...).

In our case, we just call the index pages for all relevant domains with
Apache HttpClient instead of creating the pages and components in Tapestry
itself.
But Dmitry's way is more thoroughly than our method.

The WarmupTaskRunner is combined with the health checks for HAProxy.
An HttpServletFilter checks for things like "warmup finished" by asking the
WarmupTaskRunner, and "mysql connection pool available", "mongodb
available", etc., and returns an appropriate HTTP status code to HAProxy.
If not 200 is returned, HAProxy takes the server out of rotation.

Cheers,
Ben


On Tue, Nov 30, 2021 at 2:41 AM JumpStart <
geoff.callender.jumpst...@gmail.com> wrote:

> Hi Dmitry,
>
> That is spectacularly helpful!
>
> We’re about to write a headless smoke test anyway that will visit every
> page. Do you see any downside to using that to do the warmup?
>
> Where do you keep your shared “warmup in progress” flag so that it is
> rapidly accessible on every health check request?
>
> Cheers,
>
> Geoff
>
> > On 30 Nov 2021, at 6:35 am, Dmitry Gusev  wrote:
> >
> > Hi Geoff,
> >
> > I don't think there's a simpler way, we're doing something similar.
> >
> > We created a REST endpoint with tynamo-resteasy which is effectively a
> load
> > balancer health check.
> > On the first hit it starts the warmup process on the same request,
> > following requests return an error instantly if the initial warmup
> routine
> > is still in progress.
> >
> > Our warmup logic is heavily based on tapestry internals & reflection, in
> > conjunction with eager loading services as described here:
> > https://gist.github.com/dmitrygusev/5562739
> >
> > Warmup logic is a bit complicated, it's trying to:
> > - "touch" each page using ComponentClassResolver.getPageNames()
> > - recursively for each component with mixins on a page starting from root
> > component,
> >> find imported assets via reflection (fields with names starting as
> > `importedAssets_`)
> >> stream each asset via `StreamableResourceSource` into no-op consumer
> > - find JS modules with `ModuleManager` and stream through no-op consumer
> > - every JS stack returned from `JavaScriptStackSource` assemble with
> > `JavaScriptStackAssembler` and stream through no-op consumer
> > - repeat above for each locale/axis
> >
> > Entire process usually takes 3-5 minute in our setup.
> > After it's done we return 200 to the load balancer and the first real
> > request is handled with hot caches.
> >
> > Hope this helps,
> > Dmitry
> >
> > On Mon, Nov 29, 2021 at 9:53 PM JumpStart <
> > geoff.callender.jumpst...@gmail.com> wrote:
> >
> >> Any suggestions on best ways to write a “health check” page to be called
> >> by load balancers?
> >>
> >> My app is getting big, and the traffic is big. If the app fails
> (hopefully
> >> never, but it’s a JVM) and the traffic is heavy enough, startup never
> seems
> >> to complete - every request times out, the app log goes quiet, and CPU
> goes
> >> to 100%. It appears to be due to race conditions possibly involving
> asset
> >> compression, minimising, and first time into the pages.
> >>
> >> I’m considering having a startup service crawl every page, in every
> >> language, in every skinning, before setting a singleton flag that the
> >> health check page will read to determine whether the app is ready to
> >> receive traffic.
> >>
> >> Is there a simpler way?
> >>
> >> Geoff
> >> -
> >> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> >> For additional commands, e-mail: users-h...@tapestry.apache.org
> >>
> >>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: File downloading in Tapestry

2021-11-15 Thread Ben Weidig
Hi Christopher,

not sure what the OutputStreamResponse is, it's not a part of Tapestry.
But we use a similar approach using Tapestry's StreamResponse interface.

We have a shared AbstractStreamResponse with dedicated subclasses for
File/byte[]/JSONObject etc. to simplify the needed code.
Our code is also quite "old", but I'm not aware of a better way.

public abstract class AbstractStreamResponse implements StreamResponse {

private final intsize;
private final String mimeType;
private final String filename;

public AbstractStreamResponse(String mimeType, int size, String
filename) {
super();
this.mimeType = mimeType;
this.size = size;
this.filename = filename;
}

public AbstractStreamResponse(String mimeType, int size) {
this(mimeType, size, null);
}

public AbstractStreamResponse(String mimeType) {
this(mimeType, 0, null);
}

public AbstractStreamResponse(String mimeType, String filename) {
this(mimeType, 0, filename);
}

@Override
public String getContentType() {
return this.mimeType;
}

@Override
public void prepareResponse(Response response) {
if (StringUtils.isNotBlank(this.filename)) {
String contentDisposition = String.format("attachment;
filename=\"%s\"", this.filename);
response.setHeader("Content-Disposition", contentDisposition);
}

if (this.size > 0) {
response.setContentLength(this.size);
}
}
}


The subclass for sending a File:

public class FileStreamResponse extends AbstractStreamResponse {

private final File file;

public FileStreamResponse(File file, String mimeType) {
super(mimeType, (int) file.length(), file.getName());
this.file = file;
}

@Override
public InputStream getStream() throws IOException {
return new FileInputStream(this.file);
}
}


The browser decides "download or display" with the help of the
"Content-Disposition" header:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
It isn't aware what Tapestry is actually sending back, it's all "just" an
HTTP Response for it.
Client settings might influence the decision, too.

Cheers,
Ben


On Mon, Nov 15, 2021 at 2:28 PM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hi all,
>
> Inserting a simple  type link in
> a Tapestry template so visitors can download a PDF is straightforward
> enough.
>
> I'd like to shift this to inside the controller, however, so that some
> code for analytical purposes can be added.
>
> A quick Google search revealed the code example below, from around seven
> years ago.  Just wondering whether this is still the right approach.
> Also, it's not clear how browsers might treat this 'stream response' -
> download or display?
>
> Happy to see any better approaches.
>
> Regards,
>
> Chris.
>
>
> public Object onBrochure(){
>  final File getFile();
>  final OutputStreamResponse response = new OutputStreamResponse() {
>
>  public String getContentType() {
>  return "application/pdf";
>  }
>
>  public void prepareResponse(Response response) {
>  response.setHeader ("Content-Disposition", "attachment;
> filename=\"" + file.getName() + "\"");
>  }
>
>  @Override
>  public void writeToStream(OutputStream out) throws IOException {
>  try {
>  InputStream in = new FileInputStream(file);
>  IOUtils.copy(in,out);
>  in.close();
>  } catch (Exception e) {
>  throw new RuntimeException(e);
>  }
>  }
>  };
>  return response;
> }
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Coercion error for JSONObject

2021-10-05 Thread Ben Weidig
Hi Adriaan,

we're using Ajax/JSONObject, too, but haven't seen such problems so far.
But I'm sure it's highly dependent on the context, and concurrent requests
count.

For your problem, if you can't switch out the underlying data structure,
you might get around it by writing a custom type coercer for
JSONObject-->String with a custom toString() / print() method.
The only problem is that JSONObject is a final class, and print-related
stuff is package-scoped.
So you would need to copy/adapt all the related code into a utility able to
convert a JSONObject to a String and contribute a type coercer using it.

Another option would be a custom tapestry-json version by vendoring the
whole tapestry-json code into your project and adapt it to your needs.

Cheers,
Ben

On Tue, Oct 5, 2021 at 8:09 PM Adriaan Joubert  wrote:

> Hi Ben,
>
> thanks for the reply! No, the json object is not stored in the session, but
> it does traverse a lot of different components. The most likely cause seems
> to be from separate threads that we use to speed up data loading during a
> request, but we have not been able to pin it down - naturally we have not
> been able to reproduce this problem.
>
> I have been considering using a different, thread safe data structure, but
> it is a lot of code to change. And we see this error only once every 2-3
> weeks. We will have to spend more time trying to understand where this
> could happen.
>
> The reason I mentioned it here is that json is used a lot in ajax requests
> nowadays, so this seems like a problem that could arise in other situations
> as well.
>
> All the best,
>
> Adriaan
>
> On Tue, 5 Oct 2021 at 18:48, Ben Weidig  wrote:
>
> > Hi,
> >
> > is the JSONObject in the Session and do you have Session locking
> disabled?
> > See
> >
> >
> https://tapestry.apache.org/session-storage.html#SessionStorage-SessionLocking
> >
> > Changing the print-loop to check if keys still exist would just hide the
> > underlying problem: using a data-structure concurrently that isn't
> designed
> > to be used in a concurrent environment.
> >
> > Maybe you could use another type of thread-safe data structure in your
> > session, and convert it to a JSONObject before sending it back to the
> > client?
> >
> > Cheers,
> > Ben
> >
> >
> > On Tue, Oct 5, 2021 at 2:50 PM Adriaan Joubert 
> > wrote:
> >
> > > Hi,
> > >
> > > we intermittently see coercion errors for JSONObject - which we use
> > > frequently for ajax context information.
> > >
> > > The relevant bit of stack trace is
> > >
> > > - Caused by: java.util.ConcurrentModificationException
> > > -   at
> > >
> >
> java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719)
> > > -   at
> > >
> >
> java.base/java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:741)
> > > -   at
> > org.apache.tapestry5.json.JSONObject.print(JSONObject.java:805)
> > > -   at
> > >
> org.apache.tapestry5.json.JSONCollection.toString(JSONCollection.java:46)
> > > -   at
> > >
> >
> org.apache.tapestry5.commons.internal.BasicTypeCoercions$1.coerce(BasicTypeCoercions.java:69)
> > > -   at
> > >
> >
> org.apache.tapestry5.commons.internal.BasicTypeCoercions$1.coerce(BasicTypeCoercions.java:65)
> > > -   at
> > >
> >
> org.apache.tapestry5.commons.services.CoercionTuple$CoercionWrapper.coerce(CoercionTuple.java:57)
> > >
> > >
> > > Overlapping calls mean the json object is modified in one place while
> it
> > is
> > > written elsewhere - as the objects themselves are not thread safe, it
> is
> > > quite messy to protect all possible writes.
> > >
> > > Copying the keys before the print loop, with a check that the value
> still
> > > exists when printing, would narrow the window for this to happen
> > > considerably. We could not think of any better solutions to solve this
> > > problem, but any suggestions are welcome.
> > >
> > > Cheers,
> > >
> > > Adriaan
> > >
> >
>


Re: Coercion error for JSONObject

2021-10-05 Thread Ben Weidig
Hi,

is the JSONObject in the Session and do you have Session locking disabled?
See
https://tapestry.apache.org/session-storage.html#SessionStorage-SessionLocking

Changing the print-loop to check if keys still exist would just hide the
underlying problem: using a data-structure concurrently that isn't designed
to be used in a concurrent environment.

Maybe you could use another type of thread-safe data structure in your
session, and convert it to a JSONObject before sending it back to the
client?

Cheers,
Ben


On Tue, Oct 5, 2021 at 2:50 PM Adriaan Joubert  wrote:

> Hi,
>
> we intermittently see coercion errors for JSONObject - which we use
> frequently for ajax context information.
>
> The relevant bit of stack trace is
>
> - Caused by: java.util.ConcurrentModificationException
> -   at
> java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719)
> -   at
> java.base/java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:741)
> -   at org.apache.tapestry5.json.JSONObject.print(JSONObject.java:805)
> -   at
> org.apache.tapestry5.json.JSONCollection.toString(JSONCollection.java:46)
> -   at
> org.apache.tapestry5.commons.internal.BasicTypeCoercions$1.coerce(BasicTypeCoercions.java:69)
> -   at
> org.apache.tapestry5.commons.internal.BasicTypeCoercions$1.coerce(BasicTypeCoercions.java:65)
> -   at
> org.apache.tapestry5.commons.services.CoercionTuple$CoercionWrapper.coerce(CoercionTuple.java:57)
>
>
> Overlapping calls mean the json object is modified in one place while it is
> written elsewhere - as the objects themselves are not thread safe, it is
> quite messy to protect all possible writes.
>
> Copying the keys before the print loop, with a check that the value still
> exists when printing, would narrow the window for this to happen
> considerably. We could not think of any better solutions to solve this
> problem, but any suggestions are welcome.
>
> Cheers,
>
> Adriaan
>


Re: Tapestry and Typescript

2021-09-02 Thread Ben Weidig
Hi Jonathan,

just FYI, I've created an issue for updating Rhino and adding a possibility
to configure it.

https://issues.apache.org/jira/browse/TAP5-2691

Cheers,
Ben

On Thu, Sep 2, 2021 at 10:26 AM Jonathan Luke Shearman
 wrote:

> Hi Ben,
>
> Thanks for your reply and ideas!
> I did try updating Rhino to the latest version - but it didn't fix the
> issue
> directly, I think to take advantage of the newer features an ES6 version
> flag has to be set, and I haven't had time to try and override that in the
> tapestry implementation yet.
> I'll try out the ResourceTransformer option, maybe that will be easier to
> maintain.
>
> Cheers,
> Jonathan
>
> -Original Message-
> From: Ben Weidig 
> Sent: Wednesday, 1 September 2021 10:52 AM
> To: Tapestry users 
> Subject: Re: Tapestry and Typescript
>
> Hi Jonathan,
>
> I haven't worked with TS in 5.7.2 so far, but I tried to look into it.
>
> The two issues on Rhino's Github are not very helpful...
>
> https://github.com/mozilla/rhino/issues/658 (solved itself somehow)
> https://github.com/mozilla/rhino/issues/430 (solved with newer Rhino
> version)
>
> Tapestry uses an older Rhino version, have you tried to using the latest
> one?
> Not sure if it's compatible though without changes in Tapestry itself,
> though.
>
> Another option would be writing your own ResourceTransformer to compile
> Typescript yourself using a local TSC instead of typescript.js with Rhino.
>
> Maybe someone else has an idea how to integrate Webpack, our JS-setup is
> rather simple.
>
> Cheers,
> Ben
>
>
> On Wed, Sep 1, 2021 at 9:01 AM Jonathan Luke Shearman
>  wrote:
>
> > Hello,
> >
> >
> >
> > First post here and I have a feeling it may not be Tapestry related
> > but wanted to reach out here just in case!
> >
> >
> >
> > I recently joined a project that has been maintained for a few years
> > and is currently using Tapestry 5.7.2
> >
> > Tasked with upgrading some frontend components, I wanted to use
> > typescript and got it running using the setup in tapestry-webresources
> > using the Rhino library.
> >
> > This worked great on my machine and on the web server, but in the last
> > week some colleagues needed to work on the same code and discovered
> > that typescript wasn’t getting transpiled on their local setup.
> >
> >
> >
> > Rhino complains about a “missing name after the . operator” but
> > references the typescript.js file at line 1467 (exception at the end
> > of this message) – ie the file used to transpile the other .ts files
> > as far as I’ve understood.
> > ( Please correct me if I’m mistaken)
> >
> > I’ve tested this on 8 different colleague machines with only a 50%
> > success rate unfortunately. We are all running what should be
> > identical setups, so it’s quite confusing why some don’t work.
> >
> > It doesn’t seem to depend on node or tsc command line tools, and
> >
> >
> >
> > Looking into it, I’m thinking it’s some sort of file reading issue –
> > there are similar issues on Rhino’s github but unresolved there too.
> >
> > A suggested fix was to change every someObject.delete to
> > someObject[‘delete’] but I don’t think editing typescript.js is the
> > right solution here.
> >
> > The error comes from ‘delete’ being a reserved word in javascript, and
> > so this is most probably an issue with Rhino’s javascript parser.
> >
> > I wondered if anyone has ever come across this issue before or might
> > have some better ideas on what else to check?
> >
> >
> >
> > And just as more general question – can anyone recommend a better
> > setup for handling typescript in Tapestry? My next goal is to bring in
> > npm packages and potentially work on replacing requireJS with
> > something like webpack, but I’ve seen on previous threads here that
> > there’s been limited success?
> >
> > I’ve been considering running npm scripts at Tapestry build time to
> > ‘pre-compile’ all the frontend code in a separate directory and then
> > hand it back to requireJS by dumping the javascript files into
> > /modules.. but that feels like overkill.
> >
> >
> >
> > I’d appreciate any ideas people might have, happy to test anything out
> > at this point.
> >
> > Cheers,
> >
> > Jonathan
> >
> >
> >
> >
> >
> > Original Exception:
> >
> > Exception: org.apache.tapestry5.ioc.internal.OperationException
> >
> >Message: missing name after . operator
>

Re: Tapestry and Typescript

2021-09-01 Thread Ben Weidig
Hi Jonathan,

I haven't worked with TS in 5.7.2 so far, but I tried to look into it.

The two issues on Rhino's Github are not very helpful...

https://github.com/mozilla/rhino/issues/658 (solved itself somehow)
https://github.com/mozilla/rhino/issues/430 (solved with newer Rhino
version)

Tapestry uses an older Rhino version, have you tried to using the latest
one?
Not sure if it's compatible though without changes in Tapestry itself,
though.

Another option would be writing your own ResourceTransformer to compile
Typescript yourself using a local TSC instead of typescript.js with Rhino.

Maybe someone else has an idea how to integrate Webpack, our JS-setup is
rather simple.

Cheers,
Ben


On Wed, Sep 1, 2021 at 9:01 AM Jonathan Luke Shearman
 wrote:

> Hello,
>
>
>
> First post here and I have a feeling it may not be Tapestry related but
> wanted to reach out here just in case!
>
>
>
> I recently joined a project that has been maintained for a few years and
> is
> currently using Tapestry 5.7.2
>
> Tasked with upgrading some frontend components, I wanted to use typescript
> and got it running using the setup in tapestry-webresources using the
> Rhino
> library.
>
> This worked great on my machine and on the web server, but in the last
> week
> some colleagues needed to work on the same code and discovered that
> typescript wasn’t getting transpiled on their local setup.
>
>
>
> Rhino complains about a “missing name after the . operator” but references
> the typescript.js file at line 1467 (exception at the end of this message)
> –
> ie the file used to transpile the other .ts files as far as I’ve
> understood.
> ( Please correct me if I’m mistaken)
>
> I’ve tested this on 8 different colleague machines with only a 50% success
> rate unfortunately. We are all running what should be identical setups, so
> it’s quite confusing why some don’t work.
>
> It doesn’t seem to depend on node or tsc command line tools, and
>
>
>
> Looking into it, I’m thinking it’s some sort of file reading issue – there
> are similar issues on Rhino’s github but unresolved there too.
>
> A suggested fix was to change every someObject.delete to
> someObject[‘delete’]
> but I don’t think editing typescript.js is the right solution here.
>
> The error comes from ‘delete’ being a reserved word in javascript, and so
> this is most probably an issue with Rhino’s javascript parser.
>
> I wondered if anyone has ever come across this issue before or might have
> some better ideas on what else to check?
>
>
>
> And just as more general question – can anyone recommend a better setup
> for
> handling typescript in Tapestry? My next goal is to bring in npm packages
> and potentially work on replacing requireJS with something like webpack,
> but
> I’ve seen on previous threads here that there’s been limited success?
>
> I’ve been considering running npm scripts at Tapestry build time to
> ‘pre-compile’ all the frontend code in a separate directory and then hand
> it
> back to requireJS by dumping the javascript files into /modules.. but that
> feels like overkill.
>
>
>
> I’d appreciate any ideas people might have, happy to test anything out at
> this point.
>
> Cheers,
>
> Jonathan
>
>
>
>
>
> Original Exception:
>
> Exception: org.apache.tapestry5.ioc.internal.OperationException
>
>Message: missing name after . operator
> (classpath:org/apache/tapestry5/webresources/internal/typescript.js#1467)
>
>  trace: Streaming compressed module custom-file
>
> Streaming classpath:META-INF/modules/custom-file.ts
> (compressed)
>
> Compiling classpath:META-INF/modules/custom-file.ts
> from
> TS to JavaScript
>
> Creating Rhino executor for source(s)
> classpath:org/apache/tapestry5/webresources/internal/typescript.js,
> classpath:org/apache/tapestry5/webresources/internal/invoke-typescript.js.
>
> Loading script
> classpath:org/apache/tapestry5/webresources/internal/typescript.js.
>
> Exception: org.mozilla.javascript.EvaluatorException
>
>Message: missing name after . operator
> (classpath:org/apache/tapestry5/webresources/internal/typescript.js#1467)
>
>   columnNumber: 37
>
> lineNumber: 1467
>
> lineSource: class_1.prototype.delete = function (key) {
>
>   scriptStackTrace:
>
> sourceName:
> classpath:org/apache/tapestry5/webresources/internal/typescript.js
>
>


Re: Integrating Agrest in Tapestry app

2021-08-06 Thread Ben Weidig
Hi Tim,

your code looks fine to me, but it seems like this is a limitation of
tapestry-resteasy.

The project wraps the configuration of RESTEasy to make it easier to use
with Tapestry.
The method
https://github.com/tynamo/tapestry-resteasy/blob/0111a37e842a67e49b47752de85d738676c179e9/src/main/java/org/tynamo/resteasy/ResteasyRequestFilter.java#L138
goes over the contributed instances and classes, but it doesn't support all
the available types RESTEasy has to offer, so it throws the exception
you're getting.
Only Resources and Providers are supported, but AgRuntime is a "Feature"
type.

The only option I see (without tapestry-resteasy adding it) is overriding
the ResteasyRequestFilter and extending the conditions for provider
detection to allow instances of Feature, too.
Features are internally registered like providers if I saw it correctly in
the RESTEasy code.

I've only read the tapestry-resteasy/RESTEasy source code and not tested it
with a running project, so it might not be that easy.


On Fri, Aug 6, 2021 at 1:52 PM D Tim Cummings 
wrote:

> Hi Ben
>
> I followed your suggestions and was able to get rest working with
> tapestry-resteasy without using persistence. However when I added agrest
> tapestry resteasy threw an exception unknown class type:
> io.agrest.runtime.AgRuntime. My code is as follows. I am using a simple
> data model from https://github.com/agrestio/agrest-bookstore-example .
> Could you please check I have implemented your suggestions correctly.
>
>  - add tapestry-resteasy to your project
>
> 
> org.tynamo
> tapestry-resteasy
> 0.7.0
> 
>
>  - write a service to setup the AgRuntime
>
> public class AgrestServiceImpl implements AgrestService {
>   public AgrestServiceImpl() {
> ServerRuntime runtime =
> ServerRuntime.builder().addConfig("cayenne-project.xml").build();
> AgCayenneModule cayenneExt = AgCayenneBuilder.build(runtime);
> agRuntime = new AgBuilder().module(cayenneExt).build();
>   }
>   private AgRuntime agRuntime;
>   public AgRuntime agRuntime() {
> return agRuntime;
>   }
> }
>
>
>  - write a simple resource with a single @GET method using Agrest
>
> @Path("/category")
> @Produces(MediaType.APPLICATION_JSON)
> public class CategoryResource {
>   @Context
>   private Configuration config;
>   @GET
>   public DataResponse getAll(@Context UriInfo uriInfo) {
>   return Ag.select(Category.class, config).uri(uriInfo).get();
>   }
> }
>
>
>  - contribute the AgRuntime and resource like in my previous mail.
>
> @Contribute(javax.ws.rs.core.Application.class)
> public static void configureRestProviders(Configuration
> singletons, AgrestService svcAgrest) {
> singletons.add(svcAgrest.agRuntime());
> singletons.addInstance(CategoryResource.class);
> }
>
>
>  - test it with your browser or curl
>
> http://localhost:8089/tapestry-agrest/rest/category
>
> java.lang.RuntimeException: Exception constructing service
> 'ResteasyRequestFilter': Error invoking constructor public
>
> org.tynamo.resteasy.ResteasyRequestFilter(java.lang.String,org.slf4j.Logger,org.apache.tapestry5.http.services.ApplicationGlobals,javax.ws.rs.core.Application,org.apache.tapestry5.ioc.services.SymbolSource,boolean,org.apache.tapestry5.ioc.services.UpdateListenerHub,long,long,boolean)
>  throws javax.servlet.ServletException: Application.getSingletons()
> returned unknown class type: io.agrest.runtime.AgRuntime
>
>
> On 3/8/21 22:06, Ben Weidig wrote:
> > tapestry-resteasy is just bringing RESTEasy to Tapestry.
> > There's no dependency to JPA/Hibernate.
> > Do you mean the PersistenceService in the example on the page under "Code
> > your singleton resource"?
> > That's not a necessity, just an example for a Rest resource.
> > In your case, you would use Agrest instead.
> >
> > You don't need to edit web.xml because tapestry-resteasy uses a Tapestry
> > HttpServletRequestFilter to piggyback Tapstry itself, instead of going
> > through the a custom servlet defined in the web.xml.
> > Everything that would be done in the web.xml is done with code instead.
> > This way, you don't need an extra Bridge to handle service injection.
> >
> >
> https://github.com/tynamo/tapestry-resteasy/blob/master/src/main/java/org/tynamo/resteasy/ResteasyRequestFilter.java
> >
> > The next steps for simple proof-of-concept would be something like this:
> >
> > - add tapestry-resteasy to your project
> > - write a service to setup the AgRuntime
> > - write a simple resource with a single @GET method using Agrest
> > - contribute the AgRuntime and resource like in my previous mail.
> > -

Re: Integrating Agrest in Tapestry app

2021-08-03 Thread Ben Weidig
tapestry-resteasy is just bringing RESTEasy to Tapestry.
There's no dependency to JPA/Hibernate.
Do you mean the PersistenceService in the example on the page under "Code
your singleton resource"?
That's not a necessity, just an example for a Rest resource.
In your case, you would use Agrest instead.

You don't need to edit web.xml because tapestry-resteasy uses a Tapestry
HttpServletRequestFilter to piggyback Tapstry itself, instead of going
through the a custom servlet defined in the web.xml.
Everything that would be done in the web.xml is done with code instead.
This way, you don't need an extra Bridge to handle service injection.

https://github.com/tynamo/tapestry-resteasy/blob/master/src/main/java/org/tynamo/resteasy/ResteasyRequestFilter.java

The next steps for simple proof-of-concept would be something like this:

- add tapestry-resteasy to your project
- write a service to setup the AgRuntime
- write a simple resource with a single @GET method using Agrest
- contribute the AgRuntime and resource like in my previous mail.
- test it with your browser or curl

Hope this helps!

On Tue, Aug 3, 2021 at 1:12 PM D Tim Cummings 
wrote:

> Thanks for this very detailed reply. I will work through what you have
> suggested and see how I go.
>
> I had a look at tapestry-resteasy but it seems to rely on hibernate or
> jpa and I am using cayenne. I am not sure what is required for
> org.tynamo.services.PersistenceService. Also tapestry-resteasy says I
> don't need to edit web.xml.
>
> Another example I am following says I do need to edit web.xml.
> https://github.com/andrus/wowodc13 is an example for tapestry and
> cayenne and jersey 1.x rest. It seems to rely on a JerseyTapestryBridge
> [1] but the code looks specific to jersey 1.x and wouldn't work with
> jersey 2.x
>
> Cheers
>
> Tim
>
> [1]
>
> https://github.com/andrus/wowodc13/blob/master/site/src/main/java/demo/rest/jersey/JerseyTapestryBridge.java
>
> On 3/8/21 17:15, Ben Weidig wrote:
> > Hi Tim,
> >
> > full disclosure: I haven't used Cayenne or Agrest, but I checked out
> their
> > documentation.
> >
> > I don't think there's anything Tapestry-specific needed to get it up and
> > running except setting up Rest.
> > They say in their docs that you still have to write your JAX-RS endpoints
> > and do security yourself.
> >
> > For JAX-RS, there's tapestry-resteasy
> > https://www.tynamo.org/tapestry-resteasy+guide/
> > There are examples how to add Rest to Tapestry and register your
> resources.
> >
> > The AgRuntime should be contributable just like a Rest resource. RestEasy
> > treats many of its classes are contributable (Resources, Provider, etc.).
> > You could create a service to build it.
> >
> > @Contribute(javax.ws.rs.core.Application.class)
> > public static void configureRestProviders(Configuration
> singletons,
> > YourAgRuntimeBuilder builder) {
> > singletons.add(builder.build());
> > singletons.addInstance(YourCredentialsInterceptor.class);
> > singletons.addInstance(YourResource.class);
> > }
> >
> > For security, we use custom headers containing an API key/secret that are
> > validated by a javax.ws.rs.container.ContainerRequestFilter with
> > @Priority(Priorities.AUTHENTICATION) and
> > @Priority(Priorities.AUTHORIZATION) and plug in your security code.
> >
> > But as said before, I haven't tested it, and it just looks this way to me
> > at first glance.
> >
> > Cheers,
> > Ben
> >
> > On Tue, Aug 3, 2021 at 5:28 AM D Tim Cummings
> 
> > wrote:
> >
> >> Does anyone have experience integrating Agrest (https://agrest.io/)
> into
> >> a Tapestry app? My Tapestry app uses Cayenne ORM and it looks like
> >> Agrest works well with Cayenne to produce REST functionality. It would
> >> be helpful to see some sample code.
> >>
> >> Thanks in advance
> >>
> >> Tim
> >>
> >>
> >>
> >>
>
>


Re: Integrating Agrest in Tapestry app

2021-08-03 Thread Ben Weidig
Hi Tim,

full disclosure: I haven't used Cayenne or Agrest, but I checked out their
documentation.

I don't think there's anything Tapestry-specific needed to get it up and
running except setting up Rest.
They say in their docs that you still have to write your JAX-RS endpoints
and do security yourself.

For JAX-RS, there's tapestry-resteasy
https://www.tynamo.org/tapestry-resteasy+guide/
There are examples how to add Rest to Tapestry and register your resources.

The AgRuntime should be contributable just like a Rest resource. RestEasy
treats many of its classes are contributable (Resources, Provider, etc.).
You could create a service to build it.

@Contribute(javax.ws.rs.core.Application.class)
public static void configureRestProviders(Configuration singletons,
YourAgRuntimeBuilder builder) {
singletons.add(builder.build());
singletons.addInstance(YourCredentialsInterceptor.class);
singletons.addInstance(YourResource.class);
}

For security, we use custom headers containing an API key/secret that are
validated by a javax.ws.rs.container.ContainerRequestFilter with
@Priority(Priorities.AUTHENTICATION) and
@Priority(Priorities.AUTHORIZATION) and plug in your security code.

But as said before, I haven't tested it, and it just looks this way to me
at first glance.

Cheers,
Ben

On Tue, Aug 3, 2021 at 5:28 AM D Tim Cummings 
wrote:

> Does anyone have experience integrating Agrest (https://agrest.io/) into
> a Tapestry app? My Tapestry app uses Cayenne ORM and it looks like
> Agrest works well with Cayenne to produce REST functionality. It would
> be helpful to see some sample code.
>
> Thanks in advance
>
> Tim
>
>
>
>


Re: Upgrading to Tapestry 5.6.4

2021-05-07 Thread Ben Weidig
I've created an issue https://issues.apache.org/jira/browse/TAP5-2678 and
add the notice to the page.


On Fri, May 7, 2021 at 10:54 AM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hi Ben,
>
> You were 100% correct!  Adding the below dependencies to my POM fixed
> the issue.
>
> I really appreciate the quick response you gave.
>
> Perhaps Thiago or Bob might like to make mention of this on the Tapestry
> Upgrade page?
>
>  
>  
>  
>  com.sun.xml.bind
>  jaxb-core
>  2.3.0.1
>  
>  
>  javax.xml.bind
>  jaxb-api
>  2.3.1
>  
>  
>  com.sun.xml.bind
>  jaxb-impl
>  2.3.1
>  
>
> Regards,
>
> Chris.
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Upgrading to Tapestry 5.6.4

2021-05-07 Thread Ben Weidig
Hi Chris,

this looks to me like a Java 11 issue due to the removal of packages by the
Java itself.
With version 9, multiple packages were marked deprecated, and removed with
11.
The javax.xml.bind stuff is one of them, you need to add a dependency
manually.

https://crunchify.com/java-11-and-javax-xml-bind-jaxbcontext/

https://stackoverflow.com/questions/43574426/how-to-resolve-java-lang-noclassdeffounderror-javax-xml-bind-jaxbexception

Hope this helps!

Ben

On Fri, May 7, 2021 at 8:23 AM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hi team,
>
> I have moved to upgrade a Tapestry webapp from version 5.4.3 to version
> 5.6.4, after first checking the page below for known compatibility
> issues.
>
>
> https://cwiki.apache.org/confluence/display/TAPESTRY/Supported+Environments+and+Versions
>
> Reportedly, Tapestry 5.6.4 is compatible with...
>
>  Java 8-14 (my app was compiled on Oracle 1.8.0, deployed on OpenJDK
> 13.0.1)
>
>  Hibernate 5.1.0.Final (I updated the POM accordingly)
>
> However, when I deploy to Tomcat the app fails to launch (error output
> below).
>
> In case it matters, this app also has these dependencies...
>
>  
>  
>  org.hibernate
>  hibernate-c3p0
>  ${hibernate-release-version}
>  
>
>  
>  
>  org.slf4j
>  slf4j-log4j12
>  1.7.30
>  
>
> I'd appreciate it if someone could shine some light on what is
> presumably a compatibility issue.
>
> 07-05-2021 17:46:25 ERROR Registry:208 - Error invoking constructor
> public
> org.apache.tapestry5.internal.hibernate.HibernateSessionSourceImpl(org.slf4j.Logger,java.util.List):
>
> javax/xml/bind/JAXBException
> 07-05-2021 17:46:25 ERROR Registry:209 - Operations trace:
> 07-05-2021 17:46:25 ERROR Registry:218 - [ 1] Invoking startup method
> com.optomus.harbour.dal.DataModule.initialize().
> 07-05-2021 17:46:25 ERROR Registry:218 - [ 2] Instantiating service
> HibernateSessionManager implementation via
> org.apache.tapestry5.hibernate.modules.HibernateCoreModule.buildHibernateSessionManager(HibernateSessionSource,
>
> PerthreadManag
> er) (at HibernateCoreModule.java:96)
> 07-05-2021 17:46:25 ERROR Registry:218 - [ 3] Constructing service
> implementation via
> org.apache.tapestry5.hibernate.modules.HibernateCoreModule.buildHibernateSessionManager(HibernateSessionSource,
>
> PerthreadManager) (at HibernateCoreModu
> le.java:96)
> 07-05-2021 17:46:25 ERROR Registry:218 - [ 4] Realizing service
> HibernateSessionSource
> 07-05-2021 17:46:25 ERROR Registry:218 - [ 5] Instantiating service
> HibernateSessionSource implementation via
> org.apache.tapestry5.internal.hibernate.HibernateSessionSourceImpl(Logger,
> List) (at HibernateSessionSourceImpl.java:36) via or
> g.apache.tapestry5.hibernate.modules.HibernateCoreModule.bind(ServiceBinder)
>
> (at HibernateCoreModule.java:43)
> 07-05-2021 17:46:25 ERROR Registry:218 - [ 6] Invoking constructor
> org.apache.tapestry5.internal.hibernate.HibernateSessionSourceImpl(Logger,
> List) (at HibernateSessionSourceImpl.java:36) via
> org.apache.tapestry5.hibernate.modules.Hibern
> ateCoreModule.bind(ServiceBinder) (at HibernateCoreModule.java:43) (for
> service 'HibernateSessionSource')
> 07-05-2021 17:46:25 ERROR HibernateSessionSource:65 - Construction of
> service HibernateSessionSource failed: Error invoking constructor public
>
> org.apache.tapestry5.internal.hibernate.HibernateSessionSourceImpl(org.slf4j.Logger,java.util.
> List): javax/xml/bind/JAXBException
> org.apache.tapestry5.ioc.internal.OperationException: Error invoking
> constructor public
> org.apache.tapestry5.internal.hibernate.HibernateSessionSourceImpl(org.slf4j.Logger,java.util.List):
>
> javax/xml/bind/JAXBException
>  at
>
> org.apache.tapestry5.ioc.internal.OperationTrackerImpl.logAndRethrow(OperationTrackerImpl.java:186)
>  at
>
> org.apache.tapestry5.ioc.internal.OperationTrackerImpl.invoke(OperationTrackerImpl.java:90)
>  at
>
> org.apache.tapestry5.ioc.internal.PerThreadOperationTracker.invoke(PerThreadOperationTracker.java:72)
> ...
> Caused by: java.lang.RuntimeException: Error invoking constructor public
> org.apache.tapestry5.internal.hibernate.HibernateSessionSourceImpl(org.slf4j.Logger,java.util.List):
>
> javax/xml/bind/JAXBException
>  at
>
> org.apache.tapestry5.ioc.internal.util.ConstructorInvoker.invoke(ConstructorInvoker.java:59)
> ...
> Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
>  at
>
> org.hibernate.boot.spi.XmlMappingBinderAccess.(XmlMappingBinderAccess.java:43)
> ...
> Caused by: java.lang.ClassNotFoundException:
> javax.xml.bind.JAXBException
>  at
>
> org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1365)
> ...
> 07-05-2021 17:46:25 ERROR HibernateSessionSource:65 - Construction of
> service HibernateSessionSource failed: Error 

Re: Question about JSONObject in versions 5.6.2, 5.6.3. and 5.6.4

2021-04-20 Thread Ben Weidig
Hi,

it's a known problem with 5.6.2+ and JSONObject that came to light recently.

An updated version of tapestry-json improvements were introduced with
5.7.0, but got backported to 5.6.2.

JSONObject is now a full-fledged Map, which lead to a
signature change being introduced. It slipped through into the backport,
resulting in the NoSuchMethodError for any dependency being compiled with <
5.6.2.

Due to the generic-nature of Map and Java's type erasure, the old methods
can't be retro-fitted in an update.

The are the possible workarounds I can think of:

- Update the dependency to a newer version using 5.6.2+.

- Shade the dependency and make the changes yourself

- Stay on 5.6.1 until the dependency is updated


I'm in the process of updating the documentation/release notes, so it's
clearer what the problem is.

Ben

On Tue, Apr 20, 2021 at 12:30 AM Wilson Velez 
wrote:

> There is a weird behavior with the tags 5.6.2, 5.6.3. and 5.6.4, I don't
> know if this is expected.
>
> I'm having a problem trying to upgrade from 5.6.1. When I change the
> version to 5.6.2, 5.6.3. or 5.6.4
> the org.got5.tapestry5.jquery.utils.JQueryUtils#merge method throws the
> exception:
>
> java.lang.NoSuchMethodError
>
> org.apache.tapestry5.json.JSONObject.get(Ljava/lang/String;)Ljava/lang/Object;
>
> and clearly the method with that signature doesn't exist anymore, that's
> fine, I can understand that and probably I'm not going to be able to go
> beyond this point in the upgrade.
>
> However when I go to to
>
> https://github.com/apache/tapestry-5/blob/5.6.4/tapestry-json/src/main/java/org/apache/tapestry5/json/JSONObject.java
> to see the new source code I see comments referencing the 5.7 version.
>
> Is that expected being in the 5.6.x?
>


Re: [ANNOUNCEMENT] Tapestry 5.6.2 released

2021-04-07 Thread Ben Weidig
Hi!

even though I've mentioned the signature changes as a risk in the ticket,
it slipped my mind when it got merged into 5.6.x and not just 5.7.

There are 2 signature changes in JSONObject to match the Map interface:

* Object get(String name) -> Object get(Object name)
* JSONObject putAll(Map newProperties) -> void putAll(Map newProperties)

The first one could have been augmented with the previous one as
@Deprecated, but the second one wouldn't work due to type erasure, so it
would've been a breaking change either way.

If you like I could make the changes to the release notes, and maybe wrote
a few sentences about the JSON module. And I could update the Type Coercion
page with the new JSR310 coercers.
But I don't know how to edit the project page...

Ben


On Wed, Apr 7, 2021 at 11:43 PM Thiago H. de Paula Figueiredo <
thiag...@gmail.com> wrote:

> On Wed, Mar 31, 2021 at 1:40 PM Dmitry Gusev 
> wrote:
>
> > Hello,
> >
>
> Hello!
>
>
> > I'm upgrading one of our apps to latest 5.6.3 and found that this release
> > broke binary compatibility after tapestry-json improvements:
> >
> > https://issues.apache.org/jira/browse/TAP5-2640
> >
> > Libraries compiled with < 5.6.2 _and_ using JSONObject class,
> > namely JSONObject#get(String), will fail with NoSuchMethodError at
> runtime.
> >
>
> The changes are indeed mentioned in
> https://tapestry.apache.org/release-notes-562.html, but I didn't know they
> would have binary compatibility broken. I'm sorry for that.
>
>
> >
> > Such libraries will need to be recompiled using 5.6.2+
> >
> > Release notes for 5.6.2 miss this detail.
> >
> > On Wed, Feb 24, 2021 at 3:01 PM Thiago H. de Paula Figueiredo <
> > thiag...@gmail.com> wrote:
> >
> > > Tapestry 5.6.2 is a drop-in replacement for Tapestry 5.4, 5.5 and 5.6
> > > releases. It's a recommended upgrade for 5.6.1 and 5.6.0. To upgrade,
> > just
> > > update the dependency in your build configuration (Maven POM, Gradle
> > build
> > > script, etc.) – or Download the new JAR file -- and the new version
> will
> > > just work. However, please review the How to Upgrade instructions
> before
> > > upgrading.
> > >
> > > The most interesting improvement is  TAP5-2640: better exceptions in
> > > tapestry-json code, plus JSONArray now implementing Collection and
> > > JSONObject implementing Map.
> > >
> > > Full details at https://tapestry.apache.org/release-notes-562.html.
> > >
> > > Thanks for everyone involved in this release!
> > >
> > > Happy coding!
> > >
> > > --
> > > Thiago
> > >
> >
> >
> > --
> > Dmitry Gusev
> >
> > AnjLab Team
> > http://anjlab.com
> >
>
>
> --
> Thiago
>


Re: version 5.7.0, maven and jetty

2021-02-25 Thread Ben Weidig
Ah ok. I don't know much about maven and jetty:run, we run an embedded
jetty as Java application, and use gradle ;-)

It kinda sounds like a (transitive) dependency issue.
Something still wants 5.6.x and is trying to load a class from the old
package.

Maybe "mvn dependency:tree -Dverbose" can shed some light if there's a
wrong version at some point.

Or can you pinpoint where the class is supposed to be loaded?
To identify the dependency which might be loading the wrong version?
Is there more verbose output available?

I'm sure it's one of the first things you tried, but did you clean the
project, and made sure it did clean everything?
We sometimes had issues with old/outdated class files in a
build/target-folder.

That's all I got!

On Thu, Feb 25, 2021 at 2:52 PM Marcel Schepers 
wrote:

> Hello Ben,
>
> Thank you very much for your assistance.
>
> What is was trying to say is that the Maven/Jetty occurs after the
> migration process as described in the release notes. As far as I can see
> the migration tool did its job as the project compiles error free. It is
> the 'mvn jetty:run' command that causes the error.
>
> Marcel
>
> On Thu, Feb 25, 2021 at 1:28 PM Ben Weidig  wrote:
>
> > Hi Marcel,
> >
> > Tapestry 5.7.0 is not a simple drop-in upgrade from 5.6.x and needs
> manual
> > migration steps.
> > A lot of classes, like Configuration, moved to new packages, to make the
> > Java 9+ module system (partially) possible, and decouple the UI-related
> > parts from the general web-stack.
> >
> > There's a migration tool available, and the necessary steps are in the
> > release notes
> >
> > https://tapestry.apache.org/release-notes-570.html
> >
> > Hope this helps!
> > Ben
> >
> > On Thu, Feb 25, 2021 at 9:03 AM Marcel Schepers <
> marcel.schep...@gmail.com
> > >
> > wrote:
> >
> > > Hello,
> > > After upgrading to 5.7.0 I get this error message when trying to run my
> > > development version using Jetty's Maven plugin:
> > >
> > > java.lang.NoClassDefFoundError: org/apache/tapestry5/ioc/Configuration
> > >
> > > Any ideas what needs to be added to what classpath?
> > >
> > > Best,
> > > Marcel
> > >
> >
>


Re: version 5.7.0, maven and jetty

2021-02-25 Thread Ben Weidig
Hi Marcel,

Tapestry 5.7.0 is not a simple drop-in upgrade from 5.6.x and needs manual
migration steps.
A lot of classes, like Configuration, moved to new packages, to make the
Java 9+ module system (partially) possible, and decouple the UI-related
parts from the general web-stack.

There's a migration tool available, and the necessary steps are in the
release notes

https://tapestry.apache.org/release-notes-570.html

Hope this helps!
Ben

On Thu, Feb 25, 2021 at 9:03 AM Marcel Schepers 
wrote:

> Hello,
> After upgrading to 5.7.0 I get this error message when trying to run my
> development version using Jetty's Maven plugin:
>
> java.lang.NoClassDefFoundError: org/apache/tapestry5/ioc/Configuration
>
> Any ideas what needs to be added to what classpath?
>
> Best,
> Marcel
>


Re: Ecmascript5 and tapestry-webresources

2021-01-28 Thread Ben Weidig
Hi,

the GoogleClosureMinimizer and its non-configurability is on my personal
"things to look at" list for quite some time.
We ran into issues in the past, and it popped up on the mailing list last
year a few times IIRC.

So far, you need either to set
TapestryConstants.DISABLE_JAVASCRIPT_MINIMIZATION in an appropriate place
like a RequestFilter, or disable minimization altogether.

My initial thought is a CompilerOptionsFactory/Provider with a default
implementation.

I didn't find any information if the options are thread-safe and could be
reused, so contributing it as a symbol (as an alternative to a factory)
might not be feasible.

If I find some time this weekend I try to (finally) take a deeper look at
it.

Cheers,
Ben

On Thu, Jan 28, 2021 at 1:16 PM Thiago H. de Paula Figueiredo <
thiag...@gmail.com> wrote:

> Hello, Geoff!
>
> Looking at GoogleClosureMinimizer, I cannot see how the options can be
> customized. Could you please create a Jira issue so we can fix this in
> 5.7.0? Thanks in advance.
>
> Cheers!
>
> On Thu, Jan 28, 2021 at 6:31 AM JumpStart <
> geoff.callender.jumpst...@gmail.com> wrote:
>
> > Can I pass options to GoogleClosureMinimizer at runtime?
> >
> > I have a 3rd party javascript file (html2canvas.min.js) that
> > tapestry-webresources is failing to parse because the JS is using
> > javascript getters, which I think were introduced in ECMASCRIPT5.
> >
> > 2021-01-28 04:31:40,536 ERROR [org.apache.tapestry5.ioc.Registry]
> (default
> > task-14) Compilation failed: JSC_PARSE_ERROR. Parse error. getters are
> not
> > supported in older versions of JavaScript. If you are targeting newer
> > versions of JavaScript, set the appropriate language_in option. at
> > StreamableResource > classpath:META-INF/modules/html2canvas.min.js COMPRESSABLE lastModified:
> > Thu Jan 28 03:44:05 UTC 2021 size: 165202> line 20 : 0.
> >
> > As I am targeting only modern versions of Chrome and Safari, it seems
> that
> > I could fix this by passing option —language_in=ECMASCRIPT5 to
> > google-closure-compiler, but how can I do this? Is there a system
> property
> > I can provide at runtime?
> >
> > In case it helps, here’s the stack trace...
> >
> > 2021-01-28 04:31:40,536 ERROR [org.apache.tapestry5.ioc.Registry]
> (default
> > task-14) Compilation failed: JSC_PARSE_ERROR. Parse error. getters are
> not
> > supported in older versions of JavaScript. If you are targeting newer
> > versions of JavaScript, set the appropriate language_in option. at
> > StreamableResource > classpath:META-INF/modules/html2canvas.min.js COMPRESSABLE lastModified:
> > Thu Jan 28 03:44:05 UTC 2021 size: 165202> line 20 : 0.
> > 2021-01-28 04:31:40,537 ERROR [org.apache.tapestry5.ioc.Registry]
> (default
> > task-14) Operations trace:
> > 2021-01-28 04:31:40,537 ERROR [org.apache.tapestry5.ioc.Registry]
> (default
> > task-14) [ 1] Streaming compressed module html2canvas.min
> > 2021-01-28 04:31:40,537 ERROR [org.apache.tapestry5.ioc.Registry]
> (default
> > task-14) [ 2] Streaming classpath:META-INF/modules/html2canvas.min.js
> > (compressed)
> > 2021-01-28 04:31:40,537 ERROR [org.apache.tapestry5.ioc.Registry]
> (default
> > task-14) [ 3] Minimizing StreamableResource > classpath:META-INF/modules/html2canvas.min.js COMPRESSABLE lastModified:
> > Thu Jan 28 03:44:05 UTC 2021 size: 165202>
> > 2021-01-28 04:31:40,544 ERROR
> > [org.apache.tapestry5.modules.TapestryModule.RequestExceptionHandler]
> > (default task-14) Processing of request failed with uncaught exception:
> > org.apache.tapestry5.ioc.internal.OperationException: Compilation failed:
> > JSC_PARS
> > E_ERROR. Parse error. getters are not supported in older versions of
> > JavaScript. If you are targeting newer versions of JavaScript, set the
> > appropriate language_in option. at StreamableResource > classpath:META-INF/modules/html2canvas.min.j
> > s COMPRESSABLE lastModified: Thu Jan 28 03:44:05 UTC 2021 size: 165202>
> > line 20 : 0.: org.apache.tapestry5.ioc.internal.OperationException:
> > Compilation failed: JSC_PARSE_ERROR. Parse error. getters are not
> supported
> > in older versions of JavaScript. If yo
> > u are targeting newer versions of JavaScript, set the appropriate
> > language_in option. at StreamableResource > classpath:META-INF/modules/html2canvas.min.js COMPRESSABLE lastModified:
> > Thu Jan 28 03:44:05 UTC 2021 size: 165202> line 20 : 0.
> > …
> > Caused by: java.lang.RuntimeException: Compilation failed:
> > JSC_PARSE_ERROR. Parse error. getters are not supported in older versions
> > of JavaScript. If you are targeting newer versions of JavaScript, set the
> > appropriate language_in option. at StreamableResource > classpath:META-INF/modules/html2canvas.min.js COMPRESSABLE lastModified:
> > Thu Jan 28 03:44:05 UTC 2021 size: 165202> line 20 : 0.
> > at
> >
> org.apache.tapestry5.internal.webresources.GoogleClosureMinimizer.doMinimize(GoogleClosureMinimizer.java:97)
> > at
> >
> 

Re: component

2020-11-02 Thread Ben Weidig
Hi Volker,

I believe the actual error message is done with JS:

https://github.com/apache/tapestry-5/blob/0229bd59d44de848ae7412c8161bde6afe75ab84/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/fields.coffee#L173

https://github.com/apache/tapestry-5/blob/73e327b4f89639dee922713164dec05ff2d9a3e9/tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/AbstractField.java#L287

What kind of field is the t:error for? Did you record the error manually,
or use a validator?


Cheers
Ben



On Mon, Nov 2, 2020 at 2:22 PM Volker Lamp  wrote:

> Hello everybody
>
> I'm trying to figure out why the  (singular) component is not
> working for me. No difficulties with  (plural) in the same
> place.
>
> The error is recorded with a reference to the field. Inspecting the form's
> ValidationTracker contains the expected error. Likewise,  is
> referencing that field with the for attribute.
>
> The field and the error component are also encapsulated by a Form component
> and a .
>
> All that gets rendered is:
> 
> No inner HTML instead of the expected error message.
>
> So I looked at the Error.java
> <
> https://github.com/apache/tapestry-5/blob/master/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Error.java
> >
> to understand how the component works. Apparently it never generated any
> inner HTML. Also, I was expecting to find some sort of reference to
> ValidationTracker, but there is none.
>
> Any ideas anybody, please?
>
> Volker
>


Re: TriggerFragment/FormFragment not working properly in 5.4.5

2020-01-07 Thread Ben Weidig
Hi Thiago,

with "from the outside" I meant triggering them manually, sorry.

But if I find some time, I'll check it out again, and if I can fix it on
Tapestry's side, I'll create a pull request.

Ben

On Wed, Jan 8, 2020 at 1:52 AM Thiago H. de Paula Figueiredo <
thiag...@gmail.com> wrote:

> Do you happen to know how to fix this from the outside? If you create a
> pull request, after testing, I'll happily apply it.
>
> On Mon, Jan 6, 2020 at 5:26 AM Ben Weidig  wrote:
>
> > Hi,
> >
> > we ran into some issues with nested fragments and disabled fields, too.
> > Instead of using the mixin we ended up triggering the fragments ourselves
> > with CoffeeScript:
> >
> > define ['jquery', 't5/core/events', 't5/core/form-fragment'], ($, events)
> > ->
> >
> > fieldChange = (event) ->
> > $('#formFragmentId').trigger
> events.formfragment.changeVisibility,
> > visible: 
> >
> > $ ->
> > $('input[type=radio][name=fieldName]').change fieldChange
> > fieldChange()
> >
> > If I remember correctly, it wasn't easily fixable "from the outside", so
> > we're using this workaround instead.
> >
> > – Ben
> >
> >
> > On Mon, Jan 6, 2020 at 2:46 AM Ilya Obshadko  wrote:
> >
> > > Also: nested FormFragment support appears broken. Page initialization
> > > somehow triggers the code in t5/core/form-fragment module, that
> > effectively
> > > disables input fields and form controls in visible fragments.
> > >
> > > On a bright side: Loop/AjaxFormLoop issues that prevented me from
> upgrade
> > > to release version in the past, are likely gone.
> > >
> > > On Sat, Jan 4, 2020 at 11:44 AM Ilya Obshadko  wrote:
> > >
> > > > I found the place where the old behavior was possibly broken:
> > > > https://issues.apache.org/jira/browse/TAP5-2308
> > > > Did anyone else encounter this problem as well?
> > > >
> > > > On Fri, Jan 3, 2020 at 10:04 PM Ilya Obshadko 
> wrote:
> > > >
> > > >> Disclaimer: I'm doing a 'long overdue' upgrade from 5.4-beta6, so I
> > > might
> > > >> be missing something obvious.
> > > >>
> > > >> Symptoms:
> > > >>
> > > >>- I'm using a checkbox with *TriggerFragment* mixin and
> > > *FormFragment*
> > > >>component
> > > >>- I'm getting a JavaScript error in Chrome console: RequireJS
> > error:
> > > >>require: Invalid configuration, fragment with id policyFragment_0
> > not
> > > >>found
> > > >>- Setting a breakpoint on clientId field value change in
> > > >>*FormFragment* shows the following:
> > > >>   - initially clientId value is correct and it's indeed
> > > >>   *policyFragment_0* (top if the stack is
> *conduit_get_clientId*)
> > > >>   - then it's reset to *null* (top of the stack is
> > > >>   *conduit_set_clientId*)
> > > >>   - then it's set to *policyFragment* (without trailing *_0*),
> > > >>   apparently because *TriggerFragment* mixin is calling
> > > >>   *FormFragment.getClientId()* again; the field is already null
> at
> > > >>   this point, so it's just re-initialized with an incorrect
> value
> > > >>
> > > >> Apparently the culprit here is the *clientId* field
> re-initialization;
> > > >> any ideas what might be causing this? The setup itself seems to be
> > > fairly
> > > >> obvious.
> > > >>
> > > >> --
> > > >> Ilya Obshadko
> > > >>
> > > >>
> > > >
> > > > --
> > > > Ilya Obshadko
> > > >
> > > >
> > >
> > > --
> > > Ilya Obshadko
> > >
> >
>
>
> --
> Thiago
>


Re: TriggerFragment/FormFragment not working properly in 5.4.5

2020-01-06 Thread Ben Weidig
Hi,

we ran into some issues with nested fragments and disabled fields, too.
Instead of using the mixin we ended up triggering the fragments ourselves
with CoffeeScript:

define ['jquery', 't5/core/events', 't5/core/form-fragment'], ($, events) ->

fieldChange = (event) ->
$('#formFragmentId').trigger events.formfragment.changeVisibility,
visible: 

$ ->
$('input[type=radio][name=fieldName]').change fieldChange
fieldChange()

If I remember correctly, it wasn't easily fixable "from the outside", so
we're using this workaround instead.

– Ben


On Mon, Jan 6, 2020 at 2:46 AM Ilya Obshadko  wrote:

> Also: nested FormFragment support appears broken. Page initialization
> somehow triggers the code in t5/core/form-fragment module, that effectively
> disables input fields and form controls in visible fragments.
>
> On a bright side: Loop/AjaxFormLoop issues that prevented me from upgrade
> to release version in the past, are likely gone.
>
> On Sat, Jan 4, 2020 at 11:44 AM Ilya Obshadko  wrote:
>
> > I found the place where the old behavior was possibly broken:
> > https://issues.apache.org/jira/browse/TAP5-2308
> > Did anyone else encounter this problem as well?
> >
> > On Fri, Jan 3, 2020 at 10:04 PM Ilya Obshadko  wrote:
> >
> >> Disclaimer: I'm doing a 'long overdue' upgrade from 5.4-beta6, so I
> might
> >> be missing something obvious.
> >>
> >> Symptoms:
> >>
> >>- I'm using a checkbox with *TriggerFragment* mixin and
> *FormFragment*
> >>component
> >>- I'm getting a JavaScript error in Chrome console: RequireJS error:
> >>require: Invalid configuration, fragment with id policyFragment_0 not
> >>found
> >>- Setting a breakpoint on clientId field value change in
> >>*FormFragment* shows the following:
> >>   - initially clientId value is correct and it's indeed
> >>   *policyFragment_0* (top if the stack is *conduit_get_clientId*)
> >>   - then it's reset to *null* (top of the stack is
> >>   *conduit_set_clientId*)
> >>   - then it's set to *policyFragment* (without trailing *_0*),
> >>   apparently because *TriggerFragment* mixin is calling
> >>   *FormFragment.getClientId()* again; the field is already null at
> >>   this point, so it's just re-initialized with an incorrect value
> >>
> >> Apparently the culprit here is the *clientId* field re-initialization;
> >> any ideas what might be causing this? The setup itself seems to be
> fairly
> >> obvious.
> >>
> >> --
> >> Ilya Obshadko
> >>
> >>
> >
> > --
> > Ilya Obshadko
> >
> >
>
> --
> Ilya Obshadko
>


Re: Open Discussion: remove Bootstrap from T5 core

2019-02-21 Thread Ben Weidig
Hi David,

we've used @extend with SASS in our projects and ended up not using it a
lot due to its drawbacks, instead we use Bootstraps mixins more directly.

I haven't read the article in its entirety, but here are my thoughts:

For decoupling the components it might be possible to wrap the needed CSS
in placeholder selectors and aggregate them it in custom shared classes and
load only what needed. But if the components don't use the Bootstrap
classes directly we would need to change 2 classes if we like to change
behavior (e.g. .form-control and .t5-form-control).

And this doesn't deal with changed HTML-structure of Bootstrap components
between version. We needed to adapt our TML multiple times between
Bootstrap 4.0.0 beta and 4.1.2 and 4.2.1 (especially custom controls stuff).

Separated JARs or component swaps might be the better or at least more
maintainable option IMO.

Nevertheless the direct integration of SASS-support would be great. As
written before we added it ourselves with the help of
https://github.com/bit3/jsass so we can build Bootsrap from its SASS-source
instead of using the CSS-only version, and we can add some SASS beforehand
to set the
https://github.com/twbs/bootstrap/blob/master/scss/_variables.scss before
compiling Bootstrap to customize it (thanks to !default).

Works without any major issues in our projects.

Ben


On Thu, Feb 21, 2019 at 4:24 AM David Taylor 
wrote:

> Anyone have experience working with the @extend directive in CSS
> preprocessors?
>
> I came across a post that advocates decoupling HTML markup from
> bootstrap classes by using @extend. I don't particularly agree with many
> of the points the author makes, but the technique is intriguing and
> might be something that can applied to Tapestry since we support Less.
> Here is the link to the article.
>
>
> https://hackernoon.com/the-backendification-of-frontend-development-62f218a773d4
>
> The interesting bit is titled "Dealing with CSS Frameworks" and contains
> the following example:
>
> %our-warning-button {
> @extend .btn;
> @extend .btn-warning;
> }
> .empty-shopping-cart-button {
>@extend %our-warning-button;
> }
>
> Searching the web a bit I came across another article that gets into
> this in more detail. The article's title is a bit misleading since it
> actually advocates the @extend technique and offer somes advice on best
> practices.
>
> https://webinista.com/updates/dont-use-extend-sass/
>
> David
>
> emailsig On 2/19/2019 6:03 AM, Chris Poulsen wrote:
> > Hi
> >
> > I think working on making the framework "core" more css agnostic seems
> like
> > a good direction, allowing things to move forward without having to try
> and
> > pick (and maintain) the correct bootstrap version (or other css framework
> > version/flavor). There is a pretty good chance that whatever is selected,
> > will not fit the requirements of everybody anyway.
> >
> > It is a while back, but was the tapestry bootstrap integration not
> > initially handled "externally" by a markup renderer filter (I guess it
> > removed the tapestry default styling and added the bootstrap equivalent).
> > Maybe something similar could be used to apply styling (Tapestry-BS3,
> > Tapestry- BS4 or whatever) to the tapestry components, without having to
> > dream up new stuff. (Provided that the processing does not become a
> > significant performance bottle-neck).
> >
>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Open Discussion: remove Bootstrap from T5 core

2019-02-14 Thread Ben Weidig
Hi Jens,

I like the idea of decoupling the core and Bootstrap to make it easier to
use other versions.

Maybe the components should be updated to BS4 for T5.5, with a legacy
fallback or a component swap (can't remember the service doing it, we have
our own implementation, it's doing an advice on
ComponentClassResolver#resolveComponentTypeToClassName or
ComponentInstantiatorSource#getInstantiator).

For 5.4 we've developed an internal solution for using different BS
versions, here are some specifics.

We have multi-tenant-apps with different BS versions (so far up to 3), so
we needed a flexible solution that supports the internal BS and other
versions dynamically.

To make it even more flexible we've added SASS-support and compile
Bootstrap from the source files, with the possibility to add files
beforehand to the compilation step with custom variables etc.

The layout component has an annotation that triggers
a ComponentClassTransformWorker2 attaching a JavaScriptStack containing the
BS version decided by a contributable strategy pipeline.

JavaScript modules were the biggest problems, we started with replacing the
internal modules, but ended up adding additional modules instead. This
worked fine after getting all the dependencies right, but every BS version
might break it again, so we're now using the bundled version of BS JS.

We think this could all be cleaned up nicely if the internal BS wouldn't be
as integrated as it is right now.

Eventually we will release it as open-source, but having an integration
into Tapestry (as a new tapestry-*) would be even nicer :-)

Best regards
Ben


On Thu, Feb 14, 2019 at 10:14 AM Jens Breitenstein 
wrote:

> Hi Tapestry guys!
>
> I want to hear/read your opinion about getting rid of the Bootstrap
> Library from T5 core.
> I would like to move all BS related code (css/js) to a seperate module
> like "tapestry-bootstrap3" and decouple the hardcoded BS from T5.
> Furthermore I would like to see a second module "tapestry-bootstrap4"
> which uses BS4.
>
>  From the sources I see direct dependencies are less than expected. Some
> tml's use it (I just ignore the internal T5 pages for now):
>
>  AjaxFormLoop.tml
>  class="btn btn-default btn-sm"
>  
>
>  BeanEditForm.tml
>  class="btn-toolbar"
>  class="btn-group"
>  class="btn btn-primary"
>
>  DevTool.tml
>  
>  class="dropdown-menu"
>  class="dropdown-header"
>
>  ExceptionDisplay.tml
>  class="well"
>  class="pull-right"
>  class="checkbox"// ?
>
>  Palette.tml
>  class="btn-group-vertical"
>
> and some JAVA references like:
>
>  JavaScriptModule.java
>  configuration.add("bootstrap/ ...")
>
>  bundledModules=...
>
>
> Do you think it's worths looking into it, digging deeper?
> Any pitfalls I should consider?
> Anyone interested to discuss it?
>
>
> Jens
>
>
>
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Inline SVG image is broken in proudction mode, because whitespaces are removed

2019-01-04 Thread Ben Weidig
Hi,

we ran into the same issue...

production-mode=true enables resource minimizing and you are hitting an
open bug in YUICompressor since 2014

https://github.com/yui/yuicompressor/issues/304
https://github.com/yui/yuicompressor/issues/141
and some more...

We stopped using inline-SVGs because of this and moved everything to assets.

The workaround we're planning is replace the
org.apache.tapestry5.internal.webresources.CSSMinimizer by overriding the
contribution found
in org.apache.tapestry5.webresources.modules.WebResourcesModule.class:84
with another minimizer.


Ben

On Fri, Jan 4, 2019 at 2:16 PM Balázs Palcsó 
wrote:

> Hi!
>
> I have this in my *.less* file
>
> *background-image: url("data:image/svg+xml,%3Csvg width='32' height='32'
> viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath
>  d='M5.414 11L4 12.414l5.414
> 5.414L20.828 6.414 19.414 5l-10 10z' fill='%23fff'
> fill-rule='nonzero'/%3E%3C/svg%3E ");*
>
> Which works fine unless I run it with *-Dtapestry.production-mode=true*,
> becuase then the whitespaces get removed breaking the SVG definition:
> *url("data:image/svg+xml,%3Csvgwidth='32'height='32'viewBox='003232'xmlns='
> http://www.w3.org/2000/svg'%3E%3Cpathd='M5.41411L412.414l5.4145.414L20.8286.41419.4145l-1010z'fill='%23fff'fill-rule='nonzero'/%3E%3C/svg%3E
> <
> http://www.w3.org/2000/svg'%3E%3Cpathd='M5.41411L412.414l5.4145.414L20.8286.41419.4145l-1010z'fill='%23fff'fill-rule='nonzero'/%3E%3C/svg%3E
> >")*
>
> (it is surely to do with *-Dtapestry.production-mode=true* , becuase the
> issue does not manifest when I run it with
> *-Dtapestry.compress-whitespace=true* *-Dtapestry.production-mode=false*)
>
> Any suggestions how to workaround this issue?
>
> Many thanks,
> Balazs
>


Re: data-icon for option within t:select

2018-11-15 Thread Ben Weidig
Hi,

as far as I can tell from the code and documentaion the class OptionModel
supports additional attributes with its .getAttributes() method. So you
should only need to implement your own OptionModel and build your
SelectModel with it.

Hope this helps.

Ben

On Thu, Nov 15, 2018 at 7:23 JumpStart 
wrote:

> Very good question. I don’t know the answer, but here’s an idea…
>
> The Select component does not have a class parameter, but it does render
> informal parameters. So if you specify class=“selectpicker” then I’d expect
> it will be rendered with class=“selectpicker”. By default it renders the
> "select" element with class=“form-control”, so it might be best if you
> specify class=“form-control selectpicker”.
>
> As for overriding the rendering of the “option” element, I think we come
> unstuck. The difficulty I see is that OptionModel has only a label and
> value. You need label, image, and value.
>
> I think your best bet is to copy OptionModel and Select to new classes and
> and modify them suit your purposes. They aren’t long or complicated.
>
> HTH,
>
> Geoff
>
> > On 15 Nov 2018, at 1:30 pm, D. R. 
> wrote:
> >
> > Hi,
> >
> > how can i get control of the option elements within a t:select?
> >
> > I want to provide a unique data-icon property for each option.
> >
> >  t:model="literal:fa-globe=Globe,fa-flask=Flask,fa-user-tie=User-tie">
> > 
> >
> > will render:
> >
> > 
> >  
> >  Globe
> >  Flask
> >  User-tie
> > 
> >
> > i need something like
> >
> > 
> >   
> >   Globe
> >   
> >   
> >   Flask
> >   
> >   
> >   User-tie
> >   
> > 
> >
> > i want to add class="selectpicker" to the t:select in order to let
> bootstrap convert the select to a dropdown with icons.
> >
> > Kind regards
> > David
> >
> >
> > -
> > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> > For additional commands, e-mail: users-h...@tapestry.apache.org
> >
>
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


Re: Add HTTP security Headers in the response

2018-10-04 Thread Ben Weidig
The main advantage is having the full power of Tapestry and your services
available to you. Can't speak for the performance, it might be faster with
a filter before Tapestry, but I don't think it would impact your
performance that much, we have multiple RequestFilters in our apps.

The configuration is an "OrderedConfiguration", so you can influence the
order of the filters:

conf.addInstance("my-security-headers",
MySecurityHeadersRequestFilter.class, "before:StaticFiles");

The name of the contribution is defined here
org.apache.tapestry5.modules.TapestryModule.class:862

You have access to the request and can add only the headers if needed, or
just give the request to the next filter.

Hope this helps!

On Wed, Oct 3, 2018 at 8:00 PM Ajay Arora  wrote:

> Thank you the quick response and solution.
>
> is this way of putting the headers gives us any advantages over having
> filter in front of Tapestry filter like may be better performance ?
> I believe the built-in Tapestry filters would be called before any custom
> filter(s) and one of those filter like 'StaticFilesFilter' might skip some
> requests going further to the new custom filter? And, I still needs to
> parse the resource type in custom filter before setting a particular header
> like x-frame-options does not make sense a image?
>
> Thanks for your help !
>
>
Ben

-- 

Netzgut GmbH


Re: Add HTTP security Headers in the response

2018-10-03 Thread Ben Weidig
Hi,

you could use a org.apache.tapestry5.services.RequestFilter.class to access
the response (
http://tapestry.apache.org/current/apidocs//org/apache/tapestry5/services/RequestFilter.html
)

Something like this (untested code):

public class MySecurityHeadersRequestFilter implements RequestFilter {

@Override
public boolean service(Request request, Response response,
RequestHandler handler) throws IOException {
response.addHeader("X-Frame-Options", "my options");
return handler.service(request, response);
}
}

Then just contribute it in a module:

public static void
contributeRequestHandler(OrderedConfiguration conf) {
conf.addInstance("my-security-headers",
MySecurityHeadersRequestFilter.class);
}

On Wed, Oct 3, 2018 at 5:59 PM Ajay Arora  wrote:

> Hello All,
>
> We're looking for ways to add different http security headers
> like X-Frame-Options, X-XSS-Protection and others into the http response.
> We're using Tapestry 5.4.3.
>
> One way I found was to add a additional filter in web.xml before the
> Tapestry Filter takes over but then it add the headers to all the requests
> like for static files and not sure if  X-Frame-Options header etc should be
> included for the response of such type of requests.
>
> Feel like we should wait till Tapestry done handling the request and then
> add the security headers before the response goes to the client but could
> not find how to do it In Tapestry.
>
> is there a better way to do this in Tapestry?
>
> Thanks for your help !
>


Ben
-- 

Netzgut GmbH


Re: Own jQuery version

2018-05-10 Thread Ben Weidig
Hi,

you can override the jquery version by contributing an override for
"jquery-library" in the JavaScriptStack.

We're using our own jQueryUI without tapestry-jquery by contributing
JavaScriptModuleConfigurations to the ModuleManager.

I've created a
https://gist.github.com/benweidig/90547102c7dc4dc233485fbfcd1ca5da for
better code readability but here's the code:

@Core
@Contribute(JavaScriptStack.class)
public static void overrideJquery(OrderedConfiguration
conf) {
conf.override("jquery-library",
StackExtension.library("classpath:META-INF/assets/jquery/jquery-3.3.1.min.js"));
}

@Contribute(ModuleManager.class)
public static void contributeModuleManager(MappedConfiguration<String,
JavaScriptModuleConfiguration> conf,
   @Inject
@Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode,
   AssetSource assetSource) {

final String path = "META-INF/assets/jquery-ui-1.10.3/min/";

Resource coreResource = assetSource.getClasspathAsset(path +
"jquery.ui.core.min.js");
JavaScriptModuleConfiguration core = new
JavaScriptModuleConfiguration(coreResources).dependsOn("jquery");
conf.add("jquery.ui.core", core);

Resource datepickerResource = assetSource.getClasspathAsset(path +
"jquery.ui.datepicker.min.js");
JavaScriptModuleConfiguration datepicker = new
JavaScriptModuleConfiguration(datepickerResource).dependsOn("jquery.ui.core");
conf.add("jquery.ui.datepicker", datepicker);

...
}

Hope this helps.

Ben

On Thu, May 10, 2018 at 10:34 AM Erich Gormann <e.gorm...@gormann.de> wrote:

> Dear all,
>
> I'm using Tapestry 5.4.3 and the latest release version of
> tapestry5-jquery in our application.
>
> Can you give me a hint, how to force Tapestry to use another version of
> jQuery and/or jQuery UI than the one bundled in libraries?
>
> Thanks for your suggestions. I heard, that this should be possible, but
> was not able to find this in the documentation.
>
> Regrads, Ric
>
> ---------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>

-- 

Ben Weidig
Netzgut GmbH