Skip to content

Instantly share code, notes, and snippets.

@BruceZu
Last active June 7, 2018 06:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BruceZu/3952e52edecfd3ce4b224b897641ea32 to your computer and use it in GitHub Desktop.
Save BruceZu/3952e52edecfd3ce4b224b897641ea32 to your computer and use it in GitHub Desktop.
Tomcat

Tomcat 8

https://tomcat.apache.org/tomcat-8.5-doc/host-manager-howto.html https://tomcat.apache.org/tomcat-8.5-doc/config/host.html

Automatic Application Deployment

https://tomcat.apache.org/tomcat-5.5-doc/config/host.html#Automatic Application Deployment

Tips

http://www.onjava.com/pub/a/onjava/2003/06/25/tomcat_tips.html

Apache Tomcat wiki

Removing the unpackWARs feature https://wiki.apache.org/tomcat/RemoveUnpackWARs

   // unpackWARs="false" the 
   SevletContext.getRealPath();//  method always returns null

https://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getRealPath(java.lang.String)

getServletContext().getRealPath("/") 

// returns '\' at the end when I run my project in Tomcat 7 whereas it is not 
// working as such in Tomcat 8. 

// For example, 
// In Tomcat 7 it returns as "D:\Tomcat\webapps\project\" 
// In Tomcat 8 it returns as "D:\Tomcat\webapps\project" 

//At present the project is in production so, I am unable to change the code 
//in every part(where i use getRealPath("/")). Is there a way/setting in 
//tomcat level configuration to make it resolved. 

//Additional information, Tomcat version : 8.0.14 
 

tomcat implementation

https://bz.apache.org/bugzilla/show_bug.cgi?id=57556

 
 // the servlet-2_3-fcs-docs for ServletContext.getRealPath():
 // "This method returns null if the servlet container cannot translate the virtual path to a real path for any reason 
 // (such as when the content is being made available from a .war archive)."
   config.getServletContext().getRealPath("/" + storageLocation);
   getServletContext().getResource("files");
 // Read the javadoc for ServletContext.getResource:

//"Returns a URL to the resource that is mapped to a specified path. The
//path must begin with a "/" and is interpreted as relative to the current
//context root."
ServletContext#getRealPath() 
// may return null in case that the cms.war is running without being unpacked.

// So, I think it's better to use a default storage directory instead in this
// case under the current working directory (e.g, "./repository_storage").
@BruceZu
Copy link
Author

BruceZu commented Apr 9, 2018

@BruceZu
Copy link
Author

BruceZu commented Apr 9, 2018

Need configure the location to save the sso configuration
Development and producetion environment
Window and Ubuntu and Mac

        Properties  configProp = new Properties();
        configProp.load( CommonUtils.class.getClassLoader().getResourceAsStream("application.properties"));
@ConfigurationProperties(prefix="my.properties.prefix")
public class MyProperties {
  // value from my.properties.prefix.myProperty will be bound to this variable
  String myProperty;

  // and this will even throw a startup exception if the property is not found
  @javax.validation.constraints.NotNull
  String myRequiredProperty;

  //getters
}

@Component
public class MyOtherBean {
  @Autowired
  MyProperties myProperties;
}
// Note: Just remember to restart eclipse after setting a new environment variable

https://docs.spring.io/spring-framework/docs/4.3.10.RELEASE/spring-framework-reference/htmlsingle/#beans-environment
https://docs.spring.io/spring-framework/docs/4.3.10.RELEASE/spring-framework-reference/htmlsingle/#beans-property-source-abstraction
https://www.logicbig.com/tutorials/spring-framework/spring-core/spring-env-properties.html

@BruceZu
Copy link
Author

BruceZu commented Apr 10, 2018

      String systempath = System.getProperty("java.class.path");
     String[] classpathEntries = systempath.split(File.pathSeparator);
  // /usr/lib/jvm/zulu8.23.0.3-jdk8.0.144-linux_x64/jre/lib/resources.jar:
  // /usr/lib/jvm/zulu8.23.0.3-jdk8.0.144-linux_x64/jre/lib/rt.jar:
  // /usr/lib/jvm/zulu8.23.0.3-jdk8.0.144-linux_x64/jre/lib/jsse.jar:
  // /usr/lib/jvm/zulu8.23.0.3-jdk8.0.144-linux_x64/jre/lib/jce.jar:
  // /usr/lib/jvm/zulu8.23.0.3-jdk8.0.144-linux_x64/jre/lib/charsets.jar:
  // /home/bzu/tool/apache-tomcat-9.0.0.M21/bin/bootstrap.jar:
  // /home/bzu/tool/apache-tomcat-9.0.0.M21/bin/tomcat-juli.jar:
  // /usr/lib/jvm/zulu8.23.0.3-jdk8.0.144-linux_x64/lib/tools.jar:
  // /home/bzu/eclipse-workspace-fogo-wrong-decision/.metadata/.plugins/com.zeroturnaround.xrebel.plugin/xrebel.jar
   String checktheab = new File(".").getAbsolutePath();
  // /home/bzu/project/new/FortiPortal/fortipmc/. (standlone )
  // /home/bzu/. (local eclipse + tomcat)

The java.io.File acts on the local disk file system. relative paths in java.io are dependent on the current working directory. "user.dir"

in the classpath use ClassLoader#getResource() or ClassLoader#getResourceAsStream() instead. It is able to locate files relative to the "root" of the classpath, In webapplications (or any other application which uses multiple classloaders) it's recommend to use the ClassLoader as returned by Thread.currentThread().getContextClassLoader() for this.

Another alternative in webapps is the ServletContext#getResource() and its counterpart ServletContext#getResourceAsStream(). It is able to access files located in the public web folder of the webapp project, including the /WEB-INF folder.

  URL url = this.getClass().getResource(File.separator);

// also need classloader
// local eclipse+tomcat:
// file:/home/bzu/eclipse-workspace-fogo-wrong-decision/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/fpc/WEB-INF/classes/
// a safer way is to use class name itself for this solution, for example,
// MyClass.getResourceAsStream(), as often this.getClass() won't work in subclassing or autoproxying scenarios.

CATALINA_BASE=/var/tomcat
export CATALINA_BASE
sh-3.1# grep env  /usr/local/tomcat/bin/catalina.sh
if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
  . "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
  . "$CATALINA_HOME/bin/setenv.sh"
# Get standard Java environment variables
sh-3.1# find / -type f -name setenv.sh             
/usr/local/tomcat/bin/setenv.sh
sh-3.1# grep database.properties /usr/local/tomcat/bin/setenv.sh
TOMCAT_DB_PROPERTIES=/usr/local/tomcat/util/fpc/database.properties
TOMCAT_DB_PROPERTIES_OUT=/usr/local/tomcat/util/fpc/database.propertiesout
sh-3.1# find / -type f -name database.properties                
/var/tomcat/util/fpc/database.properties
 @Autowired ServletContext servletContext;
  @Autowired Environment env;

  private void test() {
    try {
     url = this.getClass().getResource("/spring/metadata/idp.xml");                
 //file:/home/bzu/eclipse-workspace-fogo-wrong-decision/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/fpc/WEB-INF/classes/spring/metadata/idp.xml
      url = this.getClass().getResource("spring/metadata/idp.xml"); // null
      idp = this.getClass().getResourceAsStream("/spring/metadata/idp.xml"); // okay
      idp = this.getClass().getResourceAsStream("spring/metadata/idp.xml"); // null
    // 从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取??
      url = this.getClass().getClassLoader().getResource("/spring/metadata/idp.xml");
//file:/home/bzu/eclipse-workspace-fogo-wrong-decision/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/fpc/WEB-INF/classes/spring/metadata/idp.xml
      url = this.getClass().getClassLoader().getResource("spring/metadata/idp.xml");
// file:/home/bzu/eclipse-workspace-fogo-wrong-decision/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/fpc/WEB-INF/classes/spring/metadata/idp.xml

      String absoluteDiskPath = servletContext.getRealPath(File.separator);
      // home/bzu/eclipse-workspace-fogo-wrong-decision/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/fpc/
      URI uri = servletContext.getResource("WEB-INF/classes/spring/metadata/idp.xml").toURI();
      // file:/home/bzu/eclipse-workspace-fogo-wrong-decision/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/fpc/WEB-INF/classes/spring/metadata/idp.xml
      InputStream idp =
          servletContext.getResourceAsStream("WEB-INF/classes/spring/metadata/idp.xml");
      env.getProperty("user.dir");
      //  /home/bzu
     URL url = Thread.currentThread().getContextClassLoader().getResource("/spring/metadata/idp.xml");
      // file:/home/bzu/eclipse-workspace-fogo-wrong-decision/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/fpc/WEB-INF/classes/spring/metadata/idp.xml

    } catch (Exception e) {
      e.printStackTrace();
    }
    log.error("");
  }

@BruceZu
Copy link
Author

BruceZu commented Apr 10, 2018

4799 root 2564 S {catalina.sh} /bin/sh /usr/local/tomcat/bin/catalina.sh start
// VM

@BruceZu
Copy link
Author

BruceZu commented Apr 11, 2018

ResourceResolver myResolver = new ResourceResolver() {
     public InputStream getResourceAsStream(String resourceName) {
         ClassLoader loader = Thread.currentThread().getContextClassLoader();
         if (loader == null) { // there may not be a context class loader
             loader = MyClazz.class.getClassLoader();
         }
         return loader.getResourceAsStream(resourceName);
     }
 };

@BruceZu
Copy link
Author

BruceZu commented Apr 11, 2018

Code:
myclass:

this.getClass().getClassLoader().getResourceAsStream("config.xml")

to get a configuration out of the classpath.

It worked really well, but now I found something weird:

I load the class with the above function in a jsp,
the class residing in a jar in the tomcat/common/lib dir and
the config.xml in the webroot/WEB-INF/classes
Suddenly the config.xml cannt be loaded any more... at least not by myclass.

Thread.currentThread().getContextClassLoader().getResourceAsStream("config.xml")

Tomcat sets the context class loader to the class loader of the webapp (which can of course load stuff from WEB_INF/classes).
The original line this.getClass().getClassLoader().getResourceAsStream("config.xml") does not work when the class that contains the line lives in common/lib or shared/lib, because its class loader is then the 'common' or 'shared' class loader, which cannot see into individual webapps.
Class Loader HOW-TO http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment