I've noticed that using standard ArchConditions display messages in the following format:
Class <full_class_path> does not <some_rule> in (<class_link>)
However, this is not the case for custom conditions that add violation messages to the event like:
events.add(SimpleConditionEvent.violated(item, item.getName() + " some message"));
With this, no link to the violating class is appended to the message automatically. I wonder what the first argument (correspondingObject) is actually used for then.
Is this a bug in the framework or am I missing something? Having these links are really useful. I've tried using the JavaDoc #link notation in the message string to no avail.
Most of the domain classes like JavaClass, JavaMember or JavaAccess implement the interface HasSourceCodeLocation, which contains the method getSourceCodeLocation to obtain the location in the source code. The returned object SourceCodeLocation can then be used to output the location via the toString method.
For example
events.add(SimpleConditionEvent.violated(item, item.getDescription() + " is violated in " + item.getSourceCodeLocation()));
would return
Class <org.example.Dummy> is violated in (Dummy.java:0)
Related
I am working in a REST service using javax.ws.rs, running under Glassfish, and I have some strange behavior differences on different servers, regarding the interpretation of empty query params.
Note, actual names of services and implementation details deemed unimportant have had their names changed or been omitted, to protect the innocent.
Some (most) servers treat a request
http://localhost/serviceRoot/orders?status=
(i.e. a query param named status is provided, but with no value after the = sign) as equivalent to
http://localhost/serviceRoot/orders
essentially letting that query param be null, but some treat it as though that query param had the value of "" (empty-string).
This is a problem in my case, because:
/* In a Resource class, I have this method defined: */
#GET
#Path("/orders")
public Response getOrders(#QueryParam("status") OrderStatus orderStatus) throws Exception {
/* code to pull orders, optionally by status, and return them in a Response */
}
/* ... and elsewhere, our enum */
public enum OrderStatus {
RECEIVED, ACKNOWLEDGED, CANCELLED
}
and when someone sends the first request above to a server which treats it as an empty string, I get an error in the form:
"java.lang.IllegalArgumentException: No enum constant com.fqcn.OrderStatus."
(because "" is not a valid value in the enum which it tries to automatically construct) whereas it would successfully retrieve a list of orders, if the request hit a different server.
In order to debug, though I was not able to make it produce a stack trace under normal execution, I was able to write an ExceptionMapper, and output the stack trace of that, explicitly, so I came up with this:
com.sun.jersey.server.impl.model.parameter.QueryParamInjectableProvider$QueryParamInjectable.getValue(QueryParamInjectableProvider.java:74),
com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46),
com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153),
com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203),
com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75),
com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288),
com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147),
com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108),
com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147),
com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84),
com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469),
com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400),
com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349),
com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339),
com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416),
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537),
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708),
javax.servlet.http.HttpServlet.service(HttpServlet.java:770),
org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550),
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281),
org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:175),
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java),
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655),
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595),
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161),
org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331),
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231),
com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317),
com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195),
com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860),
com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757),
com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056),
com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229),
com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137),
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104),
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90),
com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79),
com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54),
com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59),
com.sun.grizzly.ContextTask.run(ContextTask.java:71),
com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532),
com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513),
java.lang.Thread.run(Thread.java:724)
My problem is: I do not know where this query-param interpreting behavior resides (what config file, or class/jar file), and I do not have control over the clients requesting this. Furthermore, the "big red button" approach of taking down the offending servers and standing up new clones from a "known good" instance is time-expensive and has to be done very carefully.
The question I would like answered is: Where, if anywhere within Glassfish or Jackson (or another layer of the service stack?), is this empty-query-param interpreting behavior configured, and how do I change it?
I am currently trying to implement file exports in background so that the user can do some actions while the file is downloading.
I used the apache isis CommandExexuteIn:Background action attribute. However, I got an error
"Not an (encodable) value", this is an error thrown by the ScalarValueRenderer class.
This is how my method looks like:
#Action(semantics = SemanticsOf.SAFE,
command = CommandReification.ENABLED)
commandExecuteIn = CommandExecuteIn.BACKGROUND)
public Blob exportViewAsPdf() {
final Contact contact = this;
final String filename = this.businessName + " Contact Details";
final Map<String, Object> parameters = new HashMap<>();
parameters.put("contact", contact);
final String template = templateLoader.buildFromTemplate(Contact.class, "ContactViewTemplate", parameters);
return pdfExporter.exportAsPdf(filename, template);
}
I think the error has something to do with the command not actually invoking the action but returns the persisted background command.
This implementation actually worked on the method where there is no return type. Did I miss something? Or is there a way to implement background command and get the expected results?
interesting use case, but it's not one I anticipated when that part of the framework was implemented, so I'm not surprised it doesn't work. Obviously the error message you are getting here is pretty obscure, so I've raised a
JIRA ticket to see if we could at least improve that.
I'm interested to know in what user experience you think the framework should provide here?
In the Estatio application that we work on (that has driven out many of the features added to the framework over the last few years) we have a somewhat similar requirement to obtain PDFs from a reporting server (which takes 5 to 10 seconds) and then download them. This is for all the tenants in a shopping centre, so there could be 5 to 50 of these to generate in a single go. The design we went with was to move the rendering into a background command (similar to the templateLoader.buildFromTemplate(...) and pdfExporter.exportAsPdf(...) method calls in your code fragment, and to capture the output as a Document, via the document module. We then use the pdfbox addon to stitch all the document PDFs together as a single downloadable PDF for printing.
Hopefully that gives you some ideas of a different way to support your use case
Thx
Dan
i want override the interface Log, because i use always this menssage:
private final static Log log = LogFactoryUtil.getLog(classess.class);
log.error("La cita " + cita.getIdCita() + " ha producido un excepcion en " + e.getClass() + " casuda por "
+ e.getCause() + ". Trace: " + e.getLocalizedMessage());
my idea is override log.error for get in for parameter the throwlable only and then print the message but i don't know how call to original error.
If I understood correctly, you want to introduce a new method (with 4 parameters) to the Log interface. This is completely discouraged, as your new interface would be utterly incompatible with the assumption that anybody else makes when using this interface (or when providing alternative implementations). You would basically maintain your own private fork of Liferay, largely incompatible with the rest of the world. And that only for a change in a lowly Log class.
Don't go there. It's not too bad to construct an error message like you do in the snippet that you include in your question.
If you have the same thing duplicated everywhere in your code and think it would be cleaner otherwise, encapsulate Liferay's logging within your own logging class and use that, delegating to Liferay's log in the end.
However, don't invest too much time in fancy logging. IMHO that problem has been tackled once and forever, and within an application context, you'd not be able to deliver significant enhancement to the logging world...
How can I make an eclipse java template that allows generating java code that eases the repeating part of registering code for a java method. Example:
Assume that the class description is like so:
class A{
public static void methodName(String s, int i, Object o) {
}
}
Now, what I want is to make a template that does something somewhat like this:
"${enclosing_type}.${enclosing_method}(" + ${variable1} + ", " + ${variable2} + ", " + ${variable3} + ")"
Given the available Eclipse variables I know, the idea would probably be:
"${enclosing_type}.${enclosing_method}(" + ${enclosing_method_arguments(" + \", \" + ")} + ")"
Where that argument would signal the glue to the join of each element of the enclosing_method_arguments. The result of the format would be:
"A.methodName(" + s + ", " + i + ", " + o + ")"
If there's an even better alternative, I'm open for suggestions.
This is meant to be used with a piece of code that is executed a LOT,
Unfortunately, String.format() (and related) "solution" is not an option here due to the requirement above and due to other inherited requirements with what I'm working on. It must generate that code in that format no matter what, unfortunately.
I'm open to any plugins that allow that and, if eclipse doesn't have it, I'm open to make a plugin myself... In case of me having to do a plugin please do show me the resources required to make it.
It should be possible to write a custom variable resolver. It is defined by org.eclipse.ui.editors.templates extension point
You could implement a custom resolver that points to Java context (its id is java defined in jdt.ui).
I don't know any plugins that would provide what you need out of the box.
If you are new to Eclipse plug-ins you might need to read the documentation on extending Eclipse. However, the task is really simple, so you should be able to do it after just a glimpse over the docs.
As far as I can see the taglet api has exactly one class in its package: Taglet, if you change Taglet.html to package-summary.html, there's nothing else in it (and there's this mildly scary message:
As of JDK version 1.5, replaced by com.sun.tools.doclets.internal.toolkit.util.
which I'm assuming that does not affect the Taglet interface itself.)
There is nothing in the interface that knows anything about the class in which the taglet resides--nothing about its context.
Is there anyway to get the name of the class in which the taglet is being "called" from? The class that has the JavaDoc block in which {#.myTaglet} exists?
As a hack, I'm thinking of forcing the user to set it with {#.thisClass my.package.AClass} at the top, before using any of my custom taglets.
Better ideas would be great.
(Here's Sun's taglet overview.)
(Also, please consider looking at my previous question, which is another taglet question: How to make inline taglets (which require com.sun) more cross-platform? Is there a non-Oracle/more-cross-platform javadoc parser?)
As I was researching this question, I figured it out. This is a function in the demo UnderlineTaglet:
public String toString(Tag tag) {
return "<u>" + tag.text() + "[" + tag + ", [" +
tag.holder() + "]]</u>";
}
If this taglet is in com.github.xbn.insertexample.BasicOutputProcessors
{#underline xxx}
It results in
<u>xxxy[#underline:xxxy, [com.github.xbn.insertexample.BasicOutputProcessors]]</u>
So tag.holder().toString() is the answer.
API:
http://docs.oracle.com/javase/7/docs/jdk/api/javadoc/doclet/com/sun/javadoc/package-summary.html