dblevins 2005/07/12 19:51:16
Modified: modules/core/src/java/org/openejb/loader
BasicURLClassPath.java ClassPath.java
ClassPathFactory.java ContextClassPath.java
LoaderServlet.java SystemClassPath.java
SystemInstance.java TomcatClassPath.java
WebAppClassPath.java
Added: modules/core/src/java/org/openejb/loader
OpenEJBInstance.java
Removed: modules/core/src/java/org/openejb/loader EmbeddedLoader.java
EmbeddingLoader.java SystemLoader.java
TomcatWebappLoader.java
Log:
Tomcat 4 Common (Global) support works. Per-webapp is still hosed.
Revision Changes Path
1.2 +3 -9
openejb1/modules/core/src/java/org/openejb/loader/BasicURLClassPath.java
Index: BasicURLClassPath.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb1/modules/core/src/java/org/openejb/loader/BasicURLClassPath.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BasicURLClassPath.java 9 Jul 2005 09:28:24 -0000 1.1
+++ BasicURLClassPath.java 12 Jul 2005 23:51:16 -0000 1.2
@@ -54,19 +54,13 @@
/**
* @version $Revision$ $Date$
*/
-public class BasicURLClassPath implements ClassPath {
+public abstract class BasicURLClassPath implements ClassPath {
public static ClassLoader getContextClassLoader() {
return (ClassLoader) java.security.AccessController.doPrivileged(new
java.security.PrivilegedAction() {
public Object run() {
return Thread.currentThread().getContextClassLoader();
}
});
- }
-
- public void addJarsToPath(File dir) throws Exception {
- }
-
- public void addJarToPath(URL jar) throws Exception {
}
private java.lang.reflect.Field ucpField;
1.2 +7 -4
openejb1/modules/core/src/java/org/openejb/loader/ClassPath.java
Index: ClassPath.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb1/modules/core/src/java/org/openejb/loader/ClassPath.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ClassPath.java 9 Jul 2005 09:28:24 -0000 1.1
+++ ClassPath.java 12 Jul 2005 23:51:16 -0000 1.2
@@ -52,7 +52,10 @@
* @version $Revision$ $Date$
*/
public interface ClassPath {
- public void addJarsToPath(File dir) throws Exception;
- public void addJarToPath(URL dir) throws Exception;
+ ClassLoader getClassLoader();
+
+ void addJarsToPath(File dir) throws Exception;
+
+ void addJarToPath(URL dir) throws Exception;
}
1.2 +3 -3
openejb1/modules/core/src/java/org/openejb/loader/ClassPathFactory.java
Index: ClassPathFactory.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb1/modules/core/src/java/org/openejb/loader/ClassPathFactory.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ClassPathFactory.java 9 Jul 2005 09:28:24 -0000 1.1
+++ ClassPathFactory.java 12 Jul 2005 23:51:16 -0000 1.2
@@ -49,7 +49,7 @@
* @version $Revision$ $Date$
*/
public class ClassPathFactory {
- public static ClassPath createLoader(String name){
+ public static ClassPath createClassPath(String name){
if (name.equalsIgnoreCase("tomcat")) {
return new TomcatClassPath();
} else if (name.equalsIgnoreCase("tomcat-common")) {
1.2 +6 -2
openejb1/modules/core/src/java/org/openejb/loader/ContextClassPath.java
Index: ContextClassPath.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb1/modules/core/src/java/org/openejb/loader/ContextClassPath.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ContextClassPath.java 9 Jul 2005 09:28:24 -0000 1.1
+++ ContextClassPath.java 12 Jul 2005 23:51:16 -0000 1.2
@@ -57,6 +57,10 @@
/*-------------------------------------------------------*/
public class ContextClassPath extends BasicURLClassPath {
+ public ClassLoader getClassLoader() {
+ return getContextClassLoader();
+ }
+
public void addJarsToPath(File dir) throws Exception {
ClassLoader contextClassLoader = getContextClassLoader();
if (contextClassLoader instanceof URLClassLoader) {
1.5 +26 -86
openejb1/modules/core/src/java/org/openejb/loader/LoaderServlet.java
Index: LoaderServlet.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb1/modules/core/src/java/org/openejb/loader/LoaderServlet.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- LoaderServlet.java 16 Jun 2005 22:29:51 -0000 1.4
+++ LoaderServlet.java 12 Jul 2005 23:51:16 -0000 1.5
@@ -44,9 +44,12 @@
*/
package org.openejb.loader;
+import org.openejb.util.FileUtils;
+
import java.io.File;
import java.util.Enumeration;
import java.util.Properties;
+import java.lang.reflect.Method;
import javax.naming.Context;
import javax.naming.InitialContext;
@@ -59,104 +62,41 @@
* @author <a href="mailto:[EMAIL PROTECTED]">David Blevins </a>
*/
public class LoaderServlet extends HttpServlet {
+ private OpenEJBInstance openejb;
public void init(ServletConfig config) throws ServletException {
- try {
-
- Properties p = new Properties();
- p.put(Context.INITIAL_CONTEXT_FACTORY,
"org.openejb.client.LocalInitialContextFactory");
-
- Enumeration enum = config.getInitParameterNames();
-
- System.out.println("OpenEJB init-params:");
- while (enum.hasMoreElements()) {
- String name = (String) enum.nextElement();
- String value = config.getInitParameter(name);
- p.put(name, value);
- System.out.println("\tparam-name: " + name + ", param-value:
" + value);
- }
-
- String openejbLoaderPropValue = p.getProperty("openejb.loader");
- if (openejbLoaderPropValue != null) {
- if (openejbLoaderPropValue.endsWith("tomcat-webapp") &&
p.getProperty("openejb.base") == null) {
- ServletContext ctx = config.getServletContext();
- p.setProperty("openejb.base",
ctx.getRealPath("WEB-INF"));
- }
- }
+ Properties p = new Properties();
+ p.setProperty("openejb.loader","tomcat");
- new InitialContext(p);
-
- } catch (Exception e) {
- e.printStackTrace();
+ Enumeration enum = config.getInitParameterNames();
+ System.out.println("OpenEJB init-params:");
+ while (enum.hasMoreElements()) {
+ String name = (String) enum.nextElement();
+ String value = config.getInitParameter(name);
+ p.put(name, value);
+ System.out.println("\tparam-name: " + name + ", param-value: " +
value);
}
- }
-
- String NO_HOME = "The openejb.home is not set.";
- String BAD_HOME = "Invalid openejb.home: ";
-
- String NOT_THERE = "The path specified does not exist.";
-
- String NOT_DIRECTORY = "The path specified is not a directory.";
-
- String NO_DIST = "The path specified is not correct, it does not contain
a 'dist' directory.";
-
- String NO_LIBS = "The path specified is not correct, it does not contain
any OpenEJB libraries.";
-
- String INSTRUCTIONS = "Please edit the web.xml of the openejb_loader
webapp and set the openejb.home init-param to the full path where OpenEJB is
installed.";
+ String loader = p.getProperty("openejb.loader"); // Default loader
set above
+ if (loader.endsWith("tomcat-webapp") &&
p.getProperty("openejb.base") == null) {
+ ServletContext ctx = config.getServletContext();
+ p.setProperty("openejb.base", ctx.getRealPath("WEB-INF"));
+ }
- private void checkOpenEjbHome() throws ServletException {
try {
-
- // The openejb.home must be set
- String homePath = System.getProperty("openejb.home");
- if (homePath == null)
- handleError(NO_HOME, INSTRUCTIONS);
-
- // The openejb.home must exist
- File openejbHome = new File(homePath);
- if (!openejbHome.exists())
- handleError(BAD_HOME + homePath, NOT_THERE, INSTRUCTIONS);
-
- // The openejb.home must be a directory
- if (!openejbHome.isDirectory())
- handleError(BAD_HOME + homePath, NOT_DIRECTORY,
INSTRUCTIONS);
-
- // The openejb.home must contain a 'dist' directory
- File openejbHomeDist = new File(openejbHome, "dist");
- if (!openejbHomeDist.exists())
- handleError(BAD_HOME + homePath, NO_DIST, INSTRUCTIONS);
-
- // The openejb.home there must be openejb*.jar files in the
'dist'
- // directory
- String[] libs = openejbHomeDist.list();
- boolean found = false;
- for (int i = 0; i < libs.length && !found; i++) {
- found = (libs[i].startsWith("openejb-") &&
libs[i].endsWith(".jar"));
- }
- if (!found)
- handleError(BAD_HOME + homePath, NO_LIBS, INSTRUCTIONS);
-
+ init(p);
} catch (Exception e) {
e.printStackTrace();
}
}
- private void handleError(String m1, String m2, String m3) throws
ServletException {
- System.err.println("--[PLEASE
FIX]-------------------------------------");
- System.err.println(m1);
- System.err.println(m2);
- System.err.println(m3);
-
System.err.println("---------------------------------------------------");
- throw new ServletException(m1 + " " + m2 + " " + m3);
+ public void init(Properties properties) throws Exception {
+ if (openejb != null) return;
+ SystemInstance.init(properties);
+ openejb = new OpenEJBInstance();
+ if (openejb.isInitialized()) return;
+ openejb.init(properties);
}
- private void handleError(String m1, String m2) throws ServletException {
- System.err.println("--[PLEASE
FIX]-------------------------------------");
- System.err.println(m1);
- System.err.println(m2);
-
System.err.println("---------------------------------------------------");
- throw new ServletException(m1 + " " + m2);
- }
}
1.2 +10 -2
openejb1/modules/core/src/java/org/openejb/loader/SystemClassPath.java
Index: SystemClassPath.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb1/modules/core/src/java/org/openejb/loader/SystemClassPath.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SystemClassPath.java 9 Jul 2005 09:28:24 -0000 1.1
+++ SystemClassPath.java 12 Jul 2005 23:51:16 -0000 1.2
@@ -70,6 +70,14 @@
this.rebuildJavaClassPathVariable();
}
+ public ClassLoader getClassLoader() {
+ try {
+ return getSystemLoader();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private URLClassLoader getSystemLoader() throws Exception {
if (sysLoader == null) {
sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
1.5 +18 -11
openejb1/modules/core/src/java/org/openejb/loader/SystemInstance.java
Index: SystemInstance.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb1/modules/core/src/java/org/openejb/loader/SystemInstance.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SystemInstance.java 9 Jul 2005 09:46:29 -0000 1.4
+++ SystemInstance.java 12 Jul 2005 23:51:16 -0000 1.5
@@ -66,16 +66,25 @@
private final Properties properties;
private final FileUtils home;
private final FileUtils base;
- private ClassLoader classLoader;
+ private final ClassLoader classLoader;
private final HashMap components;
private final ClassPath classPath;
private SystemInstance(Properties properties) throws Exception {
this.components = new HashMap();
- this.properties = properties;
+ this.properties = new Properties();
+ this.properties.putAll(System.getProperties());
+ this.properties.putAll(properties);
+
this.home = new FileUtils("openejb.home", "user.dir", properties);
this.base = new FileUtils("openejb.base", "openejb.home",
properties);
- classPath =
ClassPathFactory.createLoader(properties.getProperty("openejb.loader",
"context"));
+ this.classPath =
ClassPathFactory.createClassPath(properties.getProperty("openejb.loader",
"context"));
+ this.classLoader = classPath.getClassLoader();
+
+ // TODO Setup the jar url handler too
+
+ properties.setProperty("openejb.home",
home.getDirectory().getCanonicalPath());
+ properties.setProperty("openejb.base",
base.getDirectory().getCanonicalPath());
}
@@ -107,7 +116,7 @@
return base;
}
- public ClassPath getLoader() {
+ public ClassPath getClassPath() {
return classPath;
}
@@ -115,10 +124,6 @@
return classLoader;
}
- public void setClassLoader(ClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
public Object getObject(String name) {
return components.get(name);
}
@@ -139,9 +144,11 @@
throw new RuntimeException("Failed to create default instance of
SystemInstance",e);
}
}
-
+ private static boolean initialized;
public static void init(Properties properties) throws Exception{
+ if (initialized) return;
system = new SystemInstance(properties);
+ initialized = true;
}
public static SystemInstance get(){
1.2 +26 -23
openejb1/modules/core/src/java/org/openejb/loader/TomcatClassPath.java
Index: TomcatClassPath.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb1/modules/core/src/java/org/openejb/loader/TomcatClassPath.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TomcatClassPath.java 9 Jul 2005 09:28:24 -0000 1.1
+++ TomcatClassPath.java 12 Jul 2005 23:51:16 -0000 1.2
@@ -50,6 +50,7 @@
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.lang.reflect.Method;
/**
* @version $Revision$ $Date$
@@ -87,6 +88,10 @@
rebuild();
}
+ public ClassLoader getClassLoader() {
+ return getCommonLoader();
+ }
+
public void addJarToPath(URL jar) throws Exception {
//System.out.println("[|] TOMCAT "+jar.toExternalForm());
this._addJarToPath(jar);
@@ -95,33 +100,14 @@
public void _addJarToPath(URL jar) throws Exception {
String path = jar.toExternalForm();
- //System.out.println("[] PATH "+path);
- //if (path.startsWith("file:/C")) {
- // path = path.substring("file:/C".length());
- // path = "file:C"+path;
- //}
this.addRepository(path);
- //ClassLoader cl = ClasspathUtils.getContextClassLoader();
- //cl = getCommonLoader(cl);
- //System.out.println("[] "+cl.getClass().getName());
- //System.out.println("[] "+cl);
- //
- ////Reloader loader = (Reloader)cl.getParent();
- //cl = cl.getParent();
- //java.lang.reflect.Method m = getAddRepositoryMethod(
- // cl.getClass());
- //m.invoke( cl, new Object[]{jar.toExternalForm()});
- ////loader.addRepository( jar.toExternalForm() );
}
public void addRepository(String path) throws Exception {
-
- // Add this repository to our underlying class loader
- this.getAddRepositoryMethod().invoke(getCommonLoader(), new Object[]
{ new URL(path) });
+ this.getAddRepositoryMethod().invoke(getCommonLoader(), new Object[]
{ path });
}
private void rebuild() {
-
try {
sun.misc.URLClassPath cp = getURLClassPath((URLClassLoader)
getCommonLoader());
URL[] urls = cp.getURLs();
@@ -173,7 +159,7 @@
*
* @return URLClassLoader.addURL method instance
*/
- private java.lang.reflect.Method getAddRepositoryMethod() throws
Exception {
+ private java.lang.reflect.Method _getAddRepositoryMethod() throws
Exception {
if (addRepositoryMethod == null) {
final Class clazz = URLClassLoader.class;
@@ -195,4 +181,21 @@
return addRepositoryMethod;
}
+
+ protected Method getAddRepositoryMethod() throws Exception {
+ return (Method) AccessController.doPrivileged(new PrivilegedAction()
{
+ public Object run() {
+ Method method = null;
+ try {
+ Class clazz = getClassLoader().getClass();
+ method = clazz.getDeclaredMethod("addRepository", new
Class[]{String.class});
+ method.setAccessible(true);
+ return method;
+ } catch (Exception e2) {
+ throw (IllegalStateException) new
IllegalStateException("Unable to find or access the addRepository method in
StandardClassLoader").initCause(e2);
+ }
+ }
+ });
+ }
+
}
1.2 +6 -2
openejb1/modules/core/src/java/org/openejb/loader/WebAppClassPath.java
Index: WebAppClassPath.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb1/modules/core/src/java/org/openejb/loader/WebAppClassPath.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- WebAppClassPath.java 9 Jul 2005 09:28:24 -0000 1.1
+++ WebAppClassPath.java 12 Jul 2005 23:51:16 -0000 1.2
@@ -51,6 +51,10 @@
public class WebAppClassPath extends TomcatClassPath {
ClassLoader webappLoader;
+ public ClassLoader getClassLoader() {
+ return getCommonLoader();
+ }
+
protected ClassLoader getCommonLoader() {
if (webappLoader == null) {
webappLoader = getContextClassLoader();
1.1
openejb1/modules/core/src/java/org/openejb/loader/OpenEJBInstance.java
Index: OpenEJBInstance.java
===================================================================
/**
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright
* statements and notices. Redistributions must also contain a
* copy of this document.
*
* 2. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. The name "OpenEJB" must not be used to endorse or promote
* products derived from this Software without prior written
* permission of The OpenEJB Group. For written permission,
* please contact [EMAIL PROTECTED]
*
* 4. Products derived from this Software may not be called "OpenEJB"
* nor may "OpenEJB" appear in their names without prior written
* permission of The OpenEJB Group. OpenEJB is a registered
* trademark of The OpenEJB Group.
*
* 5. Due credit should be given to the OpenEJB Project
* (http://openejb.org/).
*
* THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2005 (C) The OpenEJB Group. All Rights Reserved.
*
* $Id: OpenEJBInstance.java,v 1.1 2005/07/12 23:51:16 dblevins Exp $
*/
package org.openejb.loader;
import org.openejb.loader.ClassPath;
import org.openejb.loader.SystemInstance;
import org.openejb.util.FileUtils;
import javax.servlet.ServletException;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
import java.io.File;
/**
* This class can exist in several child classloaders
* Specifically in the tomcat webapp style, this class
* is loaded several times.
*/
public class OpenEJBInstance {
private final Class openejb;
private final Method init;
private final Method isInitialized;
public OpenEJBInstance() throws Exception {
this.openejb = loadOpenEJBClass();
this.init = openejb.getMethod("init", new Class[]{Properties.class});
this.isInitialized = openejb.getMethod("isInitialized", new
Class[]{});
}
public void init(Properties props) throws Exception {
try {
init.invoke(null, new Object[]{props});
} catch (InvocationTargetException e) {
throw (Exception) e.getCause();
} catch (Exception e) {
throw new RuntimeException("OpenEJB.init: ", e);
}
}
public boolean isInitialized() {
try {
Boolean b = (Boolean) isInitialized.invoke(null, new Object[]{});
return b.booleanValue();
} catch (InvocationTargetException e) {
throw new RuntimeException("OpenEJB.isInitialized: ",
e.getCause());
} catch (Exception e) {
throw new RuntimeException("OpenEJB.isInitialized: ", e);
}
}
private Class loadOpenEJBClass() throws Exception {
ClassPath classPath = SystemInstance.get().getClassPath();
ClassLoader classLoader = classPath.getClassLoader();
try {
return classLoader.loadClass("org.openejb.OpenEJB");
} catch (Exception e) {
try {
checkOpenEjbHome();
FileUtils home = SystemInstance.get().getHome();
classPath.addJarsToPath(home.getDirectory("lib"));
} catch (Exception e2) {
throw new Exception("Could not load OpenEJB libraries.
Exception: " + e2.getClass().getName() + " " + e2.getMessage());
}
try {
return classLoader.loadClass("org.openejb.OpenEJB");
} catch (Exception e2) {
throw new Exception("Could not load OpenEJB class after
embedding libraries. Exception: " + e2.getClass().getName() + " " +
e2.getMessage());
}
}
}
String NO_HOME = "The openejb.home is not set.";
String BAD_HOME = "Invalid openejb.home: ";
String NOT_THERE = "The path specified does not exist.";
String NOT_DIRECTORY = "The path specified is not a directory.";
String NO_DIST = "The path specified is not correct, it does not contain
a 'dist' directory.";
String NO_LIBS = "The path specified is not correct, it does not contain
any OpenEJB libraries.";
// TODO: move this part back into the LoaderServlet
String INSTRUCTIONS = "Please edit the web.xml of the openejb_loader
webapp and set the openejb.home init-param to the full path where OpenEJB is
installed.";
private void checkOpenEjbHome() throws Exception {
try {
// The openejb.home must be set
String homePath = System.getProperty("openejb.home");
if (homePath == null)
handleError(NO_HOME, INSTRUCTIONS);
// The openejb.home must exist
File openejbHome = new File(homePath);
if (!openejbHome.exists())
handleError(BAD_HOME + homePath, NOT_THERE, INSTRUCTIONS);
// The openejb.home must be a directory
if (!openejbHome.isDirectory())
handleError(BAD_HOME + homePath, NOT_DIRECTORY, INSTRUCTIONS);
// The openejb.home must contain a 'lib' directory
File openejbHomeLibs = new File(openejbHome, "lib");
if (!openejbHomeLibs.exists())
handleError(BAD_HOME + homePath, NO_DIST, INSTRUCTIONS);
// The openejb.home there must be openejb*.jar files in the 'dist'
// directory
String[] libs = openejbHomeLibs.list();
boolean found = false;
for (int i = 0; i < libs.length && !found; i++) {
found = (libs[i].startsWith("openejb-") &&
libs[i].endsWith(".jar"));
}
if (!found)
handleError(BAD_HOME + homePath, NO_LIBS, INSTRUCTIONS);
} catch (Exception e) {
e.printStackTrace();
}
}
private void handleError(String m1, String m2, String m3) throws
Exception {
System.err.println("--[PLEASE
FIX]-------------------------------------");
System.err.println(m1);
System.err.println(m2);
System.err.println(m3);
System.err.println("---------------------------------------------------");
throw new Exception(m1 + " " + m2 + " " + m3);
}
private void handleError(String m1, String m2) throws Exception {
System.err.println("--[PLEASE
FIX]-------------------------------------");
System.err.println(m1);
System.err.println(m2);
System.err.println("---------------------------------------------------");
throw new Exception(m1 + " " + m2);
}
}