maven webapp to place jsps in /WEB-INF/jsp - java

I have inherited a webapp built using NetBean's internal ant.
All jsps reside in:
WEB-INF/jsp
And the web.xml has hardcoded links to /WEB-INF/jsp/somefile.jsp
How can I use the maven war plugin to place the JSP there, maintaining consistency with the current structure ?
My pom currently reads:
<warSourceDirectory>${basedir}/web/WEB-INF</warSourceDirectory>

What the problem? Let's look at a standard war project structure:
$ mvn archetype:create -DgroupId=com.mycompany.app \
> -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp
...
$ tree my-webapp/
my-webapp/
|-- pom.xml
`-- src
`-- main
|-- resources
`-- webapp
|-- WEB-INF
| `-- web.xml
`-- index.jsp
5 directories, 3 files
No need to configure anything, just put your JSPs under src/main/webapp/WEB-INF/jsp and there you go.
EDIT: I don't understand why you have the following line in your maven-war-plugin configuration:
<warSourceDirectory>${basedir}/web/WEB-INF</warSourceDirectory>
What is the expected behavior? Why don't you use the default value ${basedir}/src/main/webapp?

Also note that everything in src/main/resources will be "on the classpath", i.e., it all is copied to my-webapp/WEB-INF/classes when the war is built. So that's a good place to put your configuration files, for example, log4j.xml / logback.xml, or Spring's applicationContext.xml and Spring's other config files, which you can then easily reference with classpath:somefile.xml.
What also makes this very nice is you can set up filters in maven so that it transforms the files from src/resources before it puts them in the war file.
So if you have any config files, other than web.xml, in src/main/webapp/WEB-INF, think about moving them to the src/main/resources directory.

Related

How to create a file in a eclipse project directory without knowing the exact path?

I have a java class in my Eclipse web-app project that generate a XML file. This xml file will be used to display its content in a JSP page through an AJAX call. Suppose I want to export the project and send it to another user who will then use it on another PC. How can I create the xml file in the project directory even though I don't know the path it will have on the new computer?
Most Java projects have a standardized project structure.
e.g. Maven looks like follows:
my-app
|-- pom.xml
`-- src
|-- main
| |-- java
| | `-- com
| | `-- mycompany
| | `-- app
| | `-- App.java
| `-- resources
|
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java
Files a Java application will create with a relative path will read from the resources folder when run locally (of course this can be configures in the runtime environment in Eclipse or tweaked in the java/javac CLI command).
Note a packaged Java program cannot write into the packaged JAR or WAR file. So when creating a JAR/WAR you can embed static content, but writing doesn't work. So when you run JSP pages classloading comes into play. Different uses get sandboxed to their own context on the server side. Therefore sharing the same file and/or disk space might not be a good idea in overall.
When you have a file DB or similar, you should have a server configuration variable to set the path to the value that's used on your server. The complete configuration in your JSP environment is handeled in the web.xml file:
https://docs.oracle.com/cd/E13222_01/wls/docs81/webapp/web_xml.html
It's the standard way for J2EE containers by the way.
If you have a local project and not a fully blown production environment, the simplest options might be reading out an environment variable with the local path you want to use on your machine.
Note that if you want to write a file from your J2EE container (=the software that's running the JSP) there might be security rules needed you need to set in Tomcat/Glassfish/Wildfly/...
One way is to pass the path as a system property -Dproperty=value (e.g. java -DxmlDir="C:\xml" SomeClass). On Eclipse, you can add this in Run Configurations, then I think it was either in Arguments or Environment. To access the property, simply do System.getProperty("xmlDir"). On the new computer, they can specify where ever they want the XML file to reside.

Java class dependency,how "import" find the class in file system

guys,I am facing a basic but tricky problem.
Recently I am learning JSP.
As we know the "import" sentence help the java program find the class in system java library or your own file.
Here is an example to illustrate my problem: The imagine have some problem,I will upload it later the day .
Assuming I have App.java in path
$main/com/sub
,in the IDE it will belong to package com.sub;
and I have another useApp.java in path
$main/com
,it will be allocated with the package com.
Now if useApp.java need to import App.class.As my textbook say,the manually way of import the java class is to put the .class file in the subdirectory of the src directory .Then in this way the App.class should be located at
$main/com/com/sub/App.class
It is very werid,isn't it.This is the structure I use first.Now I know organize the different class in this way is terrible.So is there any convention way to organize your own file's dependencay .Should I just configure the .classpath file of the project in general?
I have trying to use .classpath file.Got the useApp.class file set.and try to invoke it in jsp file use
<%# page import="fullclassname"%> And keep getting the error"can not resolve to a type".
Classpath is not as straight simple as it seems like on the first glance. Especially Web applications and apps using plugin mechanisms use different classloaders, which can be confusing.
Classloaders
A good starting point is some reads about classloaders:
https://www.baeldung.com/java-classloaders
This will answer the question how "import will find the file" in an overall Java way.
Debugging Classloading
It you need to "find the file" while debuggin your application you can start your java application with the -verbose option (also in an IDE, normally called launch configuration or similar).
java -verbose HelloWorld
https://www.ibm.com/support/pages/using-java-verbose-option-determine-where-jdbc-driver-classes-are-loading
https://dzone.com/articles/how-use-verbose-options-java
Standardized Project Structure
In addition there's some standards hot to build Java project structures. Maven was one of the early dominators here. So adopting a standard MAVEN project structure might not be a bad idea for a beginner.
https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html
my-app
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- com
| `-- mycompany
| `-- app
| `-- App.java
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java

Personalised directory structure deploying with Maven

I have just recently started working with Maven and I have been asked to create a specific structure for when we deploy. The structure has to look like this:
/opt
\-myproject
|- libs
|- conf
\- logs
libs - Contains all the dependent libs and our own myproject.jar
conf - Contains the .properties files
logs - Contains our log file myproject.log
Our current java structure looks like this:
/src
|-myprojectpackages
propertiesfile1.properties
propertiesfile2.properties
pom.xml
My question is, do I have to change the java structure or is there any way to specify it in the pom.xml file? How should I handle this with Maven?
Edit:
In the end I used the Maven default layout, as advised in the comments section.

Exclude properties file from a WAR type sub-module in Maven

I have a complex scenario of packaging my EAR projects, below is the sort of visual description to fully understand it:
ProjA.ear
|-- ProjA.war
|-- Util.war
| |-- WEB-INF
| | |-- classes
| | | -- log4j.properties
Similarly, I have another project whose structure is:
ProjB.ear
|-- ProjB.war
|-- Util.war
| |-- WEB-INF
| | |-- classes
| | | -- log4j.properties
Util.war is a common project (except log4j.properties) for both ProjA and ProjB.
Below is how I have specified the dependency of Util.war in both ProjA and ProjB:
<dependency>
<groupId>abc</groupId>
<artifactId>xyz</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
Now the question is: As I have different versions of log4j.properties file for each project, how can I configure Maven to add ProjA specific file while packaging ProjA and use the other version when packaging ProjB?
Please let me know if you don't understand the jumbled scenario :).
Regards,
i think you could remove your log4j.properties out of the Util.war because it is application depended. instead you could use the ProjA.ear/APP-INF/classes and ProjB/APP-INF/classes folder for this.
see What difference between app-inf and web-inf folders in JavaEE applications?
Your Application Server is adding this folder automatically to the Class-Path. But be aware of parent first / child first class loading
see Java EE and Java SE classloading
However, In Java EE, a classloader first tries to load the class itself and then delegate the classloading of that class to its parent classloader.
This statement is depending on your Application Server.

Tomcat: How to point different directories to the same WEB-INF

Currently trying to setup multiple subdomains/domains in my Tomcat and I'm needing them all to use the same WEB-INF/classes/ for everything.
Basically my folder structure is like so:
Z:/
project/
assets/ (assets.domain.com)
main/ (www.domain.com)
dev/ (dev.domain.com)
WEB-INF/ (the WEB-INF I want everyone using.)
classes/
com/
example/
So basically I need assets.domain.com, www.domain.com, and dev.domain.com to go up one level in the directory to find the WEB-INF and use the Java classes stored there... Is there any way to accomplish this? Thanks!
if you are trying to share java code across webapps, you will need to package them as jar and place it in either server/lib or endorsed folder . then each deployed webapp will have access to the same class files.

Categories