Is there a way to fix the file locking issue caused by jetty entirely from gradle?
Some clarification:
When using the Gradle Jetty plugin by running gradle jettyRun, jetty causes the static resource files (html, css, js, etc.) to be locked when using Windows.
You can see a description of the problem in Files locked on Windows.
The same article also describes how you can fix that. Basically you have to either:
Disable the use of file mapped buffer
Not use NIO at all.
Both things require to add some jetty specific configuration files to the project, which I do not want to do - the jetty plugin is used only for convenience, and maintaining configuration for it does not feel right.
I do not need NIO for testing on the local machine, so any solution works.
Edit:
For now, I picked the option at which you set useFileMappedBuffer to false. This is how to do it:
Specify a path to your webdefault.xml like
[jettyRun, jettyRunWar,jettyStop]*.with {
//other configs
webDefaultXml = file("${project.webAppDir}/WEB-INF/jetty-webdefault.xml")
}
Get file from the latest 6.1.x distribution of jetty. The plugin seems to support only jetty 6. You can localte it at jetty-6.1.26\etc\webdefault.xml. Obviously, you have to place it at the path specified at the previous step.
Change the default servlet init parameter useFileMappedBuffer to false
I will research the option of using embeded jetty insted of the plugin.
I found a plugin that seem to be a better alternative:
https://github.com/akhikhl/gretty
Positives
Does not lock your files and support hot deployment (even something Gretty call "fast reload")
Gretty 1.2.0 uses Jetty 9.2.9.v20150224. Jetty plugin provided by Gradle 2.2.1 uses Jetty 6.1.25.
same task is used jettyRun (or more simply run).
"Press any key to stop the server". Jetty plugin required CTRL+C then Y.
From what I can tell, the documentation seem to be awesome (Gradle's not so much)
Negatives
A bit more bloated code to setup the buildscript's classpath dependency or apply plugin directly from URL (see doc)
Gretty crash unless you explicitly apply plugin: 'war' (Jetty plugin extends the War plugin)
Kiril answered his own question, many thanks. You should follow Kiril's instructions and this will help you find the appropriate webdefault.xml.
To find out what version of Jetty is started by Gradle, execute
gradle jettyRun -i
And you'll see something like this:
...
Tmp directory = determined at runtime
Web defaults = org/mortbay/jetty/webapp/webdefault.xml
Web overrides = none
Webapp directory = C:\dev\my-project\src\main\webapp
Starting jetty 6.1.25 ...
jetty-6.1.25
...
It took me a while to find a copy of Jetty 6.1.25 as it is no longer listed on the Jetty download page (not even in the archive section!).
You can then grab the appropriate copy of webdefault.xml from here, adjusting the version number as appropriate for your needs:
http://grepcode.com/file/repo1.maven.org/maven2/org.mortbay.jetty/jetty/6.1.25/org/mortbay/jetty/webapp/webdefault.xml
Related
My goal is to set jetty to run as a service and figured I should have it run in command line first. My current aim is to be able to run jetty from root path. Once that's done, I can then set the same command to run as a service via https://nssm.cc/.
The issue
The webapp I am deploying in this Jetty instance uses logback to manage it's logging <file>logs/app.log</file>
This works as expected.
C:\jetty>java -jar start.jar
This does not C:\>java -jar C:\jetty\start.jar. (Note the different cmd path). Jetty can't figure out correct paths for log files. After some testing, I was able to rectify the path issue but still jetty is complaining about not being able to find the log file, even though I see it exists. So, permissions issue perhaps? I go ahead and give everyone full read and write access to the entire folder. No dice, still the same error.
Command I run now
C:\>java -Djetty.base=C:\jetty -Duser.dir=C:\jetty -jar C:\jetty\start.jar but the error persists.
....
12:11:51,095 |-INFO in ch.qos.logback.core.FileAppender[FILE] - File property is set to [logs/app.log]
12:11:51,111 |-ERROR in ch.qos.logback.core.FileAppender[FILE] - Failed to create parent directories for [C:\jetty\logs\app.log]
12:11:51,111 |-ERROR in ch.qos.logback.core.FileAppender[FILE] - openFile(logs/app.log,true) call failed. java.io.FileNotFoundException: logs\app.log (The system cannot find the path specified)
at java.io.FileNotFoundException: logs\app.log (The system cannot find the path specified)
....
Jetty version is 9.4.9.v20180320
Create a proper ${jetty.base} directory, outside of of the ${jetty.home} directory.
Next, get yourself a fresh copy of jetty-home (or the jetty-distribution which really only adds documentation, demos, and sample bases to jetty-home).
http://search.maven.org/#search|gav|1|g:"org.eclipse.jetty" AND a:"jetty-home"
Unpack that jetty-home artifact into a fresh directory.
Important:
Don't touch any content in jetty-home
Don't edit anything in jetty-home
Don't remove anything from jetty-home
Don't add anything into jetty-home
Leave jetty-home alone
Treat jetty-home as a read-only directory
All above bullets apply even if using jetty-distribution
Lastly, start jetty per the recommendations in the Jetty Documentation.
> cd \path\to\myjettybase
> java -jar \path\to\jetty-home\start.jar
Note the lack of declared system properties for -Djetty.home and -Djetty.base, this is important!
This will set up the following important directory properties.
jetty.base will be your CWD, or \path\to\myjettybase
jetty.home will be where your start.jar was found, aka \path\to\jetty-home\
user.dir will be your CWD and point to \path\to\myjettybase
What's important, for logging configurations like yours, is the user.dir system property. (aka the current working directory)
The technique you are using where you don't pay attention to the working directory and just attempt to force values into the JVM with system properties is only viable in the simplest of projects and usecases. (your requirements have outgrown that kind of setup)
I am trying to write a Dropwizard application and its doc tells me that I need to ship everything as an uber jar.
However, in my application I need to support multiple databases and this requires multiple database JDBC driver jars in my classpath, all of which are not expected to be shipped together with my application. Users are expected to place the corresponding JDBC jar like mysql-connector-java-5.1.39.jar in a particular folder by their own.
After reading Dropwizard's documentation I am not sure if this kind of usage is supported. Does anyone have experience making it to work this way?
Since java 6, you can wildcard classpaths.
Using the application plugin, the generated bin folder will have a start script that contains the classpath. What we want to do, is to instead of listing every possible jar in the bin folder, we simply include all of them.
Note: You can also do the same thing with different folders if you want the classpath in a different location.
This can be achieved (in a workaround manner since there are problems with this plugin in my version) in the easiest way as follows. In build.gradle you do:
startScripts {
doLast {
def windowsScriptFile = file getWindowsScript()
def unixScriptFile = file getUnixScript()
windowsScriptFile.text = windowsScriptFile.text.replaceAll('CLASSPATH=.*', 'CLASSPATH=\\$APP_HOME/lib/*')
unixScriptFile.text = unixScriptFile.text.replaceAll('CLASSPATH=.*', 'CLASSPATH=\\$APP_HOME/lib/*')
}
}
This will wildcard your lib folder in the start scripts. When starting up, your classpath will simply be
lib/*
When you drop jars into that folder, they will automatically be picked up (on startup, not on runtime).
I hope this helps,
Artur
I am deveoloping a custom plugin for Pentaho DI / Kettle 4.4 and use custom Validation and XSLT jars as part of it.
Those jars are referenced in plugin.xml along with the plugin's jar itself and deployed in the same location as the plugin's jar.
When I try to load this plugin in Spoon GUI, I can see and run the plugin fine till I reach the reference to the external jars and after that I get ClassNotFOund Exception.
I have tried following so far but has not worked :
Add the expernal Jars to libext folder and expect those to be picked up automatically. - Failed. Jars not loaded.
Add -cp command line option to Spoon.bat and specify the Jar files - Did not work.
Turned on -verbose option and search everywhere in the output but the Jars are ignored.
Deployed the Jars next to the plugin's Jar file in the plugin's folder. - Jars are not recognized.
From Within the plugin, if I dynamically load (using Reflection and URL Class Loader) I am able to force the loading of the Jars and it works that way but I would like a simpler classpath fix.
Any class that I reference in the Jar through XSL externsion (XALAN-J Java Extension) is still not recognized / loaded and XSL terminates at the beginning of Extension call.
Searched Google and this site for something similar but did not find specific answers on why SPoon behaves so differently and avoids external code and content.
A similar issue is reported here though its too old and has not shown final conclusive fix. I tried all that it said. http://forums.pentaho.com/archive/index.php/t-77190.html
Requesting someone to help me identify whats missing. Thanks in advance,
Thanks to this seemingly obscure website and it fixed all pain.
http://www.arulraj.net/2014/09/how-to-access-external-java-libraries-with-in-pentaho.html
Basically, go to the launcher folder and edit the launcher.properties file to include any path, library etc. and it fixes all the issues I reported above. Wish Kettle documentatation had answers like this.
I can't seem to get my JSTL library working in my embedded jetty project working.
My taglib line seems to be giving me grief, and it all changes when I use different URIs. Here is the line I would want to use:
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
I first tried using the normal URI http://java.sun.com/jsp/jstl/core but that throws the error:
org.apache.jasper.JasperException: /bad.jsp(1,61) PWC6188: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
However when I change the URI to http://java.sun.com/jstl/core_rt. It works!
Another thing I noticed, if I have the old JSTL 1.0 url (http://java.sun.com/jstl/core) I get the following error:
org.apache.jasper.JasperException: /bad-el.jsp(4,0) PWC6236: According to TLD or attribute directive in tag file, attribute value does not accept any expressions
Now another preplexing thing I have noticed, this all works in IntelliJ! Which leads me to believe that there is a classpath problem, but the libraries should be all the same when I embed them inside the war. I think I am missing something.
So, what my question boils down to, what library do I need, or what configuration do I need to have to make this work properly?
Here are the current questions I have tried to follow but did not resolve my issues:
cannot load JSTL taglib within embedded Jetty server
Embedded Jetty fails to load JSP taglibs when classpath specified in jar
Jetty 8 standalone doesn't detect jstl taglib jar
JSTL not parsed in a JSP page running on an embedded Jetty instance
and many others
I have a sample project that one could checkout and try out.
if you want the JSTL uri to work, you should know that jstl is two files.
jstl-1.2.jar
jstl-api-1.2.jar
so look for them in the internet or go to the maven repo and download the jars
I want to write some unit tests that run within Adobe CQ 5.4. I am doing what is described in this article for testing within CQ:
http://jtoee.com/2011/09/799/
However, after I create the unit test class in my Java code, it won't compile within CRXDE because it can't resolve the org.junit namespaces. I installed and activated the JUnit bundle in Felix as described (Apache Sling JUnit Core), but I am guessing there is something else I need to do in order for this active Felix bundle to be found in CRXDE. The Felix bundle in the CQ5 instance I am connected to shows these exported packages:
junit.framework,version=4.8.2
org.apache.sling.junit,version=1.0.7.SNAPSHOT
org.apache.sling.junit.annotations,version=1.0.7.SNAPSHOT
org.junit,version=4.8.2
org.junit.matchers,version=4.8.2
org.junit.rules,version=4.8.2
org.junit.runner,version=4.8.2
org.junit.runner.manipulation,version=4.8.2
org.junit.runner.notification,version=4.8.2
org.junit.runners,version=4.8.2
org.junit.runners.model,version=4.8.2
In this sample unit test code below, the last three import statements "cannot be resolved."
import org.apache.sling.api.resource.*;
import org.junit.*;
import org.junit.runner.*;
import org.apache.sling.junit.annotations.*;
#RunWith(SlingAnnotationsTestRunner.class)
public class MyUnitTest {
public ResourceResolver getResourceResolver() {
try {
return getResourceResolverFactory().
getAdministrativeResourceResolver(null);
} catch (LoginException e) {
fail(e.toString());
}
return null;
}
}
It is my novice understanding that the OSGI bundle installed in Felix should be accessible for me to reference in my Java classes using CRXDE, but it isn't happening for the JUnit bundle I installed. Why not? What do I need to do to get CRXDE to find the OSGI bundle reference and compile within CRXDE?
What you're doing looks correct at first sight.
Did you try restarting CQ after installing the required bundles? In theory that should not be required but I'm wondering if the bundle compiler is picking up the newly available packages correctly.
I have uploaded a content package with a similar simple example at http://dl.dropbox.com/u/715349/cq5-examples/junit-tests-1.0.zip (md5 2915123ad581aa225bd531247ea02878), after installing this package on a fresh CQ 5.4 instance the example test is correctly executed via http://localhost:4502/system/sling/junit/
You might want to try my sample and compare with yours.
Short Answer
The problem is not with CQ, the problem is with CRXDE. CRXDE automatically downloads and caches required jar files on your local machine so they don't have to be retrieved constantly from CQ.
If you switch to the 'Package Explore' navigation and then expand the project '{SERVER}{PORT}{HASH}' you should see a folder called Referenced Libraries. Right click and select Build Path >> Configure Build Path. From there you can add any dependencies you want into the project.
Long Answer
CRXDE is not a good tool for creating bundles. It is much better to create bundles through a full fledged IDE such as Eclipse and utilize Apache Maven as a build tool. Apache Maven can automatically manage your dependencies, run tests on your code and separate test vs. runtime dependencies.
That way you can avoid having to load dependencies that you don't really need such a jUnit into your OSGi console and you have more control over how your bundle is built and deployed.
Day has a really nice guide to getting you set up with building CQ projects with Eclipse.
http://dev.day.com/docs/v5_2/html-resources/cq5_guide_developer/ch04s02.html